feat(mcp): add user-configurable MCP servers (URL + custom headers)
Lets users register Streamable-HTTP MCP servers from the Settings page.
Tools discovered from each enabled server are merged into the per-request
tool set under the `mcp__<slug>__<tool>` prefix and dispatched back to the
right server via runToolCalls. Headers (e.g. `Authorization: Bearer ...`)
are stored on the row.
Backend
- New `user_mcp_servers` table (RLS owner-only) with migration 001 + the
same DDL inlined in the one-shot schema.
- `lib/mcp/{client,servers,types}.ts`: thin wrapper around
@modelcontextprotocol/sdk's StreamableHTTPClientTransport, per-request
loader, schema converter (MCP `inputSchema` -> Mike's OpenAIToolSchema)
with 64-char tool-name truncation.
- `runLLMStream` and `runToolCalls` accept an optional `mcpServers` list;
chat routes load + close clients in a try/finally.
- New `routes/mcpServers.ts` mounted at `/user/mcp-servers` with
GET/POST/PATCH/DELETE plus `/test` for connect-and-list-tools probing.
All handlers filter by user_id since the backend uses the service role
key.
Frontend
- New `account/mcp` settings tab and page: add/edit/delete servers, toggle
enabled, run test connection. Header values are masked in the form
(type=password) and the GET endpoint returns header keys only.
- `mikeApi.ts`: typed CRUD wrappers.
Notes for review
- Header values are stored via the same RLS-only model used today for
`user_profiles.claude_api_key`/`gemini_api_key`. Per-row encryption is
a clean follow-up.
- OAuth-protected MCP servers are out of scope for this PR; a follow-up
will add an OAuth 2.1 client (PKCE + dynamic client registration) so
spec-conformant servers (e.g. https://legaldatahunter.com/mcp) work
without manual token paste.
| Repository | nforum/mike |
|---|---|
| Author | Zacharie Laik <zacharie@goodlegal.fr> |
| Authored | |
| Parents | d9690965 |
| Stats | 15 files changed , +1911 , -4 |
| Part of | MCP "Connectors": user-configurable MCP servers with OAuth 2.1 |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-277339f6.md
from inside the repo you want the change in.