Skip to main content

Tools

A tool is a function the server exposes for an agent to call. The agent picks the tool and supplies arguments; the server runs it and returns the result.

EDITED MCP's tools span three data domains — Competitive Market Data, Trend & Research, and Messaging & Promotions — plus a set of mdmcp helpers. Some resolve fuzzy concepts into stable identifiers (slug, id); others return product data, analytics, article passages, or promotions directly. See The data for the full map, or the Reference for every tool's schema.

Discover tools​

const { tools } = await client.listTools();
// → [{ name: "mdmcp-search_retailers", description: "...", inputSchema: {...},
// outputSchema: {...} }, ...]

Each tool exposes:

  • name — the stable identifier, used in tools/call
  • description — prose the agent reads to decide when to call
  • inputSchema — JSON Schema for the arguments
  • outputSchema — JSON Schema for the response, covering both branches of the envelope described in Result shapes below

Call a tool​

const result = await client.callTool({
name: "mdmcp-search_brands",
arguments: { query: "Nike", search_limit: 5 },
});
// Read the payload from result.structuredContent — see Result shapes below.
// result.content also exists, but it is the LLM-facing channel, not the contract.

The auto-generated Reference lists every tool with its full schema and a live "Try it" widget.

Batch queries​

The market-data search tools accept either a single string or a list of up to ten strings. Pass a list and the server runs the searches concurrently, returning results in the same order:

await client.callTool({
name: "mdmcp-search_retailers",
arguments: { query: ["Zara", "H&M", "Uniqlo"], search_limit: 3 },
});
// → one { retailers, search_limit, at_search_limit } wrapper per query, in
// order — search_retailers is the only search tool that wraps its hits; the
// others return one bare list per query

When you need to resolve several entities at once, batch — it's faster than serial calls and lighter on context.

Result shapes​

A tool call that runs returns an object with exactly one of result or error, read from structuredContent — the machine contract, which always matches the tool's published outputSchema. Some refusals arrive on a second channel instead, so check isError first:

if (result.isError) {
// never completed — the text is prose, not JSON
throw new Error(result.content?.[0]?.text ?? "call failed");
}
const body = result.structuredContent;
if (body.error) throw Object.assign(new Error(body.error.message), body.error);
const brands = body.result; // matches the Brand model

Tools also return a content array of TextContent blocks. That channel is what an LLM sees and it deliberately differs: on success it carries the payload without the envelope, and on a refusal it carries a plain prose message rather than JSON. Read structuredContent for anything you branch on — the one exception being the isError path above, where it is null and the text is the only message there is.

An in-band refusal arrives with isError: false and structuredContent.error, so a client checking only isError reads it as a success — while a client checking only the payload crashes on the isError cases. See Concepts → Response shape for which refusals use which channel, the error codes, and the Python .data caveat.

Errors​

Server-side failures surface as JSON-RPC errors:

{
"jsonrpc": "2.0",
"id": 1,
"error": { "code": -32602, "message": "Invalid request parameters" }
}

See Operations → Errors for every code, the HTTP-level statuses, and retry guidance.