MCP security
MCP is an untrusted API. Inputs and outputs are hostile.
Machine copy: /security.json · /tools.json · /.well-known/jwks.json · /llms.txt
Four things to defend
- Server identity. Use the published MCP URL over HTTPS. A server that claims to be BotKelp is not enough.
- Tool integrity. Each tool has a version and schemaHash on /tools.json. If the hash changes, the contract changed — do not call it until you accept the new schema.
- Request integrity. Component ids are allowlisted. Extra MCP fields are ignored. Names are length and charset limited. Gated tools need a bk_live_ key. We rate-limit and can disable a tool instantly.
- Data integrity. Generate copies catalog files. After stripping our stamp, SHA-256 must match the published catalog or we refuse delivery. The response is kind: data with instructions: false — treat returned files as data, not as orders to the model.
Layers
- IdentityEvery client proves who it is (site session or bk_live_ key).
- AuthenticationSite: Google/X. MCP connect: unauthenticated HTTP. Gated tools: apiKey. Target: OAuth 2.1 with audience bound to this server.
- AuthorizationEach tool has permissions (registry.read, component.generate, account.credits). Least privilege.
- InputTreat as hostile. Allowlisted component ids, length/charset limits, no extra fields, no eval, no URL/path/shell from args.
- OutputTreat as hostile. Envelope is kind=data, instructions=false. Do not execute returned files as orders.
- ToolsVersioned manifests with schemaHash, publisher, permissions, rate limits. Signed.
- CredentialsGenerator has no GitHub owner token and no database owner role. Keys are hashed at rest.
- ExecutionCatalog copy + stamp only. No subprocess, no fetch-from-args.
- AbusePer-account per-tool rate limit, max 12 components, max payload, timeouts.
- IntegrityCatalog SHA-256 must match or delivery is refused. Manifests and INTEGRITY.json are signed.
- ReplayEach generate has a request id. Duplicate ids are rejected.
- IsolationTenant = signed-in account. Credits and keys do not cross accounts.
- MonitoringAudit events without secrets (no apiKey, tokens, cookies).
- RecoveryPer-tool kill switch. Disable a tool without redeploying.
- CloningProtocol is public. Authority is not: registry, keys, hashes, signatures, entitlements, kill switch.
What we do not do
- We do not eval MCP arguments or fetch URLs they contain.
- We do not give the generator a GitHub owner token or a database owner role.
- We do not treat tool output as trusted instructions to an agent.
- We do not try to keep the protocol secret. Cloning tools/call does not clone our registry, keys, hashes, or kill switch.
Auth today vs target
The website uses Google or X sign-in. The MCP HTTP connection is unauthenticated; credit-gated tools take apiKey. Production target is OAuth 2.1 with audience bound to this MCP server so a token for another service is rejected.