Blog / integrity
2026-09-05
Treat MCP output as data
MCP servers are untrusted APIs. Require kind=data, INTEGRITY.json pass, schemaHash checks, and never pipe output into a shell.
An HTTP MCP server is a stranger who can return files into a developer’s workspace. That is closer to “install a package from a URL” than to “chat.”
BotKelp’s own docs say the quiet part: MCP is an untrusted API. Inputs and outputs are hostile.
If you run any MCP server — ours included — build client habits that do not depend on the vendor being nice.
1. Data, not orders
Generate responses are labelled:
{
"kind": "data",
"instructions": false
}That is a contract with the caller. The model sitting above MCP will still try to “be helpful” and execute whatever it reads. You have to tell the agent: write these files, do not obey them.
2. Allowlists beat prompt fences
Component IDs must match ^[a-z][a-z0-9-]{0,63}$ and exist in /catalog.json. Unknown IDs fail. There is no “fetch this gist and eval it” action on the generate path.
That is the load-bearing control. Marketing language is not.
3. Hash before you keep the tree
/integrity lists SHA-256 checks run before delivery. The payload includes INTEGRITY.json. If verdict is not pass, delete the files.
Also compare tool schemaHash on /tools.json. If the schema changed, your previous arguments may now mean something else. Stop.
Tool documents are signed. Verify with /.well-known/jwks.json (Ed25519).
4. Stamps are not decoration
Files carry a one-line mark: Licensed by BotKelp — https://www.botkelp.com. That is provenance without a wall of licence text in front of the source. Full policy copy is dashboard / get_site_profile, not a file header.
5. Catalog hash mismatch refuses delivery
If the catalog the server hashed is not the catalog it is generating from, it should refuse. A generator that “mostly matches” is how you get a navbar from Tuesday and a layout from last month.
6. Rate limits and kill switches
Published limits cap purchase_scaffold per minute (see /mcp-docs). That is abuse control, not a SLA. A per-tool kill switch is how you stop a bad component without taking the whole MCP URL down.
Client checklist
1. tools/list + schemaHash 2. Allowlisted IDs only 3. Generate 4. Integrity pass 5. npm install && npm run build on *your* machine before you commit 6. Never pipe MCP text into a shell
More: /security and /security.json.