# MCP Server Vetting Checklist How to tell a vendor's own server from a stranger's in ten seconds, what to check before you install anything, how to scope the credential, and what to do when something looks wrong. Companion to `mcp-small-business-starter.md` and `check-mcp-endpoints.mjs`. Version 1.1, 2026-08-22. Source article: https://jwatte.com/blog/mcp-servers-for-small-business/ --- ## 0. The one thing to internalise **An MCP server is a program you are running with your credentials.** Not a plugin, not an integration, not an app-store listing. A program, with a token, acting on your behalf, that you usually did not write and cannot read. Everything below follows from that. The official registry does not change it. Listing there means the namespace was authenticated and the metadata parsed. It hosts metadata, never code, performs no code review, and its own moderation policy says it will not remove a server for having a security vulnerability. Reading the registry as an app store is the expensive mistake. --- ## 1. The ten-second test Look at exactly two things, wherever you found the server. ``` REMOTE ENDPOINT Is the URL on the vendor's own domain? REPOSITORY Is it in the vendor's own GitHub organisation? ``` **Both yes:** it is the vendor's. Proceed to section 2. **Both no:** it is somebody else's, whatever the name says. Section 4. **Mixed:** treat as somebody else's until you can explain the mismatch. The endpoint is the field that matters. Of nine registry-listed first-party servers checked on 22 August 2026, four left the repository field empty, so on those the domain is the only identifying signal there is. ### Do not use the registry as your index Being absent from the official registry says nothing about a vendor. Ten companies running live production MCP servers on 22 August 2026 were not in it at all: HubSpot, Xero, Square, Calendly, Intercom, Pipedrive, Asana, Canva, Sentry and Squarespace. **Search the vendor's own documentation first.** Then confirm the endpoint answers, with `check-mcp-endpoints.mjs` or by hand. The registry is a cross-check, and a poor index. ### Why the name is not enough Real examples from the registry, all checked on 22 August 2026: | Looks like | Actually is | |---|---| | `al.square/fiskalizimi` | square.al, an Albanian tax and payroll tool. Not Square. | | `app.seatcanvas/seatcanvas` | A seating-plan app. "seatcanvas" contains "canva". Not Canva. | | `ai.intuitek.the-stall` | "Intuitek", a pay-per-call tool chassis. Not Intuit. | | `com.microsoft.esrp/esrp-oss-mcp-test` | Repository is an individual's account; the npm package is named `...-test`. | None of these are necessarily doing anything wrong, and the last one may well be an employee's legitimate work. That is the point: **you cannot tell from the namespace, and the namespace is what a list shows you.** Known-good examples, for calibration. Note how many have no repository at all: ``` com.stripe/mcp -> mcp.stripe.com + github.com/stripe/agent-toolkit com.cloudflare.mcp/mcp -> docs.mcp.cloudflare.com and siblings + github.com/cloudflare/mcp-server-cloudflare com.atlassian/atlassian-mcp-server -> mcp.atlassian.com/v1 + github.com/atlassian/atlassian-mcp-server com.wix/mcp -> mcp.wix.com + github.com/wix/wix-mcp com.webflow/mcp -> mcp.webflow.com + github.com/webflow/mcp-server com.paypal.mcp/mcp -> mcp.paypal.com (no repository field) com.notion/mcp -> mcp.notion.com (no repository field) com.airtable/mcp -> mcp.airtable.com (no repository field) app.linear/linear -> mcp.linear.app (no repository field) ``` Cloudflare is the reason to compare domains rather than exact hostnames. It publishes under `docs.mcp.cloudflare.com` and two siblings, not the bare `mcp.cloudflare.com` you would guess. --- ## 2. Before installing a first-party server Even the vendor's own server deserves five minutes. ``` [ ] Is it remote (OAuth) rather than local (a secret in a file)? Prefer remote. [ ] What scope does the OAuth consent screen actually ask for? Read it, do not click through. [ ] Does the vendor offer read-only credentials? Use them. [ ] Read its permission scopes, do not just count them. Fetch /.well-known/oauth-protected-resource at BOTH the endpoint path and the domain root. Square publishes two of these and they disagree: 0 at the path, 49 at the root. Then ask the only question that matters: is there a read scope I can take WITHOUT the matching write scope? - Square 26 read / 23 write, Canva 10/6, Airtable 4/3: yes, take the read half. - Xero 4 read / 0 write: no write scope exists at all. Best case. - Sentry 1 read / 3 write: mostly write. Look twice before connecting it. - Notion, Asana: a single scope named `default`. All or nothing. [ ] An empty scope list is NOT "no control". Stripe scopes through restricted API keys and dashboard settings instead. Check the vendor's permission docs. [ ] Which of my data can this reach? Write the answer down in one sentence. [ ] What is the worst case if this token leaks? If you cannot say, do not install it yet. [ ] Am I installing at local scope, or pushing it to my whole team? ``` **The read-only habit is the highest-value item on this list and it costs nothing.** Grant write access for one specific job, then take it away again. --- ## 3. Before installing a community server If you have decided to anyway, this is the minimum. ``` [ ] Open the repository. Does it exist, and is it public? [ ] When was the last commit? Older than a year is abandonware. [ ] How many people have contributed? One person who stopped is a risk. [ ] Read the tool descriptions in the source. Those strings go into the model's context and are exactly where a tool-poisoning attack would live. [ ] Does it phone anywhere other than the service it claims to talk to? [ ] Check the package registry for the published artefact. Does the name match the repository? [ ] Search the CVE databases for the package name. [ ] Pin a version. Do not float on latest for something holding a credential. [ ] Give it a token scoped to the least it can possibly do. [ ] Would I be comfortable if this token appeared in a public paste tomorrow? ``` **If the answer to the last one is no, and you cannot scope the token down further, do not install it.** That is the whole decision. ### Never for these, regardless - Accounting and bookkeeping systems - Payroll - Anything holding customer payment details - Anything holding health, immigration or legal information - Your primary email account, with write access - Production databases, with write access For those categories, use the vendor's own server or nothing. --- ## 4. The threat you are actually defending against Not "the author is malicious", usually. Three more likely shapes: **The code has a hole.** This is young software. A search of the National Vulnerability Database for "Model Context Protocol" returns 74 results, and several of the serious ones are in official code rather than community projects: a critical data-exfiltration flaw in Anthropic's own deprecated Slack server, a high-severity symlink escape in the reference Filesystem server, and a high-severity crash in the official Python SDK, all disclosed in early July 2025. If the reference implementations had holes, a weekend project certainly can. **Tool descriptions are model instructions.** The text describing what a tool does is fed to the model. A server can therefore influence the assistant's behaviour through a field nobody reads during install. Read those strings before you trust a server with anything. **Untrusted content becomes instructions.** Any server that fetches a web page, an inbox, a ticket queue or a document is a path from whoever wrote that content into your agent. The Claude Code documentation says this directly: verify you trust each server, and servers that fetch external content can expose you to prompt injection. **The exfiltration channel is rarely the obvious one.** In the Slack case the data left through link previews: the agent was induced to write a message containing a crafted URL with data in it, and Slack's own preview bots fetched the URL. Nobody thinks of a link preview as an output. --- ## 5. Credential rules ``` 1. Read-only by default. Write access is a temporary, specific grant. 2. One credential per server. Never reuse a token across two servers. 3. Prefer OAuth over a static key, because you can revoke it from the vendor's side. 4. Never paste a key into a file that a repository might contain. Check your .gitignore. 5. Write down, somewhere you will find it: what each token is, what it can do, when to rotate. 6. Rotate anything a server has held when you remove the server. 7. If a laptop with local servers is lost, rotate every credential on it. All of them. ``` Point five is the one that decays. A list of tokens you cannot explain is the same as no list. --- ## 6. Ongoing, twice a year ``` [ ] Run `claude mcp list`. Is anything connected that you forgot about? [ ] For each server: still used? If not, remove it and rotate its credential. [ ] For each community server: last commit date, any new advisories? [ ] For each token: still scoped to the minimum? Still needed at write level? [ ] Re-read your own one-sentence note about what each server can reach. Still true? ``` Twice a year, thirty minutes. Put it in the calendar or it does not happen. --- ## 7. When something looks wrong The signals, in the order you will notice them: * The assistant does something you did not ask for, in a system you did not mention. * It references data from a source that was not part of the task. * A tool call fails in a way that mentions an unfamiliar host. * Your spend jumps with no change in your usage. * The vendor emails you about an API call you did not make. The response: ``` STEP 1 Disconnect the server. Do not investigate first. STEP 2 Revoke its credential at the vendor, not just in your config. STEP 3 Write down what happened, with times, before you forget. STEP 4 Check the vendor's audit log for what the token actually did. STEP 5 Only then work out whether it was the server, the content it read, or a coincidence. STEP 6 If it was a community server, open an issue with what you saw. Others are running it. ``` Disconnecting first costs you almost nothing and preserves every option. Investigating first while a suspect program keeps running is how a small problem becomes a long afternoon. --- ## 8. The summary, if you read nothing else * An MCP server is a program running with your credentials. * The registry lists 24,240 of them and reviews none. * Roughly seventy percent are published under an individual's GitHub account. * The registry is also missing ten major vendors' real servers, so start at the vendor's docs. * Check the remote endpoint's domain. Nothing else reliably identifies a publisher, and four of nine verified first-party records had no repository field at all. * First-party or nothing, for anything that matters. * Read-only by default, one credential per server, rotate on removal. * If a CLI tool would do the job, use that instead. --- Companion file at https://jwatte.com/downloads/ * `mcp-small-business-starter.md` : what it is, whether you need it, the short list and the install paths * `check-mcp-endpoints.mjs` : asks each vendor directly whether it runs a server, and how tightly you can scope it Written by J.A. Watte. https://jwatte.com