# Screen an MCP server

> Check what an MCP server answers, what tools it offers and whether they changed, with a hosted screen or a command you run yourself. What the report contains, what it does not check, and why it is not a certificate.

An MCP server tells an agent what it can do. Badge **screens** it: it asks the server what it speaks and which tools it offers, checks that the answers are well formed, and records a hash of the tool list so you can see when it changes. A screen is a measurement taken at one moment. &#x2A;*It is screened, not certified.** The report is unsigned, it is private to your account, and it does not say the server is safe.

There are two ways to run the same screen:

* **Hosted.** You give Badge the URL of a public https server and Badge screens it. Use this for a server on the internet that needs no login.
* **On your machine.** `badgeia mcp screen` runs the same checks against a server you run, including a stdio server that has no URL. Nothing is sent to Badge, and you need no account or key. The `badgeia` command line tool is not published for download yet, so this route is for people Badge has given it to.

The hosted screen is off unless your deployment turns it on. While it is off, every route answers 404. The command line works either way.

What a screen checks [#what-a-screen-checks]

| Check             | What it looks at                                                                                                                                                                                                                              |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Reachable         | Whether the server answers at all.                                                                                                                                                                                                            |
| Discovery         | The `server/discover` answer the 2026-07-28 MCP specification requires: supported versions and capabilities. A server that still speaks the older `initialize` handshake is screened that way and reported as a legacy handshake.             |
| Tool list         | `tools/list`, all pages. Whether the list carries `ttlMs` and `cacheScope`, and whether it comes back in the same order each time.                                                                                                            |
| Tool names        | Duplicates, and names that differ only by case or punctuation.                                                                                                                                                                                |
| Schemas           | Whether each tool's `inputSchema` and `outputSchema` is well formed JSON Schema 2020-12. This checks the shape of every keyword. It is not a full validation against the metaschema.                                                          |
| Sign-in           | Whether the server asks for a login, and whether its 401 answer carries a proper Bearer challenge. Badge never sends a credential.                                                                                                            |
| Latency           | The median and the 95th percentile of 20 `server/discover` and 20 `tools/list` requests.                                                                                                                                                      |
| Tool surface hash | One SHA-256 of the full tool definitions, and one per tool. Two screens of an unchanged server give the same hash.                                                                                                                            |
| Pin               | Whether the hash equals a value you supply. Use it to notice when a server's tools change under you.                                                                                                                                          |
| Description lint  | Informational only. It flags text that looks like an instruction aimed at a model, hidden characters and very long descriptions. Findings give a rule, a tool name and a position, never the text. Treat them as hints: they are often wrong. |

What it does not check [#what-it-does-not-check]

* It never calls a tool. A call can change things on your system and cannot be undone, so the screen sends only `server/discover`, `initialize` (for older servers) and `tools/list`.
* It does not look behind a login. A server that asks for credentials is reported as protected, and nothing more is read.
* It does not measure how a tool behaves, how often it fails, or where data goes.
* It does not read or keep tool descriptions. The report stores names, counts, hashes, rule identifiers and timings.
* It does not say who runs the server or whether the name is theirs. The server name and version in the report are what the server says about itself.
* It does not follow the sign-in metadata link, and it does not try to open a session.

Run it on your machine [#run-it-on-your-machine]

```bash
# a server you start with a command (stdio)
badgeia mcp screen "node path/to/server.js"

# a server on a URL you can reach, including localhost
badgeia mcp screen http://localhost:8080/mcp

# fail if the tools changed since you last looked
badgeia mcp screen "node path/to/server.js" --pin <sha256-from-an-earlier-screen>

# keep a report and name what changed next time
badgeia mcp screen "node path/to/server.js" --json > before.json
badgeia mcp screen "node path/to/server.js" --baseline before.json
```

| Exit code | Meaning                                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------------------- |
| 0         | Screened. Failed checks are in the report; they do not change the exit code.                                   |
| 1         | The pin did not match, or the server refused (a login is required, or an opt-out). Also a usage error.         |
| 2         | Badge could not reach the server: no such command, the process exited, a timeout, a connection or TLS failure. |

Run it hosted [#run-it-hosted]

`POST /api/v1/mcp-screens` with `{"server_url": "https://example.com/mcp"}` and an optional `"pin"`. You need a verified email, and either a signed-in session or an API key with the write scope. The screen takes up to a minute.

```bash
curl -s -X POST https://api.badgeia.com/api/v1/mcp-screens \
  -H "X-API-Key: $BADGE_API_KEY" -H "Content-Type: application/json" \
  -d '{"server_url": "https://example.com/mcp"}'
```

`GET /api/v1/mcp-screens` lists your reports and `GET /api/v1/mcp-screens/{id}` returns one.

|                              | Free                      | Pro and above                             |
| ---------------------------- | ------------------------- | ----------------------------------------- |
| Screens                      | 3 in any rolling 24 hours | 30 in any rolling 24 hours                |
| Reports                      | The latest only           | Every report                              |
| Change since the last screen | Not shown                 | Added, removed and changed tools, by name |

The same server can be screened once an hour per account. A report belongs to the account that ran it. Nobody else can read it, and it is not published anywhere. It carries no signature, so you cannot show it to someone else as proof of anything.

The hosted screen accepts a public https address by DNS name, on port 443 or 8443, with no login, query string or fragment in the URL. Addresses on private networks are refused, and so is any name that resolves to one.

What your server sees [#what-your-server-sees]

Badge asks politely and tells you who is asking.

* Requests come with the user agent `badge-screen/0 (+https://badgeia.com/docs/screen-an-mcp-server)`.
* A screen sends at most 48 requests and takes at most 60 seconds. No more than one screen of your server runs at a time, and Badge limits how many screens any server gets in an hour, across all accounts and across every name that points at the same address.
* **To opt out**, serve any 2xx answer at `/.well-known/badge-screen-opt-out` on your host, or send the response header `X-Badge-Screen: deny` on any response. Badge then stops, and does not screen that host again for 24 hours. To block it for good, write to [support@badgeia.com](mailto:support@badgeia.com) from the address of the domain.

What to do with a report [#what-to-do-with-a-report]

Pin the hash of a server you have read and trust, and screen it again from time to time or before each upgrade. A changed hash does not mean the change is bad. It means the tools your agent sees are no longer the ones you looked at.
