-
Notifications
You must be signed in to change notification settings - Fork 0
feat: implement format resolution for JSON Schema with built-in and custom resolvers #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
0bf4809
feat: implement format resolution for JSON Schema with built-in and c…
frontegg-david 90f72bf
Merge branch 'main' into support-formats
frontegg-david 4468833
feat: enhance CI workflow with coverage reporting and absolute README…
frontegg-david 31b6f06
feat: improve CI summary output for test coverage and update file pat…
frontegg-david 68afe31
chore: update GitHub Actions to use checkout@v6 and setup-node@v6
frontegg-david File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| # CLAUDE.md - Project Guide for mcp-from-openapi | ||
|
|
||
| ## Project Overview | ||
|
|
||
| **mcp-from-openapi** converts OpenAPI 3.0/3.1 specifications into MCP (Model Context Protocol) tool definitions. It handles parameter resolution, schema conversion, security configuration, SSRF-safe `$ref` dereferencing, and format-to-schema enrichment. | ||
|
|
||
| ## Architecture | ||
|
|
||
| ```text | ||
| OpenAPI Spec (JSON/YAML/URL/File) | ||
| | | ||
| v | ||
| OpenAPIToolGenerator (src/generator.ts) | ||
| |-- initialize(): dereference $refs, then validate | ||
| |-- generateTools(): iterate paths/operations | ||
| |-- generateTool(): build a single McpOpenAPITool | ||
| | | ||
| |-- ParameterResolver (src/parameter-resolver.ts) | ||
| | resolves params + requestBody into inputSchema + mapper | ||
| | | ||
| |-- ResponseBuilder (src/response-builder.ts) | ||
| | builds outputSchema from responses | ||
| | | ||
| |-- Format Resolution (src/format-resolver.ts) | ||
| | enriches schemas with format constraints (optional) | ||
| | | ||
| v | ||
| McpOpenAPITool { name, description, inputSchema, outputSchema, mapper, metadata } | ||
| ``` | ||
|
|
||
| ## Key Files | ||
|
|
||
| | File | Purpose | | ||
| |------|---------| | ||
| | `src/generator.ts` | Main entry point. Factory methods (`fromJSON`, `fromYAML`, `fromURL`, `fromFile`), tool generation, SSRF protection, `$ref` dereferencing | | ||
| | `src/types.ts` | All type definitions, `toJsonSchema()` conversion, `isReferenceObject()` guard | | ||
| | `src/parameter-resolver.ts` | Resolves OpenAPI parameters + requestBody into flat inputSchema with conflict resolution | | ||
| | `src/response-builder.ts` | Builds outputSchema from OpenAPI responses with content-type and status code preferences | | ||
| | `src/format-resolver.ts` | Format-to-schema resolution. Built-in resolvers for uuid, date-time, email, int32, etc. | | ||
| | `src/schema-builder.ts` | Static utilities: merge, union, clone, flatten, simplify, withFormat, etc. | | ||
| | `src/security-resolver.ts` | Resolves security schemes (Bearer, Basic, Digest, API Key, OAuth2, OpenID Connect) | | ||
| | `src/validator.ts` | Validates OpenAPI document structure | | ||
| | `src/errors.ts` | Error class hierarchy: LoadError, ParseError, ValidationError, GenerationError, SchemaError | | ||
| | `src/index.ts` | Barrel file for public exports | | ||
|
|
||
| ## Development Commands | ||
|
|
||
| ```bash | ||
| yarn test # Run all tests (unit + integration) | ||
| yarn test:unit # Run unit tests only | ||
| yarn test:integration # Run integration tests only | ||
| yarn test:coverage # Run tests with coverage report | ||
| yarn build # Build CJS + ESM + type declarations | ||
| yarn build:cjs # Build CommonJS output only | ||
| yarn build:esm # Build ESM output only | ||
| yarn build:types # Emit TypeScript declarations only | ||
| yarn clean # Remove dist/ and coverage/ | ||
| ``` | ||
|
|
||
| ## Build System | ||
|
|
||
| - **Bundler**: esbuild (separate CJS and ESM builds) | ||
| - **Type declarations**: tsc with `tsconfig.lib.json` | ||
| - **Packages**: external (not bundled into output) via `--packages=external` | ||
| - **CJS output**: `dist/index.js` | ||
| - **ESM output**: `dist/esm/index.mjs` | ||
| - **Types**: `dist/index.d.ts` | ||
|
|
||
| ## Testing | ||
|
|
||
| - **Framework**: Jest 29 with SWC transformer (`@swc/jest`) | ||
| - **Coverage provider**: V8 (`coverageProvider: 'v8'` in jest.config.js) | ||
| - **Coverage target**: 100% statements, branches, functions, lines | ||
| - **Unit tests**: `src/__tests__/*.spec.ts` (one per module) | ||
| - **Integration tests**: `src/__tests__/integration.spec.ts` (full pipeline, imports from entrypoint only) | ||
| - **Coverage exclusion**: `src/index.ts` (barrel file) | ||
|
|
||
| ### Testing Patterns | ||
|
|
||
| - **Inline specs**: Tests create OpenAPI spec objects directly (no fixture files) | ||
| - **Mock fetch**: URL loading tests mock `global.fetch` with `jest.fn()` | ||
| - **Temp files**: File loading tests create temp files in `os.tmpdir()`, clean up in `finally` | ||
| - **Spy on dereference**: SSRF tests spy on `$RefParser.dereference` to inspect options without making network calls | ||
| - **`c8 ignore next`**: Used for defensive branches unreachable through normal code paths (V8 coverage ignores) | ||
| - **`transformIgnorePatterns`**: `@apidevtools/json-schema-ref-parser` is ESM-only and must be transformed by SWC | ||
|
|
||
| ### ESM Dependency Handling | ||
|
|
||
| `@apidevtools/json-schema-ref-parser` v15 is ESM-only. The project uses dynamic `import()` in `generator.ts` so it works from both CJS and ESM contexts. Jest transforms the package via `transformIgnorePatterns` in `jest.config.js`. | ||
|
|
||
| ## Options Flow | ||
|
|
||
| ```text | ||
| LoadOptions (factory methods) | ||
| -> constructor (normalizes defaults) | ||
| -> initialize() | ||
| -> $RefParser.dereference() [if dereference: true] | ||
| -> Validator.validate() [if validate: true] | ||
|
|
||
| GenerateOptions (generateTools/generateTool) | ||
| -> ParameterResolver(namingStrategy) | ||
| .resolve(operation, pathParams, security, includeSecurityInInput) | ||
| -> ResponseBuilder(preferredStatusCodes, includeAllResponses) | ||
| .build(responses) | ||
| -> resolveSchemaFormats(schema, resolvers) [if resolveFormats/formatResolvers set] | ||
| ``` | ||
|
|
||
| ## Key Conventions | ||
|
|
||
| - `toJsonSchema()` converts OpenAPI SchemaObject to JSON Schema (handles exclusiveMin/Max boolean-to-numeric conversion) | ||
| - Schemas pass through `toJsonSchema()` in both ParameterResolver and ResponseBuilder | ||
| - Metadata is attached via `x-` prefixed properties (`x-parameter-location`, `x-status-code`, `x-content-type`) | ||
| - The `mapper` array maps inputSchema keys to their HTTP locations (path/query/header/body/cookie) | ||
| - Security info lives on mapper entries (not on inputSchema unless `includeSecurityInInput: true`) | ||
| - Format resolution is a post-processing step applied to final inputSchema/outputSchema | ||
|
|
||
| ## Documentation | ||
|
|
||
| - All docs live in `docs/` folder | ||
| - `docs/FORMAT_RESOLUTION.md` — Format resolution feature docs (built-in resolvers, custom resolvers, standalone usage) | ||
|
|
||
| ### README Links for npm | ||
|
|
||
| All links in `README.md` must use **absolute GitHub URLs** (not relative paths) because npm renders README on its own domain and relative links break. Use the format: | ||
|
|
||
| ``` | ||
| https://github.com/agentfront/mcp-from-openapi/blob/main/docs/<file>.md | ||
| ``` | ||
|
|
||
| When adding new docs or links to README, always use absolute URLs pointing to the `main` branch. | ||
frontegg-david marked this conversation as resolved.
Show resolved
Hide resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.