feat(mcp): remote MCP servers per chat with sealed keys and owner-only commands
Streamable HTTP/SSE servers from the workspace's .volcanic/mcp/servers.json. Headers are sealed with AES-GCM; the chat and the visible fields are the associated data, so only /mcp_add|remove|tools change servers. Tools <server>__<tool> go live in the session. An unreachable server is skipped and reported in the system prompt. Keys are redacted from tool results, and Telegram deletes messages that carry one.
This commit is contained in:
@@ -68,6 +68,7 @@ settings use the `GoogleCalendar` section, the scheduler the `Scheduler` section
|
||||
| `PLAYWRIGHT_ENABLED` / `Mcp:Playwright:Enabled` | `false` | Browser tools through `@playwright/mcp` ([mcp.md](mcp.md)) |
|
||||
| `PLAYWRIGHT_HEADLESS`, `PLAYWRIGHT_BROWSER`, `PLAYWRIGHT_EXTRA_ARGS`, `PLAYWRIGHT_COMMAND` | `true`, `chromium`, —, `npx` | See [mcp.md](mcp.md#the-playwright-preset) |
|
||||
| `Mcp:Servers:<name>` | — | Other stdio MCP servers ([mcp.md](mcp.md#configuration)) |
|
||||
| `MCP_ENCRYPTION_SECRET` | the bot token | Seals the keys of each chat's remote MCP servers ([mcp.md](mcp.md#remote-servers-per-chat)). Set it so a new bot token doesn't make the stored servers unreadable. Hidden from `bash` and redacted |
|
||||
| `A2A__Enabled` / `A2A:Enabled` | `false` | Serve other agents over A2A (see [A2A](#a2a) and [a2a.md](a2a.md)). Opens Kestrel: port 8080 in the container, `ASPNETCORE_URLS` or Kestrel's default (`http://localhost:5000`) under `dotnet run` |
|
||||
| `A2A__PublicUrl` / `A2A:PublicUrl` | — | External base URL for the agent card and push webhooks, e.g. `https://bot.example.com`. Required for push to work; see [docker.md](docker.md) |
|
||||
| `A2AClient__Enabled` / `A2AClient:Enabled` | `false` | The A2A client: the `a2a` tool in every allowed chat, for calling other agents listed in the chat's `.volcanic/a2a/agents.json`, and watches for their long tasks (see [A2A](#a2a) and [a2a.md](a2a.md#client)). Independent of `A2A__Enabled` |
|
||||
@@ -127,6 +128,10 @@ started a chat with the bot, Telegram refuses the message; the bot logs that and
|
||||
| `/calendar_status` | The connected account and time zone, or the pending code |
|
||||
| `/calendar_disconnect` | Revoke and delete this chat's calendar token, or cancel a pending connect |
|
||||
| `/a2a` | This chat's A2A callers and recent tasks, remote agents and watches (see [A2A](#a2a)) |
|
||||
| `/mcp_list` | This chat's remote MCP servers: status, header names (never values), allowed and active tools |
|
||||
| `/mcp_add <name> <url>` | Add a remote MCP server; the bot asks for the key and deletes your answer (see [Remote MCP servers](#remote-mcp-servers)) |
|
||||
| `/mcp_remove <name>` | Remove one; its tools disappear at once |
|
||||
| `/mcp_tools <name> [a,b\|all]` | Show a server's tools, or limit which ones the agent gets |
|
||||
|
||||
Any other `/command` is passed to the session, so extension commands such as `/claude-code-doctor` and
|
||||
`/claude-code-login` work. `/mcp` lists the MCP servers (see [mcp.md](mcp.md#mcp)).
|
||||
@@ -299,6 +304,22 @@ chat's account, so nobody sees another chat's calendar through the agent. The bo
|
||||
sending the link and code and confirms in the chat once access is approved. Setup of the Google Cloud app, token
|
||||
storage and time zones are in [google-calendar.md](google-calendar.md).
|
||||
|
||||
### Remote MCP servers
|
||||
|
||||
Each chat can connect its owner's remote MCP servers (Streamable HTTP or SSE; no processes are started):
|
||||
|
||||
```
|
||||
/mcp_add notes https://mcp.example.com/mcp
|
||||
→ Key for notes: send the token (sent as "Authorization: Bearer <token>"), or one "Header-Name: value" per line, or - for none.
|
||||
tok_abc123 ← your reply; the bot deletes it and the agent never sees it
|
||||
→ Added notes (https://mcp.example.com/mcp): 12 tools on the server.
|
||||
```
|
||||
|
||||
Options: `--tools a,b` (allowlist), `--transport auto|http|sse`, `--bearer <token>` or `--header "Name: value"` instead
|
||||
of the question (the bot deletes that message too), `--no-key`, `--force` (save even when the server can't be reached
|
||||
now). The tools appear in the same conversation as `notes__<tool>`. Only these commands change the servers: the agent
|
||||
can't add one, even by editing `.volcanic/mcp/servers.json`. Details in [mcp.md](mcp.md#remote-servers-per-chat).
|
||||
|
||||
### A2A
|
||||
|
||||
With `A2A__Enabled=true` the bot also serves [A2A](a2a.md): other agents can call it over HTTP once given a key.
|
||||
|
||||
Reference in New Issue
Block a user