{"slug": "i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting", "title": "I scanned 10 MCP servers – here's what agents can't know before connecting", "summary": "A new tool called mcp-trustcard scans Model Context Protocol (MCP) servers before agents connect, grading them on installability, protocol compliance, tool schema validity, destructive capabilities, authentication, secret exposure, and latency. The project aims to improve security and quality verification in the rapidly growing MCP ecosystem, where clients currently connect blind to servers that may have exploitable weaknesses.", "body_md": "The \"npm audit\" for MCP servers. A trust card for every Model Context Protocol server — before you connect.\n\nEvery day, agents connect to MCP servers they've never met. They don't know whether the server installs, whether it speaks the current protocol, whether its tool schemas are valid, whether it exposes destructive tools, or whether it leaks secrets — **until something breaks or something leaks.**\n\n`mcp-trustcard`\n\ngives every MCP server a **public trust card** in one command:\n\n```\nnpx mcp-trustcard @modelcontextprotocol/server-github\nMCP Trustcard: github-mcp-server  @modelcontextprotocol/server-github\n────────────────────────────────────────────────────────────────────────\nInstallability             PASS  @modelcontextprotocol/server-github@2025.4.8\nProtocol handshake         PASS  github-mcp-server 0.6.2 · 717ms\nTool schema validity       PASS  26 tools, all schemas valid\nDestructive capabilities   PASS  no destructive verbs; 11 write/exec tool(s)\nAuthentication             PASS  no auth required to list tools\nSecret exposure            UNKNOWN  no secrets seen in this run (single probe)\nProtocol version           WARN  negotiated 2024-11-05 (latest is 2025-06-18)\nLatency & failure rate     PASS  1ms avg, 0% failure\n────────────────────────────────────────────────────────────────────────\nScore                      86/100\n```\n\nThe MCP registry is growing fast. Security and quality verification are not. Recent research has found widespread exploitable weaknesses across MCP servers — tool poisoning, prompt injection via tool descriptions, shadowing, and secret leakage. Clients currently connect blind.\n\nThis project is a **public ranking surface**. If maintainers argue with a score, that's traction. If they ask how to improve, that's a product. If teams want private scanning, that's a company.\n\n| Check | Pts | What it probes |\n|---|---|---|\n| Installability | 15 | Does the package resolve and install from npm? |\n| Protocol handshake | 25 | Does it respond to `initialize` over stdio JSON-RPC? |\n| Tool schema validity | 15 | Are `tools/list` schemas well-formed JSON Schema? |\n| Destructive capabilities | 10 | Does it expose delete/drop/kill/overwrite tools? |\n| Authentication | 10 | Is auth required, absent, or unknown? |\n| Secret exposure | 10 | Do tool descriptions or errors leak secret-shaped strings? |\n| Protocol version | 10 | Does it negotiate the latest protocol version? |\n| Latency & failure rate | 5 | Handshake latency + 3-ping failure rate |\n\nEach check returns `PASS`\n\n/ `WARN`\n\n/ `FAIL`\n\n/ `UNKNOWN`\n\nand a partial-credit score. The total is the headline number.\n\nScanned 2026-07-14. Servers are probed as a **naive client** — `npx -y <pkg>`\n\nwith no extra args or env. This is exactly what an agent does on first contact. Servers that require configuration fail the handshake, which is the point: **clients can't discover that requirement before connecting.**\n\n| # | Server | Score | Handshake | Tools | Proto | Destructive | Notes |\n|---|---|---|---|---|---|---|---|\n| 1 | `@playwright/mcp` |\n87/100 |\nPASS · 838ms | 24 | 2025-06-18 | WARN | 6/24 destructive (browser actions) |\n| 2 | `chrome-devtools-mcp` |\n87/100 |\nPASS · 1021ms | 29 | 2025-06-18 | WARN | 5/29 destructive |\n| 3 | `@modelcontextprotocol/server-filesystem` |\n87/100 |\nPASS · 768ms | 14 | 2025-06-18 | WARN | 3/14 destructive (write/delete) |\n| 4 | `@modelcontextprotocol/server-github` |\n86/100 |\nPASS · 717ms | 26 | 2024-11-05 | PASS | Lags latest protocol version |\n| 5 | `@modelcontextprotocol/server-memory` |\n85/100 |\nPASS · 789ms | 9 | 2025-06-18 | WARN | 3/9 destructive (delete_*) |\n| 6 | `@upstash/context7-mcp` |\n85/100 |\nPASS · 997ms | 2 | 2025-06-18 | WARN | Heuristic flagged descriptions |\n| 7 | `@eslint/mcp` |\n85/100 |\nPASS · 915ms | 1 | 2025-06-18 | WARN | 1 tool (lint-files) |\n| 8 | `@modelcontextprotocol/server-brave-search` |\n33/100 |\nFAIL | 0 | — | UNKNOWN | Needs `BRAVE_API_KEY` env — undocumented to client |\n| 9 | `@modelcontextprotocol/server-puppeteer` |\n28/100 |\nFAIL | 0 | — | UNKNOWN | Handshake timeout (needs config/launch args) |\n| 10 | `@storybook/mcp` |\n28/100 |\nFAIL | 0 | — | UNKNOWN | Handshake timeout (needs project context) |\n\n**4 of 10 recognizable MCP servers cannot complete a protocol handshake when invoked the way an agent invokes them.** There is no machine-readable way for a client to learn *why* before connecting. That gap is the wedge.\n\n```\nnpm install -g mcp-trustcard\n# or just:\nnpx mcp-trustcard <server-spec>\n# single server, text report\nnpx mcp-trustcard @modelcontextprotocol/server-github\n\n# single server, JSON\nnpx mcp-trustcard --json @modelcontextprotocol/server-memory\n\n# batch scan (JSON array of specs)\nmcp-trustcard --batch servers/official.json --json-out results.json\n```\n\nExit code is non-zero when the score is below 50, so it drops straight into CI.\n\n```\n- uses: davidnichols-ops/trustcard@v0.1\n  with:\n    server: @modelcontextprotocol/server-github\n    min-score: \"50\"\n    json-out: reports/github.json\n```\n\nThe action fails the job when the score drops below `min-score`\n\n. See `.github/workflows/healthcheck.yml`\n\nfor a full matrix that scans all 10 servers on every push and on a daily cron for drift detection.\n\n`npm view <spec>`\n\n— resolve the package (installability).- Spawn\n`npx -y <spec>`\n\nas a child process with stdio JSON-RPC. - Send\n`initialize`\n\nwith the latest protocol version, measure latency. - Send\n`notifications/initialized`\n\n, then`tools/list`\n\n. - Validate each tool's\n`inputSchema`\n\nas JSON Schema. - Scan tool names + descriptions for destructive verbs and secret-shaped strings.\n- Probe 3 quick\n`tools/list`\n\npings for failure rate. - Score and print the trust card.\n\nNo dependencies. Pure Node stdlib. The whole probe runs in seconds.\n\n**Single probe.** Secret exposure is`UNKNOWN`\n\nunless a secret surfaces in one run. A real audit needs fuzzing and traffic replay.**Naive invocation.** Servers that need args/env fail the handshake. That's a feature, not a bug — it surfaces the discovery gap — but maintainers can fairly argue their server works fine*with*documented config. Good. Let's have that conversation in the scorecard metadata.**Heuristic destructive detection.** Flagging is keyword-based and will have false positives (e.g. a description that mentions \"delete\" in passing). v2 will use call-site analysis.**No auth flow testing.** We detect that auth*seems*required; we don't exercise OAuth.**stdio only.** HTTP/SSE transports are next.\n\nThis repo ships with a proposal for a standard ** mcp.health** metadata field that servers can publish so clients can render a trust card\n\n*before*connecting. See\n\n[. The tracker issue is filed against the spec registry.](/davidnichols-ops/trustcard/blob/master/PROPOSAL.md)\n\n`PROPOSAL.md`\n\nScores are disputable — that's the point. To get your server scanned or to contest a score:\n\n- Open an issue with the server spec.\n- Optionally include a\n`mcp.health`\n\nsnippet (see`PROPOSAL.md`\n\n) so we can verify declared vs. observed behavior.\n\nIf you want to add a check, the scorecard is in `lib/checks.js`\n\nand is deliberately small.\n\nMIT", "url": "https://wpnews.pro/news/i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting", "canonical_source": "https://github.com/davidnichols-ops/trustcard", "published_at": "2026-07-15 00:45:49+00:00", "updated_at": "2026-07-15 01:18:02.890923+00:00", "lang": "en", "topics": ["ai-agents", "ai-safety", "developer-tools", "ai-infrastructure"], "entities": ["mcp-trustcard", "Model Context Protocol", "npm", "Playwright", "Chrome DevTools", "GitHub", "ESLint", "Brave Search"], "alternates": {"html": "https://wpnews.pro/news/i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting", "markdown": "https://wpnews.pro/news/i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting.md", "text": "https://wpnews.pro/news/i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting.txt", "jsonld": "https://wpnews.pro/news/i-scanned-10-mcp-servers-here-s-what-agents-can-t-know-before-connecting.jsonld"}}