Merge PR #807: support custom headers for MCP HTTP authentication

This commit is contained in:
Re-bin
2026-02-20 08:50:39 +00:00
3 changed files with 23 additions and 4 deletions

View File

@@ -753,6 +753,12 @@ Add MCP servers to your `config.json`:
"filesystem": { "filesystem": {
"command": "npx", "command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"] "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
},
"my-remote-mcp": {
"url": "https://example.com/mcp/",
"headers": {
"Authorization": "Bearer xxxxx"
}
} }
} }
} }
@@ -764,7 +770,7 @@ Two transport modes are supported:
| Mode | Config | Example | | Mode | Config | Example |
|------|--------|---------| |------|--------|---------|
| **Stdio** | `command` + `args` | Local process via `npx` / `uvx` | | **Stdio** | `command` + `args` | Local process via `npx` / `uvx` |
| **HTTP** | `url` | Remote endpoint (`https://mcp.example.com/sse`) | | **HTTP** | `url` + `headers` (optional) | Remote endpoint (`https://mcp.example.com/sse`) |
MCP tools are automatically discovered and registered on startup. The LLM can use them alongside built-in tools — no extra configuration needed. MCP tools are automatically discovered and registered on startup. The LLM can use them alongside built-in tools — no extra configuration needed.

View File

@@ -3,6 +3,7 @@
from contextlib import AsyncExitStack from contextlib import AsyncExitStack
from typing import Any from typing import Any
import httpx
from loguru import logger from loguru import logger
from nanobot.agent.tools.base import Tool from nanobot.agent.tools.base import Tool
@@ -59,9 +60,20 @@ async def connect_mcp_servers(
read, write = await stack.enter_async_context(stdio_client(params)) read, write = await stack.enter_async_context(stdio_client(params))
elif cfg.url: elif cfg.url:
from mcp.client.streamable_http import streamable_http_client from mcp.client.streamable_http import streamable_http_client
read, write, _ = await stack.enter_async_context( if cfg.headers:
streamable_http_client(cfg.url) http_client = await stack.enter_async_context(
) httpx.AsyncClient(
headers=cfg.headers,
follow_redirects=True
)
)
read, write, _ = await stack.enter_async_context(
streamable_http_client(cfg.url, http_client=http_client)
)
else:
read, write, _ = await stack.enter_async_context(
streamable_http_client(cfg.url)
)
else: else:
logger.warning("MCP server '{}': no command or url configured, skipping", name) logger.warning("MCP server '{}': no command or url configured, skipping", name)
continue continue

View File

@@ -258,6 +258,7 @@ class MCPServerConfig(Base):
args: list[str] = Field(default_factory=list) # Stdio: command arguments args: list[str] = Field(default_factory=list) # Stdio: command arguments
env: dict[str, str] = Field(default_factory=dict) # Stdio: extra env vars env: dict[str, str] = Field(default_factory=dict) # Stdio: extra env vars
url: str = "" # HTTP: streamable HTTP endpoint URL url: str = "" # HTTP: streamable HTTP endpoint URL
headers: dict[str, str] = Field(default_factory=dict) # HTTP: Custom HTTP Headers
class ToolsConfig(Base): class ToolsConfig(Base):