5 min read

LibreChat: One Self-Hosted Chat for Every AI Provider (GitHub, Scanned)

A self-hosted ChatGPT-style interface for every major AI provider, with agents, MCP and multi-user logins.

LibreChat logo
✅
Scan: safe. Nothing to warn about. Every secret and IP hit is a test fixture for its own security code, and the only advisories are two false matches on a spreadsheet library it installs at an already-fixed version. Scanned Sep 27, 2026; the full report is below.

LibreChat puts every major model provider behind one ChatGPT-style interface that you host. OpenAI, Anthropic, Google, AWS Bedrock, Azure and Vertex AI are built in, and anything OpenAI-compatible, from Ollama to OpenRouter, is a custom endpoint in a YAML file. Around the chat it has agents with MCP tools, sub-agents and skills, code artifacts, a sandboxed code interpreter, web search, chat with files, conversation search and forking, and resumable streams that survive a dropped connection.

What sets it apart is the multi-user plumbing: OAuth, LDAP and email logins, per-role and per-group permissions, token spend controls and a browser admin panel, which is what makes it fit a company or school deployment. It is MIT-licensed, a Node and React code base started by Danny Avila in 2023 with more than 400 contributors, and the project is joining ClickHouse, whose open-source code interpreter it already uses.

Who it is for

Organizations that want one governed chat interface for staff across several paid providers, and individuals who want all their API keys and local models in one self-hosted app.

Getting started

1. Clone the repository (Docker Desktop, or Docker with Compose, required)

git clone https://github.com/LibreChat-AI/LibreChat.git && cd LibreChat

2. Create the environment file from the example and fill in what you need

cp .env.example .env

3. Start the stack, then open http://localhost:3080 and register an account

docker compose up -d

Safety scan

We cloned LibreChat-AI/LibreChat at commit 3c72c3f on Sep 27, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • 28 private-key hits, all test fixtures: throwaway keys in the tests for CloudFront signed cookies and URLs and for the key-handling utilities. The 13 bare-IP URLs are in tests too, most of them checking that requests to internal or private addresses are refused by the SSRF protection in the MCP, OAuth and actions code.
  • No pattern hits. The four binaries are OpenDocument sample files (.odt, .ods) for the document parser; the format is a zip archive, which the scanner reads as a Java archive.
  • Install hooks: one prepare script that sets up husky Git hooks and ignores failure. Of the three shell scripts, one installs fonts on the CI runner and two start a local Redis cluster or a TLS Redis for development; the cluster script uses sudo, on your machine only if you run it.
  • No critical advisories across 2,731 npm packages checked. The two high entries are for xlsx 0.20.3, which LibreChat installs from SheetJS's own CDN; SheetJS stopped publishing to npm, and both advisories were fixed in earlier CDN releases (0.19.3 and 0.20.2), so this is a false match.
  • 29 workflows. One uses pull_request_target, to retarget pull requests to the dev branch, and it checks out the trusted base commit, never the pull request's code. None of the 23 third-party actions is pinned to a commit. Security policy, contributing guide and code of conduct present; no Dependabot.

What the scanner counted

