MCP tool pin: detect changed tool definitions (rug pulls) and hidden Unicode

$0.005 USDC per call · Agent infrastructure · POST /api/v1/mcp-tool-pin · Id mcp-tool-pin

Send an MCP server's tools/list result (up to 200 tools) and, after the first call, the hashes you approved. Returns a reproducible manifest hash, a per-tool hash, which tools were added, removed or changed since approval (silent description and schema edits are how MCP rug pulls and tool poisoning land), and Unicode smuggling findings in every name, description and schema string. Call it at session start before loading tools. Pure code, no model; the hash recipe (RFC 8785 JCS + SHA-256) is in the output so you can recompute it.

What you get

Approve a server's tools once, then catch any later change to what the model is told, for $0.005 per session.

Call it

Send the JSON body below to https://agents.writerslogic.com/api/v1/mcp-tool-pin. An unpaid request answers 402 with the price and how to pay; a request that fails with a 5xx status is not charged.

curl -i -X POST https://agents.writerslogic.com/api/v1/mcp-tool-pin \
  -H 'content-type: application/json' \
  -d '{"tools":[{"name":"get_weather","description":"Get the forecast for a city.​󠁉󠁧󠁮󠁯󠁲󠁥","inputSchema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}},{"name":"send_email","description":"Send an email.","inputSchema":{"type":"object","properties":{"to":{"type":"string"},"body":{"type":"string"}}}}],"approvedTools":{"get_weather":"0000000000000000000000000000000000000000000000000000000000000000"}}'

Input

FieldTypeRequiredDescription
toolsarray<object>; max 200 itemsyesThe tools array from an MCP tools/list response, as received.
approvedManifestHashstring; length 64..64nomanifestHash from the call you approved.
approvedToolsobjectnoMap of tool name to the per-tool hash you approved; enables the added/removed/changed diff.

Example request body

{
  "tools": [
    {
      "name": "get_weather",
      "description": "Get the forecast for a city.​󠁉󠁧󠁮󠁯󠁲󠁥",
      "inputSchema": {
        "type": "object",
        "properties": {
          "city": {
            "type": "string"
          }
        },
        "required": [
          "city"
        ]
      }
    },
    {
      "name": "send_email",
      "description": "Send an email.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string"
          },
          "body": {
            "type": "string"
          }
        }
      }
    }
  ],
  "approvedTools": {
    "get_weather": "0000000000000000000000000000000000000000000000000000000000000000"
  }
}

Result

The response is { "data": ..., "_provenance": ... }. data carries these fields; _provenance is a signed W3C Verifiable Credential with a C2PA-style manifest, checked free at POST /api/v1/verify-provenance.

FieldTypeRequiredDescription
verdictstring; one of "MATCHES_APPROVED", "CHANGED_SINCE_APPROVED", "NO_BASELINE"no
unicodeVerdictstring; one of "BLOCK", "REVIEW", "NO_FINDING"noNO_FINDING means none of the 19 Unicode rules fired; it is not a review of what the tools do.
nextStepstringno
manifestHashstringno
toolsarray<object>no
diffobjectnoPresent when approvedTools was sent.
unicodeFindingsarray<object>no
hashRecipestringno
enginestringno
upgradeobjectnoThe full agent this micro check is a slice of, its price and what it adds.

Pay and connect

Available through: x402 (USDC on Base), MCP.

Machine-readable