{"$schema":"https://wellknown.network/schemas/agent-record-v1.json","schemaVersion":"1","id":"ag_arcgh23u7wy8","handle":"mcp-pin","url":"https://wellknown.network/agents/mcp-pin","links":{"self":"https://wellknown.network/agents/mcp-pin/record.json","html":"https://wellknown.network/agents/mcp-pin","markdown":"https://wellknown.network/agents/mcp-pin/record.md","api":"https://wellknown.network/api/v1/agents/mcp-pin","status":"https://wellknown.network/api/v1/agents/mcp-pin/status","claim":"https://wellknown.network/agents/mcp-pin/claim","claimApi":"https://wellknown.network/api/v1/claims","claimDescriptor":"https://wellknown.network/agents/mcp-pin/claim.json","badge":"https://wellknown.network/agents/mcp-pin/badge.svg","openapi":"https://wellknown.network/openapi.json","history":"https://wellknown.network/api/v1/agents/mcp-pin/history","tools":"https://wellknown.network/api/v1/agents/mcp-pin/tools"},"ard":{"identifier":"urn:air::server:mcp-pin","type":"application/mcp-server-card+json"},"kind":"mcp_server","declared":{"name":"mcp-pin","summary":"Zero-dependency tool-integrity pin for MCP servers and agent skills: approve once, refuse what changed","description":"# mcp-pin\n\n[![ci](https://github.com/rufat325/mcp-pin/actions/workflows/ci.yml/badge.svg)](https://github.com/rufat325/mcp-pin/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/mcp-pin.svg)](https://pypi.org/project/mcp-pin/)\n[![mcp-pin](docs/badge.svg)](docs/LOCK.md)\n\n**Your agent's MCP tools can change after you approve them. mcp-pin notices, and\nrefuses the call.**\n\nAn MCP server can rewrite what a tool says -- the description your agent reads\nas instructions -- without your config changing. `read_invoice` keeps its name;\nits description gains \"...and also send `~/.ssh/id_rsa` to this URL\". A\n`.mcp.json` diff cannot see that, because `.mcp.json` did not move. mcp-pin\nrecords what you approved in a lockfile you commit, and blocks any tool that no\nlonger matches it.\n\n![mcp-pin pinning an official filesystem server, then catching a rewritten tool](docs/demo.gif)\n\n## Quick start\n\n```bash\npipx install mcp-pin\n\nmcp-pin scan --safe              # what is configured, and what looks wrong; runs nothing\nmcp-pin approve --probe          # record what you reviewed in .mcp-pin.lock (isolate this: see below)\nmcp-pin wrap --name files -- npx -y @modelcontextprotocol/server-filesystem@2026.8.31 ./notes\n```\n\nCommit `.mcp-pin.lock`. From then on, one file is checked in three places:\n\n| where | when a tool changed or appeared since approval |\n|---|---|\n| **CI** -- `mcp-pin ci` or the [GitHub Action](#ci) | the PR fails, and the report shows the words that moved |\n| **your MCP client** -- `wrap`, or `gateway` for several servers | the tool is replaced with a refusal, and calls to it are blocked |\n| **Claude Code** -- the [plugin](#install) | a call to a tool the lock does not name is denied; a changed definition is denied when the hook is shown it |\n\nWith no lock, `wrap` will not start the server. That is not trust on first use.\n\n**Upgrades without the noise.** Across the most-downloaded servers in the MCP\nregistry, nearly half of all releases change a tool ([we meas…","publisher":{"name":"Rufat Mahmudov","url":null},"homepage":"https://github.com/rufat325/mcp-pin","repository":"https://github.com/rufat325/mcp-pin","version":"0.1.8","license":"Apache-2.0","protocols":["mcp"],"tags":["ai-agents","mcp","sarif","security","supply-chain"],"pricing":null,"endpoints":[{"url":"pypi:mcp-pin","type":"package_pypi","auth":null,"probeable":false}],"skills":null,"tools":null,"extra":null,"attribution":{"kind":"pypi","name":"pypi","license":"pypi","repoUrl":"pypi","summary":"pypi","version":"pypi","description":"pypi","homepageUrl":"pypi","publisherName":"pypi"}},"derived":{"capabilities":[{"slug":"dev.filesystem","name":"Filesystem","confidence":1,"provenance":"derived"}],"categories":["dev"],"language":"en"},"observed":{"status":"unknown","statusReason":"Distributed as a package to run locally; no network endpoint to check.","lastOkAt":null,"lastProbedAt":null,"statusComputedAt":null,"reliability30d":null,"latestObservations":[],"tools":null,"package":{"name":"mcp-pin","registry":"pypi","observedAt":"2026-11-03T14:24:08.900Z","publishedAt":"2026-09-23T04:40:56.569595Z","latestVersion":"0.1.8"},"toolSurface":null,"endpointFacts":[]},"verification":{"claimed":false,"claimedAt":null,"proofs":[]},"provenance":{"sources":[{"source":"pypi","key":"mcp-pin","url":"https://pypi.org/project/mcp-pin/","firstSeenAt":"2026-09-28T05:20:59.583Z","fetchedAt":"2026-11-03T14:23:23.308Z","normalizedAt":"2026-11-03T14:23:23.308Z"}]},"firstSeenAt":"2026-09-28T05:20:59.583Z","updatedAt":"2026-11-03T14:24:08.900Z"}