Skip to content

Refactor api2ai into modular architecture for mcp-use 2.x - #76

Merged
vtempest merged 1 commit into
masterfrom
claude/laughing-fermat-hzj69j
Oct 7, 2026
Merged

vtempest merged 1 commit into
masterfrom
claude/laughing-fermat-hzj69j

Conversation

@vtempest

@vtempest vtempest commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Refactored the monolithic generate-mcp-use-server.js into a modular architecture with separate concerns for spec loading, schema conversion, tool extraction, code generation, and CLI handling. Updated generated servers to target mcp-use 2.x API with zod 4 support.

Key Changes

  • Modularized codebase: Split 1000+ line single file into focused modules:

    • spec/load-spec.js — fetch and parse OpenAPI specs (JSON/YAML)
    • spec/schema-to-zod.js — convert OpenAPI schemas to Zod source code with proper escaping
    • spec/extract-tools.js — extract operations into tool descriptions
    • spec/classify-risk.js — categorize tools by risk level with MCP annotations
    • templates/* — one module per generated file (package.json, .env, policy, http-client, etc.)
    • cli.js — command-line argument parsing and entry point
    • generate.js — orchestrate spec loading and file rendering
    • index.js — library exports
  • mcp-use 2.x compatibility:

    • Generated servers now use MCPServer class and inputSchema (not schema)
    • Tool annotations: readOnlyHint, destructiveHint, idempotentHint derived from HTTP method
    • Async listen() instead of synchronous server setup
    • Zod 4 with z.iso.datetime(), z.email(), z.uuid() formatters
  • Improved schema handling:

    • Proper JSON string literal escaping via literal() function — prevents injection of newlines, backslashes, */ into generated code
    • Local $ref resolution with cycle detection (cycles become z.unknown())
    • allOf merging for plain object schemas
    • OpenAPI 3.0 (nullable: true) and 3.1 (type: ['string', 'null']) nullability support
    • Enum values and descriptions safely escaped
  • Enhanced HTTP client:

    • Streamed response reading with byte-cap enforcement
    • Proper URL joining (preserves base path like /api/v3)
    • Form-encoded body support
    • Timeout and size limits configurable via environment
  • Better documentation:

    • Generated README with tool table, security model, and environment variable reference
    • Clearer .env/.env.example with inline comments
    • Tool annotations visible in Inspector
  • Test coverage: Added comprehensive test suite (packages/grab-url/test/api2ai.test.ts) covering schema conversion, tool extraction, CLI parsing, and generated file validity

Implementation Details

  • Safe code generation: All user-controlled strings (descriptions, names, enum values) go through JSON.stringify() before splicing into generated source
  • Backward compatibility: Old entry point generate-mcp-use-server.js re-exports from new modules
  • Flexible tool filtering: Support for tag-based inclusion/exclusion, operation ID blacklists, and custom filter functions
  • Risk classification: Automatic detection of dangerous patterns (delete, payment, auth, etc.) with override flags for mutations

https://claude.ai/code/session_01RDDWQMAX1u1DQcFHrE5hFY

…use 2.x

The 1,000-line generate-mcp-use-server.js is now spec/ (load, OpenAPI → Zod,
risk, tool extraction), templates/ (one module per generated file),
generate.js, cli.js and index.js. The old path remains as a re-exporting shim.

Generated servers now target mcp-use ^2.7.3 + zod 4: `import { MCPServer }
from 'mcp-use'`, `inputSchema`, MCP tool annotations, awaited listen(), raw
tool results with isError/structuredContent, and `mcp-use dev` for the
Inspector. dotenv is replaced by `node --env-file-if-exists`.

Fixes along the way:
- descriptions/enums with quotes, newlines or backslashes broke the output
- base URL path was dropped (`/api/v3` + `/pet` → `/pet`)
- relative and templated `servers[].url` are resolved
- local $ref schemas/parameters/bodies, allOf, 3.0/3.1 nullable
- --approve-writes was parsed but never applied
- duplicate tool names and duplicate path/operation params
- host allowlist now defaults to the spec's API host, as documented
- response size cap is enforced while streaming, in bytes
- regenerating no longer overwrites an existing .env

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDDWQMAX1u1DQcFHrE5hFY
@vercel

vercel Bot commented Oct 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
grab-url Error Error Oct 6, 2026 6:45am UTC

@codecov

codecov Bot commented Oct 6, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@vtempest
vtempest merged commit 08c4200 into master Oct 7, 2026
15 of 16 checks passed
@vtempest
vtempest deleted the claude/laughing-fermat-hzj69j branch October 7, 2026 03:27

This branch had an error being deployed

1 failed deployment
Preview — e92f67ae Deployed Oct 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants