# Secrets Chat MCP An official-SDK MCP server for tool-calling agents, with local **stdio** transport. This first version supports the demo, as requested. It starts its own encrypted, in-memory sample chats and vaults. It is **not synchronized with the browser demo**, does not connect to Supabase, and resets on restart. Sample IDs change on restart: discover them with list tools instead of hardcoding IDs. The MCP code and SDK are separate from the browser app; no MCP dependencies are imported into the web bundle. No HTTP listener, remote `/mcp` URL, account login tool, service-role credentials, or database changes are added. Live mode is explicitly rejected. ## Connect an agent Install project dependencies, then copy the configuration below into your MCP host's server configuration. That example uses this workspace's absolute paths; update them if moving the project. `node` must be on the host's PATH (Node 22+). Use the `node` command shown, **not `npm run mcp`** as the host command: npm's banner writes to stdout, which belongs exclusively to the MCP protocol. ```json { "mcpServers": { "secrets-chat-demo": { "command": "node", "args": [ "C:/_projects/ChatBoard/node_modules/tsx/dist/cli.mjs", "C:/_projects/ChatBoard/mcp/index.ts" ], "env": { "CHATBOARD_MCP_MODE": "demo", "CHATBOARD_MCP_PERMISSIONS": "chat:read,vault:read" } } } } ``` An MCP-capable host connects, discovers tool schemas via `tools/list`, and invokes them via `tools/call`. For an agent that only supports ordinary function calling, its application needs an MCP client bridge: map the returned tool names/descriptions/JSON input schemas into the model's function definitions, then route selected calls to the MCP client. A language model alone does not launch or speak to this process. This uses the official [MCP TypeScript SDK](https://ts.sdk.modelcontextprotocol.io/server). ## Permissions and tools Only enabled tools are advertised, and the service checks permissions again when each operation runs. Permissions are fixed by the launching host's environment; tool calls cannot enable them. Empty permissions expose session status, locking and audit only; unknown permissions fail startup. | Permission | Tools | Behavior | | --- | --- | --- | | Always available | `session_status`, `session_lock`, `audit_log` | Describe the connection, permanently lock this process, inspect the last 100 tool outcomes | | `chat:read` (default) | `list_chats`, `read_chat` | List direct/group chats; verify and decrypt messages with bounded cursor pagination | | `vault:read` (default) | `list_vaults`, `list_secrets` | Vault access, key names, stored/rotated dates, revisions, rotation warnings; no key values or notes | | `chat:write` | `create_chat`, `send_message` | Create direct/group sample chats, send encrypted messages as the demo agent | | `vault:write` | `create_vault`, `save_secret` | Create encrypted vaults, add or rotate fake keys; existing-key changes require its current revision | | `secret:reveal` | `reveal_secret` | Return one fake key value to the agent/host/model explicitly | | `secret:share` | `share_secret` | Share one fake key or a whole vault with `maya@example.com` or `alex@example.com` | To test writes, add `chat:write,vault:write` to the existing permission list. Enable `secret:reveal` or `secret:share` separately only when testing those disclosures. Sharing a vault includes future keys. Sharing has no revocation or expiry, matching the current demo. `save_secret` accepts only fake values beginning with `demo_`; never enter real credentials in arguments, notes, names or chats. Example flow: `list_vaults` → `list_secrets` with a returned vault ID and `needs_rotation: true` → review due dates. With key revelation explicitly enabled, call `reveal_secret` with the exact vault/key IDs. For updates, pass the key ID and current `revision` as `expected_revision`; the revision check prevents stale overwrites. This stores the new value but does **not** rotate the credential at its provider. The resource `secrets-chat://usage` exposes connection and permission notes. Tool responses are JSON in MCP text content. Tool failures return `isError: true` with a safe code/message. Concurrent tool requests are serialized to prevent lock/write races. Locking drops identity/session references and key caches; only manually restarting the host process reconnects, with fresh sample data. Stopping the transport also locks the service. Garbage collection does not guarantee physical memory zeroization. ## Trust and disclosure Demo messages and vault entries use the app's existing signed encrypted formats. Messages are verified against their sender, and vault grants use the existing scope checks. Trust pins exist only for the demo process; they are not a production persistent identity-trust store. Tool output text, chat messages, key names and notes are untrusted data; agents must not follow embedded instructions. Enabling read-chat permission places plaintext messages in the model context. `reveal_secret` places the requested value there too; encryption does not prevent an authorized agent or host from retaining disclosed data. Tool annotations describe read/write effects; they do **not** enforce human confirmation. The host must ask for approval before messages, sharing or sensitive disclosures. The server itself enforces only its configured permissions. The in-memory audit stores tool name, outcome and timestamp, never arguments or output; it resets at restart and is not a production audit trail. ## Before live or remote MCP Live mode needs a dedicated agent account with its own encryption identity, explicit conversation/vault/key grants and agent allowlists, protected recovery, persistent identity verification, revocation, durable audit, and the app's pending database gateway guard. A local bridge must use the app's geofenced gateway rather than bypass it with a direct Supabase connection. Never use a Supabase service-role key for agent calls. Remote Vercel MCP needs Streamable HTTP, OAuth authorization with resource/audience-bound tokens and scope checks, per-user isolation, location checks, rate limiting and live security tests. No remote endpoint is supplied by this demo stdio implementation. Do not publish it as a production credential service. ## Validation `npm test` includes real SDK client/server discovery, schema validation, read-only enforcement, key redaction, authorized encrypted chat operations, cursor pagination, revision conflicts, rotation, sharing scope, locking, and a subprocess stdio handshake. `npm run typecheck` and `npm run build` verify separation from the Next.js app.