Skip to content

v2.6.0 — MCP-native tools, request builder & client targets

Choose a tag to compare

@github-actions github-actions released this 11 Aug 23:42
· 48 commits to main since this release

The biggest release since 1.0 — 731 tests (up from 477), 100% coverage enforced in CI, and every change hardened by an adversarial review pass before tagging.

✨ Highlights

🧰 Stop hand-writing request assembly. buildHttpRequest() applies the full OpenAPI serialization table — deepObject queries, label/matrix paths, multipart, binary, whole-body payloads, cookies. Pure function, bring your own fetch:

const req = buildHttpRequest(tool, { id: '42', filter: { tag: 'news' } });
// → https://api.example.com/users/42?filter[tag]=news

await fetch(req.url, { method: req.method, headers: req.headers, body: req.body as BodyInit });

🎯 One spec, valid on every client. Claude, OpenAI strict mode, and Gemini each accept a different JSON Schema subset. Pick a target and ship schemas that client actually accepts:

const tools = await generator.generateTools({ target: 'gemini' });
// 'claude' | 'openai' | 'gemini' | 'strict'

🏷️ MCP-native tools out of the box. Every tool now carries a title and MCP annotations inferred from HTTP semantics (GET → read-only, DELETE → destructive), plus spec-compliant names (64-char cap, stable dedup). Override anything from the spec via the x-mcp extension family.

🔎 Curate instead of dumping. Filter by tag, method, or path glob — or flip the read-only safety switch:

await generator.generateTools({ includeTags: ['public'], excludePaths: ['/admin/**'], readOnlyOnly: true });

🔒 Security

  • SSRF connection pinning — the DNS-validated address is the one actually connected to, closing the rebinding race noted in 2.5.0
  • secureDefaults: true — one flag for untrusted specs: redirects off, external $ref resolution off
  • Request guards: header names/values, cookies, base URLs, and path templates are all validated before a request is built

🛠 Also in this release

  • toSdkTool() — one-line tool registration with the official MCP TypeScript SDK
  • Clean JSON Schema 2020-12 output: nullable → type unions, example → examples, applied under every keyword
  • allOf bodies flatten; union and binary bodies map cleanly (wholeBody, serialization.binary)
  • includeExamples and maxSchemaDepth now work; tool ordering is deterministic
  • McpOpenAPITool<TMeta> metadata generics and per-scheme includeSecurityInInput: string[]

⚠️ Upgrading

Change Impact
Tool names are normalized (64-char cap, invalid chars replaced, collisions deduped) Only affects names that Claude/Bedrock already rejected
maxSchemaDepth (default 10) is now enforced Very deep schemas truncate with a note
generateTools() output is sorted by path, then method Stable order; previously spec key order
Non-object bodies map with wholeBody: true Send the value as the whole body — or just use buildHttpRequest

📚 New guides: Request Builder · Client Targets · Annotations & Extensions

Full change list

Features

  • buildHttpRequest pure request builder with full OpenAPI style/explode serialization (#12)
  • Client compatibility targets: claude / openai / gemini / strict (#12)
  • Tool title + annotations inferred from HTTP semantics with x-mcp family overrides (#11)
  • MCP tool-name rules: sanitization, length caps, stable collision dedup (#11)
  • Tag / method / path-glob filtering, readOnlyOnly switch, x-mcp precedence root < path < operation (#12)
  • Generic tool metadata, per-scheme includeSecurityInInput, secureDefaults preset (#12)
  • toSdkTool adapter for MCP SDK registerTool (#12)
  • allOf body flattening, wholeBody flag, binary/encoding markers (#11)
  • includeExamples and maxSchemaDepth implemented; deterministic ordering (#11)
  • JSON Schema 2020-12 normalization across all structural keywords (#11)

Fixes (adversarial review rounds)

  • secureDefaults merges per key; explicit-undefined values cannot defeat the lockdown
  • OpenAPI explode defaults per style; cookie values verbatim with RFC 6265 validation
  • Server URL templates substituted from spec defaults; unresolved templates throw
  • Union collapses run to fixpoint; Gemini output never carries x-variants; external $refs removed
  • OpenAI target implements the full strict contract (closed objects + required/nullable, enum/const-safe)
  • Header names token-validated; Content-Type handling case-insensitive; multipart lets the client set the boundary
  • Digest credentials pass through verbatim; name dedup fails loudly on exhausted name spaces

Security

  • SSRF-safe fetch with connection pinning; every redirect hop re-validated (#9, #10)

Installation

npm install mcp-from-openapi@2.6.0

Release line: 2.6.x · Branch: release/2.6.x · Type: stable