klaridian()
How-to guides

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,admin
npx klaridian generate --spec ./api.yaml --out ./my-server \
  --include-tags public

By operation ID

Exclude specific operations regardless of tag:

npx klaridian generate --spec ./api.yaml --out ./my-server \
  --exclude-operation-ids deleteAccount,purgeData

By 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 delete

Path/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 tool

An 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 reads

Each 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 summary

Title 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 the public tags," or "skip everything under /internal/." Flags also cover coarse curation—by tag, path, or method—that x-klaridian can't express.
  • x-klaridian is 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: a POST /calls that spends money is destructive, /admin/reindex should never become a tool (expose: false), and a raw operationId deserves a human title. 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 --interactive

This 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.

On this page