A tool call that works in your own test script can still fail the moment a real model is driving it — a vague description picked in the wrong context, an error message the model can’t parse, a write tool that duplicates itself on retry. None of that shows up by running the server and manually calling each tool once. Here’s a practical checklist to work through before you publish an MCP server anywhere — your own docs, the official registry, or a directory like gate’s.

A clean scan is a floor, not a finish line

Run your server through a security scan first — gate’s free MCP security scanner or the official MCP Inspector will both connect, list your tools, and flag obvious problems: prompt-injection phrasing in a description, hidden Unicode, permissions that look broader than the tool’s stated job. That check matters, and it’s worth doing early, but as we covered in what an MCP security scanner actually checks, it’s a text-based review of what your tools say, not a test of what they actually do when a model calls them in a real conversation. A server can pass a clean scan and still be broken, confusing, or unsafe to retry.

Call every tool yourself, not just once

Before anything else, connect to your own server with an actual MCP client — the MCP Inspector, Claude, or a hosted checker like gate’s browser-based inspector — and call each tool with realistic arguments, missing arguments, and clearly wrong arguments. Watch what comes back in each case. A tool that only ever gets tested with perfect input looks finished right up until a model passes it something slightly off, which happens constantly once real users are driving it.

Read your descriptions like the model does

The model never sees your code, your comments, or your intentions — it sees the tool name, the description, and the schema, and decides whether and how to call the tool from that alone. Read each one cold, as if you’d never seen the server before. Would you know when to use this tool, and what arguments it needs, from the text alone? We wrote up the specific pitfalls — vague verbs, missing constraints, descriptions that double as instructions to the model instead of documentation for it — in how to write MCP tool descriptions your AI will actually use correctly.

Set your annotations honestly

If your tools set readOnlyHint, destructiveHint, or the other MCP tool annotations, check that they match reality — a “read-only” tool that can actually delete something under the wrong argument combination is worse than not setting the hint at all, because a client or gateway may use it to relax how carefully a call gets reviewed. We covered why these are hints rather than guarantees, and what to set if you’re building a server, in MCP tool annotations explained.

Test what happens on a retry

AI clients retry stalled or timed-out tool calls as a matter of course — it’s normal behavior on their end, not a bug. If one of your write tools isn’t safe to call twice with the same arguments, a retry turns into a duplicate email, ticket, or charge, and nothing in the protocol stops that from happening silently. Before you publish a write tool, call it twice in a row with identical arguments and check what actually happens on the far side. We laid out the underlying problem and some concrete fixes — idempotency keys, checking for an existing record before creating a new one — in MCP tool idempotency.

Don’t just count tools — curate them

If you generated your server from an existing API, it’s easy to end up exposing every endpoint as its own tool. A long, undifferentiated tool list doesn’t just clutter a client’s context; it measurably hurts how reliably a model picks the right tool at all, which we went through in how many tools should an MCP server expose. Before you publish, look at your tool list the way a user’s AI client will: does every tool earn its place, or are several of them the same underlying action with slightly different names?

What a directory listing actually checks: gate’s own self-serve directory submission is one concrete example of an automated pre-publish check: it runs deterministic pattern checks alongside a model review of every tool description, scores the server, and only servers at grade B or better move on to a human review before listing. That two-stage shape — automated check first, human judgment second — is worth copying for your own release process even if you never list anywhere: let a scan catch the obvious problems fast, then have an actual person read through the tool list before it ships.

The bottom line

A security scan tells you your tool descriptions aren’t hostile. It doesn’t tell you they’re clear, that your annotations are accurate, or that a retry won’t double-charge someone. Before you publish an MCP server, call every tool with real and bad input, read your own descriptions as a model would, and check what a duplicate call actually does. If you’re building the server itself rather than testing one you already have, gate’s MCP server builder is one way to start from an existing API instead of from scratch.