MCP tool discovery for agents starts before a model calls anything. The tool list must let the model recognize one bounded job, construct valid arguments and predict which evidence the result will return.
That requirement becomes harder when a server exposes adjacent actions. Discovering providers, comparing candidates and selecting one provider all concern routing, but they are not interchangeable. A useful MCP surface keeps those verbs separate enough that a model can choose the next action from the user’s task and the workflow state, without a hidden prompt that explains the catalogue every time.
Discovery happens in two stages
An MCP client first obtains the tools a server exposes. The protocol’s tool definition includes a programmatic name, a human-readable description and a JSON Schema input contract. It can also include a title, an output schema and behavioral annotations. The client then places some or all of those definitions in the model’s available context.
Being present in that list is protocol discovery. Being selected for the right task is semantic discovery. The first is a transport fact. The second depends on whether the definition matches the buyer’s language and gives the model a safe route to a useful result.
This distinction matters for providers. A connected server can still receive no calls because its tools say “search,” “get data” or “route request.” Those labels do not identify the object being searched, the unit returned or the boundary with another tool. The operational work described in getting your API found by AI agents applies inside MCP too: publish a job, not a product category.
Give every tool one decision verb
Start with the decision the tool enables. Apiosk exposes the HTTP discovery chain as three MCP tools: `apiosk_discover`, `apiosk_compare` and `apiosk_decide`. Their names remain related, while the verbs tell a model where each belongs in a workflow.
The description should make the boundary explicit:
- `apiosk_discover` finds providers for a stated job and returns reviewed candidates with stable candidate IDs.
- `apiosk_compare` places specified candidate IDs side by side using shared requirements and measured dimensions.
- `apiosk_decide` returns one provider, the rule that selected it, exact rejection constraints and ordered runners-up.
Do not make the discover description promise a winning provider. Do not describe compare as a broad catalogue search. Do not describe decide as a quality judgment. Apiosk does not measure result quality or provider terms, so neither field can justify a decision score.
Clear verb boundaries also improve observability. A provider can distinguish failure to enter a candidate set from failure to survive a constraint. Combining all three stages into one opaque router hides that difference from the agent and the operator.
Write a manifest for model matching
In practice, the “manifest” a model sees is the collection of tool definitions returned to the client. Each definition should answer four questions in compact, literal language: when should this tool run, what arguments are required, what will it return and when should another tool run instead?
Inspect these fields as one contract:
- `name`: a stable, specific identifier whose verb matches the operation;
- `description`: the bounded job, expected result and important exclusion;
- `inputSchema`: property types, required fields, allowed values and field-level descriptions;
- `outputSchema`: the stable result shape when the server returns structured content;
- `annotations`: behavioral hints such as read-only or open-world access;
- server context: a short explanation of the server’s domain when the client supports it.
Field descriptions matter as much as the top-level description. `candidates` should say that it accepts stable candidate IDs from discovery, not provider names or external URLs. `max_latency_ms` should name its unit. `require_all_inputs` should explain whether a candidate is rejected when the buyer lacks one required field.
Use enums for bounded choices. Apiosk shares `settlement=apiosk|direct` and `optimize_for=price|latency|reliability|balanced` across the chain. Reusing those exact constraints prevents a model from translating “fastest” into one value during comparison and another during selection.
Make the result support the next call
Automatic selection improves when the model can see how one result becomes the next input. Discovery should return stable candidate IDs because compare and decide accept those IDs. Compare should return dimensions, weights and per-candidate contributions because a buyer may need to inspect the evidence before choosing. Decide should explain both selection and rejection because an operator may prefer a runner-up.
This is more precise than asking a model to infer workflow state from prose. The output contract itself says what can happen next. A predictable structured result also makes it easier for the client to validate a response before placing it back into model context.
Keep external discovery hits outside this chain. `GET /v1/discover` can sweep external x402 sources, but those hits appear separately in `external_candidates`. They have no `candidate_id`, are unreviewed and unmeasured, and cannot enter compare, decide or Apiosk settlement. A tool description that calls every hit “available” would erase a boundary the model needs.
The same principle applies to paid tools. A payment-ready MCP tool manifest should point to live payment requirements rather than freezing changeable terms in a cached description. Tool metadata helps route the call; the gateway response remains authoritative for current payment terms.
Test selection without naming the tool
A good selection test gives the model a buyer task, not the tool name. If the prompt says “call `apiosk_discover`,” it tests invocation syntax rather than discovery. Use a cold session with the same tool set a production client exposes.
Run task-shaped cases such as:
- find providers that can verify a postal address;
- compare these candidate IDs under one maximum latency;
- choose one candidate for reliability and explain every rejection;
- show available capabilities before the buyer knows the job label;
- find external options but do not treat them as reviewed candidates.
Record the selected tool, arguments, validation failures and whether the result supplied the fields needed for the next step. Test nearby negative cases too. A request to compare two known IDs should not trigger discovery again. A request for candidates should not silently make the final choice.
Tool annotations can help clients filter or approve calls, but they are hints rather than proof. Treat permission policy as a client control. Treat tool descriptions and schemas as routing inputs. Mixing those responsibilities creates either unsafe automation or unnecessary approval prompts.
Where Apiosk fits
The Apiosk MCP server exposes discovery, comparison and decision as three named tools that mirror the HTTP chain. A provider can list an API on Apiosk so its capability and input contract can enter the reviewed catalogue that `apiosk_discover` searches.
The discovery result supplies stable IDs. The comparison step evaluates price, settlement rail and input compatibility, plus latency and success rate where enough calls have been measured. Every score is relative to that candidate set, includes its weights and contributions, and names dimensions dropped for missing measurements. The decision step returns the selected provider and the evidence needed to challenge it.
MCP does not make a vague endpoint self-routing. It gives you a structured surface on which clear routing metadata can work. Keep one verb per tool, make schemas executable, return evidence for the next action and test with buyer language that never names the implementation.
Frequently asked questions
What makes an MCP tool discoverable to a model?
The client must expose the tool, and its definition must give the model a recognizable job, a precise description and a valid input schema. Discovery does not guarantee selection; the tool still has to match the current task better than the alternatives.
Should one MCP tool discover, compare and select a provider?
Separate tools make the workflow and evidence boundaries visible. A model can discover candidates first, compare a chosen set next and request a decision only when the task requires a final provider.
Does an output schema improve MCP tool selection?
An output schema tells a client and model what structured result to expect after the call. It is optional in MCP, but it can distinguish nearby tools when their outputs support different next actions.
Can tool annotations prove that an MCP tool is safe?
No. Read-only, destructive, idempotent and open-world annotations are hints, not security guarantees. Clients should apply their own trust, permission and approval controls.