-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat: restructure mcp auth docs into dedicated section and add per-user headers auth type #3707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| --- | ||
| title: "Header-Based Authentication" | ||
| sidebarTitle: "Headers" | ||
| description: "Configure static HTTP headers (API keys, bearer tokens, custom auth) shared across all requests to an MCP server." | ||
| icon: "key" | ||
| --- | ||
|
|
||
| ## Overview | ||
|
|
||
| `auth_type: "headers"` attaches a fixed set of HTTP headers to every request Bifrost makes to the upstream MCP server. Use it for shared API keys, bearer tokens, or any other static authentication scheme. | ||
|
|
||
| The same headers are used regardless of which caller (which VK, which user, which session) is hitting Bifrost — this is **server-level** auth. If you need each end-user to supply their own credentials, use [Per-User Headers](./per-user-headers) instead. | ||
|
|
||
| This auth type is only valid for **HTTP** and **SSE** connections. | ||
|
|
||
| --- | ||
|
|
||
| ## When to use | ||
|
|
||
| - Shared API key the whole team uses | ||
| - Internal MCP servers with a single bearer token | ||
| - Custom header-based schemes (`X-Tenant-ID`, `X-Region`, etc.) | ||
| - Anything where you'd add headers to a `curl` command | ||
|
|
||
| For per-user OAuth see [OAuth 2.0](./oauth) (admin authenticates once) or [Per-User OAuth](./per-user-oauth) (each user authenticates). | ||
|
|
||
| --- | ||
|
|
||
| ## Configuration | ||
|
|
||
| Header values support environment-variable references — use `env.MY_VAR` (or the UI's env-var picker) to keep secrets out of the config file. Values are encrypted at rest when `BIFROST_ENCRYPTION_KEY` is set. | ||
|
|
||
| <Tabs> | ||
| <Tab title="Web UI"> | ||
|
|
||
| 1. Navigate to **MCP Gateway** in the sidebar | ||
| 2. Click **New MCP Server** | ||
| 3. Pick **HTTP** or **SSE** as the connection type, fill in the **Connection URL** | ||
| 4. Set **Auth Type** to **Headers** | ||
| 5. Add one row per header in the **Headers** table: | ||
| - **Header name** (e.g., `Authorization`, `X-API-Key`) | ||
| - **Value** — either a literal string or an environment-variable reference | ||
| 6. Configure tool execution as needed | ||
| 7. Click **Create** | ||
|
|
||
| <Frame> | ||
| <img src="/media/ui-mcp-auth-headers-form.png" alt="MCP client form with Auth Type set to Headers and two static header rows configured" /> | ||
| </Frame> | ||
|
|
||
| </Tab> | ||
| <Tab title="API"> | ||
|
|
||
| ```bash | ||
| curl -X POST http://localhost:8080/api/mcp/client \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "name": "web-search", | ||
| "connection_type": "http", | ||
| "connection_string": "https://mcp.example.com/mcp", | ||
| "auth_type": "headers", | ||
| "headers": { | ||
| "Authorization": { "value": "Bearer your-api-key" }, | ||
| "X-Tenant-ID": { "value": "acme-corp" } | ||
| }, | ||
| "tools_to_execute": ["*"] | ||
| }' | ||
| ``` | ||
|
|
||
| To reference an environment variable instead of a literal: | ||
|
|
||
| ```json | ||
| "Authorization": { "env_var": "MCP_API_KEY", "from_env": true } | ||
| ``` | ||
|
|
||
| </Tab> | ||
| <Tab title="config.json"> | ||
|
|
||
| ```json | ||
| { | ||
| "mcp": { | ||
| "client_configs": [ | ||
| { | ||
| "name": "web-search", | ||
| "connection_type": "http", | ||
| "connection_string": "https://mcp.example.com/mcp", | ||
| "auth_type": "headers", | ||
| "headers": { | ||
| "Authorization": { "value": "Bearer your-api-key" }, | ||
| "X-Tenant-ID": { "value": "acme-corp" } | ||
| }, | ||
| "tools_to_execute": ["*"] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Use `{ "env_var": "MCP_API_KEY", "from_env": true }` for env references — same shape as the API tab. | ||
|
|
||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ## Header lifecycle | ||
|
|
||
| - **At connect time**, Bifrost opens a persistent transport with these headers attached. The same transport is reused for every tool call. | ||
| - **`Authorization`** is treated specially — even if you set it via `headers`, the credential-store layer overrides it with the OAuth bearer for `auth_type=oauth` clients. For `headers` clients there is no override, so the literal value goes through. | ||
| - **Editing** headers on an existing MCP client triggers a connection reset so the new headers take effect immediately. The MCP client's `connection_type`, `auth_type`, and `connection_string` are immutable after creation. | ||
|
|
||
| --- | ||
|
|
||
| ## Combining with `per_user_headers` | ||
|
|
||
| `per_user_headers` clients support a **static admin headers** section in addition to the per-user values. Use it for tenant headers or any constant that should accompany every per-user request. See [Per-User Headers — Static admin headers](./per-user-headers#static-admin-headers). | ||
|
|
||
| --- | ||
|
|
||
| ## Next Steps | ||
|
|
||
| - [OAuth 2.0](./oauth) — when the upstream provides OAuth and you want token refresh | ||
| - [Per-User Headers](./per-user-headers) — when each user has their own key | ||
| - [Connecting to MCP Servers](../connecting-to-servers) — connection-type details |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| --- | ||
| title: "No Authentication" | ||
| sidebarTitle: "None" | ||
| description: "Connect to MCP servers that don't require any upstream credential." | ||
| icon: "globe" | ||
| --- | ||
|
|
||
| ## Overview | ||
|
|
||
| `auth_type: "none"` is the default. Use it for MCP servers that don't require any upstream authentication — public MCP services, local STDIO tools, internal services already protected at the network layer, etc. | ||
|
|
||
| This is also the only valid `auth_type` for STDIO connections; STDIO subprocesses inherit their environment from the spawning process and there is no per-call header to attach. | ||
|
|
||
| --- | ||
|
|
||
| ## When to use | ||
|
|
||
| - Public MCP servers with no auth | ||
| - Local STDIO tools (`@anthropic/mcp-filesystem`, etc.) | ||
| - Internal services already gated at the network or VPN layer | ||
| - Anything you'd hit with `curl` and no extra headers | ||
|
|
||
| If the upstream eventually adds a key, switch to [Headers](./headers) and refill the `headers` map. (`connection_type` and `auth_type` are immutable after creation, so plan ahead — auth_type=none can be edited later if you delete and re-create the MCP client.) | ||
|
|
||
| --- | ||
|
|
||
| ## Configuration | ||
|
|
||
| <Tabs> | ||
| <Tab title="Web UI"> | ||
|
|
||
| 1. Navigate to **MCP Gateway** in the sidebar | ||
| 2. Click **New MCP Server** | ||
| 3. Pick a **Connection Type** (STDIO, HTTP, or SSE) and fill in the connection target | ||
| 4. Leave **Auth Type** on **None** (the default) | ||
| 5. Optionally configure `tools_to_execute` / `tools_to_auto_execute` | ||
| 6. Click **Create** | ||
|
|
||
| <Frame> | ||
| <img src="/media/ui-mcp-auth-none-form.png" alt="MCP client form with Auth Type set to None" /> | ||
| </Frame> | ||
|
|
||
| </Tab> | ||
| <Tab title="API"> | ||
|
|
||
| ```bash | ||
| curl -X POST http://localhost:8080/api/mcp/client \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "name": "public-service", | ||
| "connection_type": "http", | ||
| "connection_string": "https://public-mcp.example.com/mcp", | ||
| "auth_type": "none", | ||
| "tools_to_execute": ["*"] | ||
| }' | ||
| ``` | ||
|
|
||
| Response: | ||
|
|
||
| ```json | ||
| { | ||
| "status": "success", | ||
| "message": "MCP client created" | ||
| } | ||
| ``` | ||
|
|
||
| </Tab> | ||
| <Tab title="config.json"> | ||
|
|
||
| ```json | ||
| { | ||
| "mcp": { | ||
| "client_configs": [ | ||
| { | ||
| "name": "public-service", | ||
| "connection_type": "http", | ||
| "connection_string": "https://public-mcp.example.com/mcp", | ||
| "auth_type": "none", | ||
| "tools_to_execute": ["*"] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| --- | ||
|
|
||
| ## STDIO example | ||
|
|
||
| STDIO connections must use `auth_type: "none"`: | ||
|
|
||
| <Tabs> | ||
| <Tab title="Web UI"> | ||
|
|
||
| 1. **New MCP Server** → **Connection Type: STDIO** | ||
| 2. Fill in **Command**, **Args** (comma-separated), and **Envs** (env-var names to pass through) | ||
| 3. Auth Type stays on **None** | ||
| 4. Click **Create** | ||
|
|
||
| </Tab> | ||
| <Tab title="API"> | ||
|
|
||
| ```bash | ||
| curl -X POST http://localhost:8080/api/mcp/client \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "name": "filesystem", | ||
| "connection_type": "stdio", | ||
| "stdio_config": { | ||
| "command": "npx", | ||
| "args": ["-y", "@anthropic/mcp-filesystem"], | ||
| "envs": ["HOME", "PATH"] | ||
| }, | ||
| "auth_type": "none", | ||
| "tools_to_execute": ["*"] | ||
| }' | ||
| ``` | ||
|
|
||
| </Tab> | ||
| <Tab title="config.json"> | ||
|
|
||
| ```json | ||
| { | ||
| "mcp": { | ||
| "client_configs": [ | ||
| { | ||
| "name": "filesystem", | ||
| "connection_type": "stdio", | ||
| "stdio_config": { | ||
| "command": "npx", | ||
| "args": ["-y", "@anthropic/mcp-filesystem"], | ||
| "envs": ["HOME", "PATH"] | ||
| }, | ||
| "auth_type": "none", | ||
| "tools_to_execute": ["*"] | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| </Tab> | ||
| </Tabs> | ||
|
|
||
| <Warning> | ||
| **Docker users:** STDIO connections won't work if the spawned command (e.g., `npx`, `python`) isn't installed in the container. For STDIO-based MCP servers, build a custom Docker image that includes the dependencies, or host the server separately and connect via HTTP/SSE. | ||
| </Warning> | ||
|
|
||
| --- | ||
|
|
||
| ## Next Steps | ||
|
|
||
| - [Headers](./headers) — when the upstream needs an API key | ||
| - [OAuth 2.0](./oauth) — for shared OAuth services | ||
| - [Connecting to MCP Servers](../connecting-to-servers) — connection-type details (STDIO, HTTP, SSE) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parenthetical says
connection_typeandauth_typeare immutable after creation, then immediately says they "can be edited later if you delete and re-create." Readers will infer there is an in-place edit path. Consider rephrasing: "…immutable after creation — to changeauth_typelater you must delete and re-create the MCP client."