What a Good MCP Tool Description Looks Like

An agent reads your tool description to decide whether to call you. Here is what it needs: the question the tool answers, an example, the cost, and what an empty result means.

An MCP server can be perfectly built and still never get called. The reason is usually not the code. It is the description.

When an agent connects to a Model Context Protocol server, it does not read your source. It does not read your README. It reads a short block of text attached to each tool, plus a JSON schema for the inputs. That text is the whole basis for its decision to call you, skip you, or call you wrong. If the description is vague, the agent guesses. If it is too long, the agent skims. If it is written for a human developer instead of for a model choosing between twenty tools, it gets ignored in favor of something clearer.

This piece is about what to put in that text. It is written from the point of view of a data server that serves SEC and House disclosure signals, but the pattern applies to any tool.

The description is a decision aid, not documentation

Start with what the agent is actually doing. At every step it looks at the user's request, the tools it has, and it asks one question: which of these, if any, gets me closer to an answer? Your description competes for that slot. It is not a place to explain your architecture. It is not a changelog. It is a pitch, and it has to be honest, because a description that oversells produces bad calls that the agent then has to recover from.

That framing gives you a rule. Every sentence in the description should help the model answer one of four questions:

  1. What question does this tool answer?
  2. What does a good call look like?
  3. What does calling it cost?
  4. What does an empty or partial result mean?

If a sentence does not serve one of those, cut it.

Part one: the question the tool answers

Most weak descriptions describe the tool's mechanism. "Queries the disclosures database and returns matching records." That tells the agent nothing it can match against a user request. Nobody asks an assistant to "query the disclosures database." They ask things like "did any senator buy Nvidia recently" or "who is buying the same small caps as Renaissance."

So write the description as the question it answers, in the user's language, and be specific about the boundaries.

Weak:

Returns congressional trading data.

Better:

Answers: which members of Congress reported buying or selling a given stock, and when. Covers periodic transaction reports filed with the House Clerk and the Senate. Does not cover holdings, only transactions. Does not cover trades that have not yet been filed.

Notice the negatives. Telling the agent what the tool does not do is as valuable as telling it what it does. It stops the model from calling you for something adjacent and then treating your empty result as proof there was nothing there.

If your data has a structural delay, say so here in one line and let the agent decide whether the tool fits the question. Congressional trades are reported on a lag governed by the STOCK Act's 45-day window, which is covered in detail in the 45-day rule and why it matters. Institutional holdings on Form 13F have their own quarterly lag, covered in 13F deadlines and the 45-day lag. A description does not need to re-explain either. It needs a sentence like "data reflects filings, not real time, and filings can trail the trade by weeks." That one sentence changes how an agent phrases its answer to the user, which is the whole point.

Part two: an example call

Schemas describe shape. Examples describe intent. Models are much better at pattern-matching a worked example than at reasoning from a type definition, so a single concrete call inside the description does more than three paragraphs of parameter notes.

Keep it tiny and realistic:

Example: {"ticker": "NVDA", "since": "2026-05-01", "side": "buy"} returns buy transactions in NVDA reported on or after that date, newest first.

That example quietly teaches four things: the ticker is uppercase, the date is ISO format, side is a closed set of values, and results are sorted. You could state each of those in prose. The example does it in one line, and the model will copy the form.

If the tool has one common mistake, put the correct version in the example rather than warning about the wrong one. Warnings get read as trivia. Examples get read as templates.

For a Form D tool the same idea applies. Form D filings are exempt offering notices, and if a reader wants to know how the fields fit together they can read how to read a Form D filing. The description should not carry that. It should carry a call like {"industry": "Technology", "min_amount": 5000000, "days": 30} and one sentence saying what comes back.

Part three: the cost

Agents budget. Every call adds latency, consumes context window when the result comes back, and may cost money on a metered server. If your description is silent on cost, the agent assumes it is cheap and free, and it may call you in a loop.