CheckResult
Secrets28 candidates found and read; see the notes above.
Suspicious codeNone found.
Install-time code1 npm lifecycle script. 3 installer scripts (one can call sudo)
Committed binaries4 executable or compiled objects committed; listed under the raw findings.
CI workflows29 workflows. 1 uses pull_request_target, none check out the pull request head. 23 of 23 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often api.example.com, auth.example.com, mcp.example.com, code.example.com. 13 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities3 advisories across 2,731 pinned packages: 0 critical, 2 high, 0 moderate, 1 low. otel/langfuse-fanout/go.mod: 20 packages, 0 advisories; package-lock.json: 3,159 packages, 3 advisories; packages/data-provider/react-query/package-lock.json: 27 packages, 0 advisories.
Project hygieneHas security policy, licence file, contributing guide. Missing automated dependency updates, CodeQL.
OpenSSF ScorecardNot scored: the project is not in Scorecard's weekly index.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Secret candidates (28, redacted)
WhereRuleMatch
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:45private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:116private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:132private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:157private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:212private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:241private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:286private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:334private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:360private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:395private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:431private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:484private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:533private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:567private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:592private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:614private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:633private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront-cookies.test.ts:652private-key-----B…--- (31 chars)
packages/api/src/cdn/__tests__/cloudfront.test.ts:72private-key-----B…--- (31 chars)
packages/api/src/utils/key.test.ts:24private-key-----B…--- (27 chars)
packages/api/src/utils/key.test.ts:107private-key-----B…--- (27 chars)
packages/api/src/utils/key.test.ts:114private-key-----B…--- (27 chars)
packages/api/src/utils/key.test.ts:123private-key-----B…--- (27 chars)
packages/api/src/utils/key.test.ts:131private-key-----B…--- (27 chars)
and 4 more
URLs to bare IP addresses (13)
WhereRuleMatch
packages/api/src/auth/agent.spec.ts:453ip-literal-urlapplySSRFSafeAgentIfDirect(config, 'http://8.8.8.8:80');
packages/api/src/mcp/__tests__/MCPConnectionSSRF.test.ts:1848ip-literal-urlawait expect(customFetch('http://203.0.113.10/mcp')).rejects.toThrow(
packages/api/src/oauth/tokens.spec.ts:71ip-literal-urlclient_url: 'https://93.184.216.34/oauth/token',
packages/api/src/oauth/tokens.spec.ts:82ip-literal-url'http://93.184.216.34/oauth/token',
packages/api/src/oauth/validation.spec.ts:8ip-literal-urlvalidateActionOAuthEndpoint('https://93.184.216.34/oauth/token', 'client_url'),
packages/api/src/oauth/validation.spec.ts:13ip-literal-url['HTTP endpoint', 'http://93.184.216.34/oauth/token'],
packages/api/src/oauth/validation.spec.ts:54ip-literal-urlauthorization_url: 'https://93.184.216.34/oauth/authorize',
packages/data-provider/specs/actions.spec.ts:2188ip-literal-urlconst result = validateActionDomain('api.example.com', 'http://224.0.0.1/');
packages/data-provider/specs/actions.spec.ts:2194ip-literal-urlconst result = validateActionDomain('api.example.com', 'http://255.255.255.255/');
packages/data-provider/specs/actions.spec.ts:2254ip-literal-url'http://100.100.100.200/latest/meta-data/',
packages/data-provider/specs/actions.spec.ts:2330ip-literal-urlconst result = validateActionDomain('api.example.com', 'http://240.0.0.1/');
packages/data-provider/specs/actions.spec.ts:2336ip-literal-urlconst result = validateActionDomain('api.example.com', 'http://192.0.2.1/');
packages/data-provider/specs/actions.spec.ts:2342ip-literal-urlconst result = validateActionDomain('192.0.2.1', 'http://192.0.2.1/api');
npm lifecycle scripts (1)
  • package.json prepare: node -e "import('husky').then((h) => h.default()).catch(() => {})"
Installer scripts (3)
Committed binaries (4)
  • packages/api/src/files/documents/sample.ods: JAR, 8 KB
  • packages/api/src/files/documents/sample.odt: JAR, 1 KB
  • packages/api/src/files/documents/sample-entities.odt: JAR, 1 KB
  • packages/api/src/files/documents/empty.odt: JAR, 1 KB
Worst known vulnerabilities (3 of 3)
AdvisorySeverityPackageSummary
GHSA-4r6h-8v6p-xvw6highxlsx@0.20.3Prototype Pollution in sheetJS
GHSA-5pgg-2g8v-p4x9highxlsx@0.20.3SheetJS Regular Expression Denial of Service (ReDoS)
GHSA-848j-6mx2-7j84lowelliptic@6.6.1Elliptic Uses a Cryptographic Primitive with a Risky Implementation
Workflows worth a look

By the numbers

Stars45K
Forks9,215
Contributors417
Commits5,792
Open issues379
Open pull requests412
Releases97
Latest releasenone tagged
LicenceMIT
Main languageTypeScript
Project age3 years
Last pushSep 27, 2026
Tracked files5,567
Lines of code1.6M
Checkout size66 MB

Lines by language: TypeScript 1.3M, JavaScript 265.9K, JSON 58.5K, YAML 9,923, Markdown 7,456, CSS 3,208.

Questions

Is LibreChat free?

Yes. LibreChat is MIT-licensed and free to self-host for any purpose, including inside a company, and there is no paid edition of the software. You pay the model providers you connect, with your own API keys, or nothing at all if you point it at local models through Ollama or another OpenAI-compatible server.

Does LibreChat work with local models?

Yes. Any OpenAI-compatible server works as a custom endpoint defined in librechat.yaml, and the README lists Ollama, koboldcpp, Apple MLX and AMD Lemonade among the compatible ones. The Docker stack can run on the same machine as Ollama, so a fully local install with no provider keys at all is possible.

LibreChat or Open WebUI?

Both are self-hosted chat interfaces. Open WebUI is built around local models and Ollama, with document search and Python functions, and is the quicker install. LibreChat is built around hosted providers and organizations: it handles OpenAI, Anthropic, Bedrock, Azure and Vertex natively, with LDAP and OAuth logins, per-role permissions and spend controls. LibreChat is also plain MIT, where Open WebUI's licence adds a branding clause.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.