Rightshold™ Sign up

Answers · MCP security

How do I separate read-only analysis MCP tools from side-effecting tools and lazy-load by task?

Last updated

TL;DR: Do not dump every connected MCP server's full tools/list into the model at session start. Split the catalog into a read-only analysis set (search, fetch, get, list) and a side-effecting set (write, send, pay, delete, deploy), keep side-effecting tools out of context until the task actually needs them, and record which tool name plus which schema/version you exposed when you load it. MCP client best practices (2025-11-25) call this progressive discovery: fetch tools/list host-side, give the model a lightweight search or catalog meta-tool, and inject full definitions only as needed — especially once tool definitions take more than a small share of the context window. Treat readOnlyHint and destructiveHint as untrusted hints unless the server is one you pin and trust; enforce the split with your own allowlists, separate credentials, and human approval for anything that writes, sends, or spends. Pair check_tool_integrity (or precall_check) before enabling a write toolset, and record_ai_run when you want a signed receipt of the selected tool fingerprint for the run.

What should I check, step by step?

1. Inventory every connected MCP server's tools into two buckets you own: analysis/read (no environment change) vs side-effecting (write, send, pay, delete, mutate). Do not trust the tool name alone.

  1. Keep a host-side full tools/list (or per-server cache). Do not inject every schema into the model prompt by default.
  2. Expose a small always-on catalog: search_tools / list_toolsets / enable_toolset (or your host's equivalent), with one-line descriptions and a read_only vs side_effect flag per entry.
  3. Lazy-load by task: when the model (or a skill) picks a toolset, inject only that tool's full inputSchema — append after the cache breakpoint, or route calls through a stable call_tool meta-tool so the tools array stays cache-friendly.
  4. Gate side-effecting enablement: require a separate credential or scope, and request_human_approval (or your own confirm) before the first write tool of a session or task.
  5. On enable, record tool name, server URL/serverInfo.version, and a hash of the tool definition (name + description + inputSchema + annotations). Re-check on notifications/tools/list_changed.
  6. Treat annotations as routing hints for trusted servers only. readOnlyHint defaults to false and destructiveHint to true; unannotated tools are side-effecting until proven otherwise by your allowlist and credentials.
  7. After the run, seal which tools were selected and which versions with record_ai_run (tool names + definition hashes in params). Use check_tool_integrity or precall_check before unfamiliar write servers.

How do I split the catalog before the model sees it?

MCP client best practices warn that naive hosts pass every connected server's tool definitions into the model at the start of each conversation; with dozens of servers that can consume most of the context window before the user message is read.

How do I lazy-load by task and record what was selected?

Switch to progressive discovery when tool definitions take a meaningful share of the context window (MCP's client guidance suggests thresholds around 1%–5% as a starting point). For a handful of tools, loading all is fine.

Are annotations and hints the security boundary?

Tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) shipped in the 2025-03-26 MCP revision. The schema says they are hints and are not guaranteed to describe behavior faithfully; clients must treat them as untrusted unless they come from trusted servers.

What can go wrong?

Every server's full tools/list is pasted into the system prompt; the model picks a send_email tool while "just researching".

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before I enable write tools for this task, check that this MCP server's tools/list fingerprint still matches what I recorded for the read-only analysis set, and flag any new or changed side-effecting tools.”

One-click setup

{
  "tool": "check_tool_integrity",
  "arguments": {
    "url": "https://mcp.example.com",
    "expected_tools_sha256": "<sha256 of the reviewed tools/list or selected tool definitions>"
  }
}

Rightshold checks MCP listings and recorded tool fingerprints and can record human approvals and AI-run receipts for agents that call it. It does not sit in your host's context window, split your tool catalog, or stop a client that injects every tools/list into the model. Enforce progressive discovery and the read vs write split in your MCP host. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'