Cost has three parts worth naming:

  • Latency. "Typically returns in under a second" or "may take several seconds for wide date ranges." Rough is fine. Invented precision is not.
  • Result size. "Returns up to 50 rows by default. Use limit to reduce." A model that knows the result may be large will ask for less or paginate.
  • Money and quota. If calls are metered, say so and say what a call costs in the unit the user pays in. If there is a free tier or a free alternative for the same raw data, name it. For congressional data the free primary source is the House Clerk's disclosure site at disclosures-clerk.house.gov. For 13F and Form D filings it is EDGAR full text search. A signal server adds scoring and structure on top of those. It does not own the underlying facts, and the description should not pretend otherwise.

Being upfront about cost also protects you. An agent that knows a call is expensive will explain that to the user before making it, instead of racking up calls and leaving the user surprised.

Part four: what empty means

This is the part almost everyone skips, and it is the part that causes the most wrong answers downstream.

When a tool returns nothing, the agent has to interpret that. Without guidance it will pick the most convenient reading, which is usually "there is nothing to find." For disclosure data that is often false. An empty result can mean any of:

  • No filings match, genuinely.
  • The window is too recent and the filings have not been submitted yet.
  • The ticker is not the one used on the filing, because the filing lists an issuer name or a different security.
  • The filter combination is too narrow.
  • The server has not ingested the latest batch.

Each of those calls for a different next step by the agent. So the description should say which are possible and how to tell them apart:

An empty result does not mean no trades occurred. Filings can lag the trade date. If since is within the last few weeks, widen the window or check last_ingested in the response before concluding nothing was reported.

If your response includes a field that helps disambiguate, name it in the description. last_ingested, total_before_filter, matched_issuer_names. Fields like these are cheap to add and they turn a silent zero into something the agent can reason about.

The same applies to partial results. If a query hits a limit, the response should say so, and the description should tell the agent to look for that flag. "Results are truncated when truncated: true. Narrow the query or page with cursor."

Putting it together

Here is a full description in the shape described above. It is a template, not a spec, and yours should be shorter or longer depending on how much genuinely needs saying.

congress_trades Answers: which members of Congress reported buying or selling a given stock, and when. Covers periodic transaction reports from the House and Senate. Transactions only, not holdings. Data reflects filings, which can trail the trade by weeks. Example: {"ticker": "NVDA", "since": "2026-05-01", "side": "buy"} returns buy reports in NVDA on or after that date, newest first, up to 50 rows. Cost: usually under a second. Wide date ranges return more rows and take longer. Use limit to reduce. Empty results do not mean no trades occurred. Filings lag. If since is recent, widen the window or check last_ingested. Free primary source: disclosures-clerk.house.gov.

That is under 120 words. It answers all four questions. It names the free alternative. It does not explain how congressional disclosure works end to end, because that is a separate topic and there is a piece for it at how congressional trading disclosures work. A description should link out mentally the same way a good article does: state the fact, point to the depth, move on.

What to leave out

A few things that show up constantly in tool descriptions and hurt more than they help:

  • Marketing language. "Powerful," "comprehensive," "real-time." The agent cannot act on these and they lower trust in everything around them. If your data is not real time, saying it is produces confident wrong answers.
  • Implementation details. Which database, which language, which cloud. Irrelevant to the decision.
  • Legal boilerplate in the description body. Put disclaimers in the response payload or on the site. The description is for routing. And to say it plainly once here: signals built from disclosure filings are information, not investment advice.
  • Restating the schema. If the schema says ticker: string, required, the description does not need to say it again. Spend the words on what the schema cannot express: meaning, cost, and the interpretation of results.

A test you can run

Read your description and imagine you are a model with fifteen other tools in front of you and a user who just asked "has anyone in Congress been buying defense stocks this summer." Can you tell, from the text alone, whether this tool applies, how to call it, what it will cost, and what to say if it comes back empty? If any of those four is a guess, that is the sentence to fix.

Descriptions are the cheapest part of an MCP server to change and the most consequential for whether it gets used well. Write them for the reader you actually have.

If you want to see what the underlying data looks like when it is scored and structured this way, the Congress Stock Trades report shows recent reported trades by members of Congress, with the filing dates and lag visible so you can judge the freshness yourself.


Want the signal instead of the raw filings? Get a free report preview. Prefer the tool to the write-up? Browse all data feeds or connect the free MCP server.