Curating the tool surface
Control which OpenAPI operations become MCP tools.
Why curate
An OpenAPI spec built for humans is generous—hundreds of small, separate endpoints. Agents pay a real cost for every tool they see: more context, more chances to pick the wrong one. Converting every operation into a tool, 1:1, can leave agents with a bloated, confusing tool list.
Curation lets you decide what agents actually see.
By tag
Most specs group operations with OpenAPI tags. Use these to include or exclude by tag:
npx klaridian generate --spec ./api.yaml --out ./my-server \
--exclude-tags internal,adminnpx klaridian generate --spec ./api.yaml --out ./my-server \
--include-tags publicBy operation ID
Exclude specific operations regardless of tag:
npx klaridian generate --spec ./api.yaml --out ./my-server \
--exclude-operation-ids deleteAccount,purgeDataBy path or method
Some specs don't use tags at all. --include-paths, --exclude-paths, --include-methods, and --exclude-methods work without them—they match on the operation's URL path (regex) or HTTP method:
npx klaridian generate --spec ./api.yaml --out ./my-server \
--exclude-paths "^/internal/" \
--exclude-methods deletePath/method filters and tag filters can combine—an operation must pass both to be included.
From the spec, with x-klaridian
The filters above are things you decide at generate time. Sometimes the API author is better placed to decide—and wants those decisions to travel with the spec. klaridian reads an x-klaridian extension on any operation for exactly that.
Hide an operation
Set expose: false to keep an operation out of the generated tool surface entirely—useful for internal or maintenance endpoints that should never become agent tools:
paths:
/admin/reindex:
post:
operationId: reindexCatalog
x-klaridian:
expose: false # never generated as a toolAn operation with no x-klaridian, or without expose, is exposed as usual (fail-open). This composes with the flag-based filters above: an operation is generated only if it survives both.
Tune the tool annotations
Every generated tool carries MCP annotation hints (readOnlyHint, destructiveHint, openWorldHint) that tell an agent how risky a tool is. By default klaridian derives them from the HTTP method: GET is read-only, DELETE is destructive, POST and PATCH are writes. When the method isn't the whole story—a POST /calls that spends money, or a POST /search that changes nothing—the author can state the truth directly:
paths:
/calls:
post:
operationId: startCall
x-klaridian:
destructive: true # a POST that really does something irreversible
openWorld: true
/search:
post:
operationId: search
x-klaridian:
readOnly: true # a POST that only readsEach hint is optional and overrides the method-derived default for that hint alone—anything you leave out keeps its default. Recognised keys: readOnly, destructive, openWorld, expose, and title.
Set the tool title
By default a tool's display title is the operation's summary, falling back to a humanized version of its operationId (listBooks → "List Books"). Set title on x-klaridian to override both:
paths:
/books/{id}:
delete:
operationId: deleteBook
summary: Delete a book
x-klaridian:
destructive: true
title: Remove a book from the catalog # wins over the summaryTitle precedence is x-klaridian.title → the OpenAPI summary → the humanized operationId. The tool's name (what the agent calls) is always the operationId—only the human-facing title changes.
A ready-to-generate example lives at examples/annotated/openapi.json in the repository.
Tool order
The server returns tools from tools/list in a fixed order: paths in the order the spec lists them, and within a path, by HTTP method in the order GET, PUT, POST, DELETE, OPTIONS, HEAD, PATCH, TRACE. Curation removes tools but never reorders the ones that remain. Generating from the same spec always gives the same order, which MCP recommends so that clients and model prompt caches see a stable tool list. To change the order, reorder the paths in your spec.
Large APIs
The server returns every tool in a single tools/list response; it doesn't paginate. When a server has more than 128 tools, klaridian generate warns, because VS Code (GitHub Copilot) and OpenAI-backed agents reject requests with more than 128 tools. Pagination wouldn't help here: clients that support it fetch every page and pass the whole list to the model anyway. To get under the limit, curate with the flags on this page, or switch to code mode, which exposes two tools for the whole API.
Flags or x-klaridian: When to use which
The flags and the x-klaridian extension aren't two ways to do the same thing—they answer to different people at different times.
- Flags are the generator's decision, made at generate time. They live in your command (or your
klaridian.config.json), apply to one build, and don't travel with the spec. Reach for them when the choice is yours as the person running klaridian: "for this server, only expose thepublictags," or "skip everything under/internal/." Flags also cover coarse curation—by tag, path, or method—thatx-klaridiancan't express. x-klaridianis the API author's decision, and it travels with the spec. It's versioned alongside the contract, so every consumer generating from that spec inherits it. Reach for it when the knowledge belongs to whoever owns the API: aPOST /callsthat spends money isdestructive,/admin/reindexshould never become a tool (expose: false), and a rawoperationIddeserves a humantitle. A consumer shouldn't have to rediscover any of that through flags.
The two compose. An operation is generated only if it survives both layers, so expose: false in the spec and --exclude-operation-ids on the command line both hide an operation—the difference is intent. expose: false says "this is never a tool, for anyone"; --exclude-operation-ids says "not in this build." Use the spec for durable, author-owned truth; use flags for the choices that change from one generation to the next.
Interactively
Prefer to pick tags by hand instead of writing flags? Use --interactive:
npx klaridian generate --spec ./api.yaml --out ./my-server --interactiveThis prompts you for which tags to include before generating. It needs a real terminal—it fails with a clear error in CI or scripts, instead of silently generating with no tools.