{"_id":"@bahridev/mcpify","_rev":"5-4a2d3519d556c0900c5b007bdf88952c","name":"@bahridev/mcpify","dist-tags":{"latest":"1.3.0"},"versions":{"1.0.0":{"name":"@bahridev/mcpify","version":"1.0.0","keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","_id":"@bahridev/mcpify@1.0.0","maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"homepage":"https://bahri-hirfanoglu.github.io/mcpify","bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"bin":{"mcpify":"dist/cli.js"},"dist":{"shasum":"4a77a07fc7db4638200084a123ac93f568cc4e87","tarball":"https://registry.npmjs.org/@bahridev/mcpify/-/mcpify-1.0.0.tgz","fileCount":35,"integrity":"sha512-RmVqz1NPaeyk0JrnYYVa6xioUNxEwVqJzRkUPU3UzDt4KowVBL81+pkul3jqv8vL5mZvVx3a+/CeGeaurNNUTg==","signatures":[{"sig":"MEQCICQHzEwtg80bvqSx6itpQpDHFsrCwUyxZnik4HAPCaNGAiAu1/53nDaIxOU+5DkrE+6JIB+BgRLzxjRWUY+G5E6Djg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55511},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"176e03d1e6d47dd180a96f07a99bd77a81f58013","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"bahridev","email":"bahrihrf34@gmail.com"},"repository":{"url":"git+https://github.com/bahri-hirfanoglu/mcpify.git","type":"git"},"_npmVersion":"11.8.0","description":"CLI tool that generates an MCP server from OpenAPI specs automatically","directories":{},"_nodeVersion":"24.13.1","dependencies":{"commander":"^14.0.3","minimatch":"^10.2.5","@modelcontextprotocol/sdk":"^1.29.0","@apidevtools/swagger-parser":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typescript":"^6.0.2","@types/node":"^25.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mcpify_1.0.0_1775677429199_0.7188313763611354","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@bahridev/mcpify","version":"1.1.0","keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","_id":"@bahridev/mcpify@1.1.0","maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"homepage":"https://bahri-hirfanoglu.github.io/mcpify","bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"bin":{"mcpify":"dist/cli.js"},"dist":{"shasum":"aba6e91ee9414d02d3a0a57b5ce1ccfd7324c8a0","tarball":"https://registry.npmjs.org/@bahridev/mcpify/-/mcpify-1.1.0.tgz","fileCount":39,"integrity":"sha512-wD4s7t2Rrpp5FJs0ClZTZxVrWLdLBzv2XSazvopBUdKTIlEWYiDxSXRFaaktaJhCfronJBe4JLAg1+TqDUjRLg==","signatures":[{"sig":"MEYCIQCj4hb7zA9q8WVJ0KGQ80pT5yy8ZuwygGHdIVu4CTIOHgIhAN7+QF69tJewnWbUU1ylnbka2dzclPrG3ush6bfCCSQZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88560},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"971f6556145c4752305272c8952f2ea7ef653924","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"bahridev","email":"bahrihrf34@gmail.com"},"repository":{"url":"git+https://github.com/bahri-hirfanoglu/mcpify.git","type":"git"},"_npmVersion":"11.8.0","description":"CLI tool that generates an MCP server from OpenAPI specs automatically","directories":{},"_nodeVersion":"24.13.1","dependencies":{"commander":"^14.0.3","minimatch":"^10.2.5","@modelcontextprotocol/sdk":"^1.29.0","@apidevtools/swagger-parser":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typescript":"^6.0.2","@types/node":"^25.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mcpify_1.1.0_1775679326266_0.19098893694347052","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@bahridev/mcpify","version":"1.1.1","keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","_id":"@bahridev/mcpify@1.1.1","maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"homepage":"https://bahri-hirfanoglu.github.io/mcpify","bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"bin":{"mcpify":"dist/cli.js"},"dist":{"shasum":"b8ead39c1d371a1fe48eeb2a7d98bb7f55953684","tarball":"https://registry.npmjs.org/@bahridev/mcpify/-/mcpify-1.1.1.tgz","fileCount":43,"integrity":"sha512-3OmuXApue3jaT8Y+eFBvnFA8JgW2H3fb+tyLfT4bIz77bclzJ2V+MgTp6cd7WZLUv+ZrCp0e3NElNmsvXoXAyA==","signatures":[{"sig":"MEUCIF/FPn8IfBqZsyPmPo9dCBwpIzMeU8MoG4/+E/8pREiRAiEAlgs8Q/zRg1CvQ/JV51jw+rXluXw+JKEuPl2iZZpjBvQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105509},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18"},"gitHead":"426753b7bf01755d350d058c1534817a94f51c25","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"bahridev","email":"bahrihrf34@gmail.com"},"repository":{"url":"git+https://github.com/bahri-hirfanoglu/mcpify.git","type":"git"},"_npmVersion":"11.8.0","description":"CLI tool that generates an MCP server from OpenAPI specs automatically","directories":{},"_nodeVersion":"24.13.1","dependencies":{"commander":"^14.0.3","minimatch":"^10.2.5","@modelcontextprotocol/sdk":"^1.29.0","@apidevtools/swagger-parser":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typescript":"^6.0.2","@types/node":"^25.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mcpify_1.1.1_1775725780960_0.8553272700165","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@bahridev/mcpify","version":"1.2.0","keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","_id":"@bahridev/mcpify@1.2.0","maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"homepage":"https://bahri-hirfanoglu.github.io/mcpify","bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"bin":{"mcpify":"dist/cli.js"},"dist":{"shasum":"5ea6a8dae63eafc614fae70cb50a33cc41135f34","tarball":"https://registry.npmjs.org/@bahridev/mcpify/-/mcpify-1.2.0.tgz","fileCount":63,"integrity":"sha512-/p8YhDH5Ey1CsqnSH3Vq6Cd8iH8EhdK18oCbBjMpLEhTKZYyW5sCWf7Iy69BL3snkZ+BhKrvKOgj9EjVsRLV9g==","signatures":[{"sig":"MEUCIQDK2nO8+UlD9anx/LxtMdsPR/V1X5eXPmU17WgUm267fAIgaBlNED3bHvRmhfDYm65eCTgc3vLSZT7CvTfqN0zBfOM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197885},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"5c1340e48edae1c41678ad6c93818027f3d2c585","scripts":{"dev":"tsx src/cli.ts","test":"vitest run","build":"tsc","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"bahridev","email":"bahrihrf34@gmail.com"},"repository":{"url":"git+https://github.com/bahri-hirfanoglu/mcpify.git","type":"git"},"_npmVersion":"11.8.0","description":"CLI tool that generates an MCP server from OpenAPI specs automatically","directories":{},"_nodeVersion":"24.13.1","dependencies":{"commander":"^14.0.3","minimatch":"^10.2.5","@modelcontextprotocol/sdk":"^1.29.0","@apidevtools/swagger-parser":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","vitest":"^4.1.3","typescript":"^6.0.2","@types/node":"^25.5.2"},"_npmOperationalInternal":{"tmp":"tmp/mcpify_1.2.0_1775847522410_0.10653099455603732","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@bahridev/mcpify","version":"1.3.0","description":"CLI tool that generates an MCP server from OpenAPI specs automatically","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","bin":{"mcpify":"dist/cli.js"},"scripts":{"build":"tsc","dev":"tsx src/cli.ts","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/bahri-hirfanoglu/mcpify.git"},"homepage":"https://bahri-hirfanoglu.github.io/mcpify","bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"engines":{"node":">=20"},"dependencies":{"@apidevtools/swagger-parser":"^12.1.0","@modelcontextprotocol/sdk":"^1.29.0","commander":"^14.0.3","minimatch":"^10.2.5"},"devDependencies":{"@types/node":"^25.5.2","tsx":"^4.21.0","typescript":"^6.0.2","vitest":"^4.1.3"},"gitHead":"215902bbd536cb6f712dc17e7ca069cb601ceb7e","_id":"@bahridev/mcpify@1.3.0","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-xf/3EychvgIu/59FqpqJgiW5AXNcwmswwgUTYtM3BSA2hCs14gq93PQHT2mEoS7X3V6CNEXdZMczM8m/x8gnPw==","shasum":"5e66e54ae317405636a85f3beda13920ad7b8cf6","tarball":"https://registry.npmjs.org/@bahridev/mcpify/-/mcpify-1.3.0.tgz","fileCount":87,"unpackedSize":276695,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICL/84rhKDKMcL+KCCWZQOUy0TWCtlW5UUunvEZprKGcAiEAqC9KUqfTibzKJwA5pHWeRRNWkBwSl0KvkMRgrQKQUQM="}]},"_npmUser":{"name":"bahridev","email":"bahrihrf34@gmail.com"},"directories":{},"maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcpify_1.3.0_1776199274814_0.15696070414193564"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-08T19:43:49.095Z","modified":"2026-04-14T20:41:15.073Z","1.0.0":"2026-04-08T19:43:49.351Z","1.1.0":"2026-04-08T20:15:26.406Z","1.1.1":"2026-04-09T09:09:41.102Z","1.2.0":"2026-04-10T18:58:42.578Z","1.3.0":"2026-04-14T20:41:14.952Z"},"bugs":{"url":"https://github.com/bahri-hirfanoglu/mcpify/issues"},"author":{"name":"Bahri Hirfanoglu"},"license":"MIT","homepage":"https://bahri-hirfanoglu.github.io/mcpify","keywords":["mcp","openapi","swagger","cli","model-context-protocol","ai","api","rest","tool","server","claude","llm"],"repository":{"type":"git","url":"git+https://github.com/bahri-hirfanoglu/mcpify.git"},"description":"CLI tool that generates an MCP server from OpenAPI specs automatically","maintainers":[{"name":"bahridev","email":"bahrihrf34@gmail.com"}],"readme":"<p align=\"center\">\r\n  <img src=\"docs/logo.png\" width=\"120\" alt=\"mcpify logo\">\r\n</p>\r\n\r\n<h1 align=\"center\">mcpify</h1>\r\n\r\n<p align=\"center\">\r\n  <strong>OpenAPI to MCP in seconds</strong>\r\n</p>\r\n\r\n<p align=\"center\">\r\n  <a href=\"https://www.npmjs.com/package/@bahridev/mcpify\"><img src=\"https://img.shields.io/npm/v/@bahridev/mcpify?style=flat-square&color=6366f1\" alt=\"npm version\"></a>\r\n  <a href=\"https://github.com/bahri-hirfanoglu/mcpify/blob/master/LICENSE\"><img src=\"https://img.shields.io/npm/l/@bahridev/mcpify?style=flat-square&color=8b5cf6\" alt=\"license\"></a>\r\n  <a href=\"https://www.npmjs.com/package/@bahridev/mcpify\"><img src=\"https://img.shields.io/npm/dm/@bahridev/mcpify?style=flat-square&color=a78bfa\" alt=\"downloads\"></a>\r\n  <a href=\"https://github.com/bahri-hirfanoglu/mcpify\"><img src=\"https://img.shields.io/github/stars/bahri-hirfanoglu/mcpify?style=flat-square&color=c4b5fd\" alt=\"stars\"></a>\r\n</p>\r\n\r\n<p align=\"center\">\r\n  Generate an MCP server from any OpenAPI specification.<br>\r\n  Let AI assistants interact with your REST APIs instantly.\r\n</p>\r\n\r\n---\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install -g @bahridev/mcpify\r\n```\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# Start an MCP server from a local spec\r\nmcpify ./openapi.yaml\r\n\r\n# From a URL\r\nmcpify https://petstore3.swagger.io/api/v3/openapi.json\r\n\r\n# With authentication\r\nmcpify ./api.yaml --bearer-token $API_TOKEN\r\n\r\n# HTTP transport (remote access)\r\nmcpify ./api.yaml --transport http --port 3100\r\n\r\n# Preview tools without starting server\r\nmcpify ./api.yaml --dry-run\r\n\r\n# Watch for spec changes\r\nmcpify ./api.yaml --watch\r\n\r\n# Interactive config setup\r\nmcpify init\r\n\r\n# Validate a spec for MCP compatibility\r\nmcpify validate ./api.yaml\r\n\r\n# Inspect a single tool\r\nmcpify inspect ./api.yaml listPets\r\n\r\n# Add to Claude Desktop config automatically\r\nmcpify install ./api.yaml --name my-api --bearer-token $API_TOKEN\r\n\r\n# Retry on 429/5xx, cache GETs, auto-paginate, pluck fields\r\nmcpify ./api.yaml --retry 3 --cache-ttl 60 --auto-paginate \\\r\n  --response-fields \"data[].id,data[].name\"\r\n\r\n# Compare two specs for breaking changes\r\nmcpify diff ./old.yaml ./new.yaml --fail-on-breaking\r\n\r\n# Smoke-test safe operations against a live API\r\nmcpify test ./api.yaml --bearer-token $TOKEN\r\n```\r\n\r\n## Usage\r\n\r\n```\r\nmcpify <spec> [options]\r\n\r\nArguments:\r\n  spec                     OpenAPI spec file path or URL\r\n\r\nOptions:\r\n  --spec <source>              Spec source (alternative to positional arg)\r\n  --transport <type>           stdio (default) | http\r\n  --port <number>              HTTP port (default: 3100)\r\n  --base-url <url>             API base URL override\r\n  --bearer-token <token>       Bearer token\r\n  --api-key-header <name>      API key header name\r\n  --api-key-value <value>      API key value\r\n  --oauth-flow <flow>          OAuth2 flow (client_credentials | refresh_token)\r\n  --oauth-token-url <url>      OAuth2 token endpoint\r\n  --oauth-client-id <id>       OAuth2 client ID\r\n  --oauth-client-secret <s>    OAuth2 client secret\r\n  --oauth-refresh-token <t>    OAuth2 refresh token\r\n  --oauth-scopes <scopes>      OAuth2 scopes (comma-separated)\r\n  --include <patterns>         Include operations (glob, comma-separated)\r\n  --exclude <patterns>         Exclude operations (glob, comma-separated)\r\n  --tags <tags>                Only include these tags (comma-separated)\r\n  --naming <style>             Tool naming: camelCase | snake_case | original\r\n  --prefix <prefix>            Prefix for all tool names\r\n  --header <key:value>         Custom headers (repeatable)\r\n  --max-response-size <kb>     Max response size in KB (default: 50)\r\n  --retry <count>              Retry attempts on 429/5xx (default: 0)\r\n  --retry-delay <ms>           Base delay for retry backoff (default: 500)\r\n  --retry-max-delay <ms>       Max delay for retry backoff (default: 10000)\r\n  --cache-ttl <seconds>        Cache TTL for GET responses (default: 0)\r\n  --cache-max <count>          Max cached entries (default: 100)\r\n  --auto-paginate              Follow pagination links and merge pages\r\n  --max-pages <count>          Max pages when paginating (default: 10)\r\n  --response-fields <paths>    Dotted paths to select (e.g. \"data[].id\")\r\n  --dry-run                    List tools without starting server\r\n  --watch                      Watch spec file and reload on changes\r\n  --verbose                    Verbose HTTP logging to stderr\r\n  -V, --version                Output version\r\n  -h, --help                   Show help\r\n\r\nCommands:\r\n  init                         Interactively create a .mcpifyrc.json\r\n  validate <spec>              Report MCP compatibility of a spec\r\n  inspect <spec> <tool>        Show full schema and example call for a tool\r\n  install <spec>               Add entry to claude_desktop_config.json\r\n  diff <left> <right>          Compare two specs, report changes\r\n  test <spec>                  Smoke-test safe operations against a live API\r\n```\r\n\r\n## Retry, Cache, Pagination, Field Selection\r\n\r\nFor resilient and token-efficient runtime behavior:\r\n\r\n```bash\r\n# Retry on 429/5xx with exponential backoff, honoring Retry-After\r\nmcpify ./api.yaml --retry 3 --retry-delay 500 --retry-max-delay 10000\r\n\r\n# Cache GET responses for 60 seconds (per-auth keyed)\r\nmcpify ./api.yaml --cache-ttl 60 --cache-max 200\r\n\r\n# Follow Link/next/cursor pagination and merge pages into one response\r\nmcpify ./api.yaml --auto-paginate --max-pages 20\r\n\r\n# Pluck only the fields the LLM needs from large responses\r\nmcpify ./api.yaml --response-fields \"data[].id,data[].name\"\r\n```\r\n\r\nAll four can be combined and are also configurable via `.mcpifyrc.json`\r\n(`retry`, `retryDelay`, `retryMaxDelay`, `cacheTtl`, `cacheMax`,\r\n`autoPaginate`, `maxPages`, `responseFields`).\r\n\r\n## `mcpify diff`\r\n\r\nCompare two spec versions and report added, removed, and changed\r\noperations:\r\n\r\n```bash\r\n$ mcpify diff ./v1.yaml ./v2.yaml\r\n\r\nMinimal API v0.1.0  →  Minimal API v0.2.0\r\n\r\nAdded:     1\r\nRemoved:   1\r\nChanged:   1\r\nUnchanged: 1\r\n\r\nAdded operations:\r\n  + getStatus  GET /status\r\n\r\nRemoved operations:\r\n  - legacy  GET /legacy\r\n\r\nChanged operations:\r\n  ~ getItem  GET /items/{id}\r\n      + param query:verbose\r\n```\r\n\r\nUse `--fail-on-breaking` in CI to guard against removed operations,\r\nnewly-required parameters, or method/path changes.\r\n\r\n## `mcpify test`\r\n\r\nSmoke-test safe `GET` / `HEAD` operations against a live API:\r\n\r\n```bash\r\n$ mcpify test ./api.yaml --bearer-token $TOKEN\r\n\r\nBase URL: https://api.example.com\r\nOperations: 5  (ok: 3, fail: 0, skipped: 2)\r\n\r\n  ✓ healthCheck  GET /health 200 45ms\r\n  ✓ listPets     GET /pets   200 112ms\r\n  ∘ getPet       GET /pets/{petId} (requires parameters)\r\n```\r\n\r\nExits 1 when any probe fails. Operations requiring path/query/header\r\nparameters or using unsafe methods are skipped automatically.\r\n\r\n## Supported Specs\r\n\r\n- **OpenAPI 3.0.x** and **3.1.x**\r\n- **Swagger 2.0**\r\n- YAML and JSON formats\r\n- Local files and remote URLs\r\n\r\nVersion is auto-detected — just point mcpify at any spec.\r\n\r\n## Claude Desktop Configuration\r\n\r\nThe fastest way: let mcpify edit the config for you.\r\n\r\n```bash\r\nmcpify install ./path/to/openapi.yaml --name my-api --bearer-token $API_TOKEN\r\n```\r\n\r\nThis writes (or updates) an `mcpServers.my-api` entry in the\r\nplatform-specific config file:\r\n\r\n| Platform | Path |\r\n|----------|------|\r\n| Windows  | `%APPDATA%\\Claude\\claude_desktop_config.json` |\r\n| macOS    | `~/Library/Application Support/Claude/claude_desktop_config.json` |\r\n| Linux    | `$XDG_CONFIG_HOME/Claude/claude_desktop_config.json` or `~/.config/Claude/claude_desktop_config.json` |\r\n\r\nBearer tokens are written to `entry.env` (not to the CLI args) so they\r\ndon't show up in process listings. Pass `--force` to overwrite an\r\nexisting entry, `--config <path>` to target a different file, and\r\n`--transport http --port 3100` to wire up the HTTP transport.\r\n\r\nOr edit the file manually:\r\n\r\n```json\r\n{\r\n  \"mcpServers\": {\r\n    \"my-api\": {\r\n      \"command\": \"mcpify\",\r\n      \"args\": [\"./path/to/openapi.yaml\"],\r\n      \"env\": {\r\n        \"MCPIFY_BEARER_TOKEN\": \"your-token\"\r\n      }\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n## HTTP Transport\r\n\r\nRun as a remote MCP server accessible over HTTP:\r\n\r\n```bash\r\nmcpify ./api.yaml --transport http --port 3100\r\n```\r\n\r\nThis exposes:\r\n- `POST /mcp` — MCP JSON-RPC endpoint (Streamable HTTP)\r\n- `GET /mcp` — SSE stream for server-initiated messages\r\n- `DELETE /mcp` — End an MCP session\r\n- `GET /health` — Health check endpoint\r\n\r\nEach client gets an isolated session with its own MCP server instance. Sessions are tracked via the `mcp-session-id` header.\r\n\r\n## OAuth2\r\n\r\nmcpify supports OAuth2 **client credentials** and **refresh token**\r\nflows. When either the `oauth2` security scheme in your spec exposes a\r\n`clientCredentials.tokenUrl` / `authorizationCode.refreshUrl` and the\r\ncorresponding credentials are present in the environment, mcpify will\r\nautomatically fetch tokens and refresh them before expiry.\r\n\r\n### Client credentials (machine-to-machine)\r\n\r\n```bash\r\nmcpify ./api.yaml \\\r\n  --oauth-flow client_credentials \\\r\n  --oauth-token-url https://auth.example.com/token \\\r\n  --oauth-client-id $CLIENT_ID \\\r\n  --oauth-client-secret $CLIENT_SECRET \\\r\n  --oauth-scopes \"read,write\"\r\n```\r\n\r\nOr equivalently, let mcpify discover `tokenUrl` from the spec and only\r\nsupply the credentials via env vars:\r\n\r\n```bash\r\nexport MCPIFY_OAUTH_CLIENT_ID=...\r\nexport MCPIFY_OAUTH_CLIENT_SECRET=...\r\nmcpify ./api.yaml\r\n```\r\n\r\n### Refresh token\r\n\r\n```bash\r\nmcpify ./api.yaml \\\r\n  --oauth-flow refresh_token \\\r\n  --oauth-token-url https://auth.example.com/token \\\r\n  --oauth-client-id $CLIENT_ID \\\r\n  --oauth-refresh-token $REFRESH_TOKEN\r\n```\r\n\r\nThe refresh token is rotated automatically when the server returns a\r\nnew one in the token response.\r\n\r\n### `.mcpifyrc.json`\r\n\r\n```json\r\n{\r\n  \"spec\": \"./api.yaml\",\r\n  \"oauth\": {\r\n    \"flow\": \"client_credentials\",\r\n    \"tokenUrl\": \"https://auth.example.com/token\",\r\n    \"clientId\": \"my-client\",\r\n    \"clientSecret\": \"shhh\",\r\n    \"scopes\": [\"read\", \"write\"]\r\n  }\r\n}\r\n```\r\n\r\n### Authorization code / OpenID Connect\r\n\r\nFull interactive browser-based authorization is out of scope for now.\r\nUse your IdP's tooling (or a one-time `curl` exchange) to obtain a\r\nrefresh token, then pass it with `--oauth-refresh-token`. If your spec\r\nuses an `openIdConnect` scheme, provide `--oauth-token-url` explicitly\r\nbecause mcpify does not auto-discover OIDC configuration.\r\n\r\n## `mcpify init`\r\n\r\nGenerates a `.mcpifyrc.json` interactively:\r\n\r\n```bash\r\n$ mcpify init\r\nOpenAPI spec source (file path or URL): ./openapi.yaml\r\nTransport (stdio | http) (stdio): http\r\nHTTP port (3100):\r\nOverride base URL (empty to skip):\r\nAuth type (none | bearer | api-key | oauth2) (none): oauth2\r\nOAuth2 flow (client_credentials | refresh_token) (client_credentials):\r\n...\r\n✓ Wrote /path/to/.mcpifyrc.json\r\n```\r\n\r\nPass `--force` to overwrite an existing config without confirmation.\r\n\r\n## `mcpify validate`\r\n\r\nReports which parts of a spec mcpify can handle, with issues grouped\r\nby severity:\r\n\r\n```bash\r\n$ mcpify validate ./api.yaml\r\n\r\nOAuth API v1.0.0\r\nBase URL: https://api.example.com\r\n\r\nOperations: 12\r\nTools:      12\r\n\r\nSecurity schemes:\r\n  ✓ oauth (oauth2 (clientCredentials))\r\n  ⚠ oidc (openIdConnect)\r\n\r\nIssues:\r\n  ⚠ security scheme \"oidc\" is OpenID Connect — mcpify does not\r\n    auto-discover the tokenUrl. Provide --oauth-token-url manually\r\n\r\n⚠ PASS with warnings — 1 warning(s)\r\n```\r\n\r\nExits with code 1 when errors are present. Use this in CI to guard\r\nagainst spec regressions.\r\n\r\n## `mcpify inspect`\r\n\r\nShows the full tool metadata, a placeholder example argument object,\r\nand an equivalent cURL invocation:\r\n\r\n```bash\r\n$ mcpify inspect ./api.yaml getPet\r\n\r\ngetPet\r\n──────\r\nGET /pets/{petId}\r\nBase URL: https://petstore.example.com/v1\r\nTags: pets\r\nHints: read-only\r\n\r\nDescription:\r\n  Get a pet by ID\r\n\r\n  Returns: {id, name, tag}\r\n\r\nInput schema:\r\n  { ... }\r\n\r\nExample arguments:\r\n  { \"petId\": \"<string>\" }\r\n\r\ncURL:\r\n  curl -X GET 'https://petstore.example.com/v1/pets/%3Cstring%3E' \\\r\n    -H 'Accept: application/json'\r\n```\r\n\r\nRespects `--naming`, `--prefix`, `--include`, `--exclude`, `--tags`,\r\nand `--base-url`, so tool name resolution matches the configuration\r\nyou use at runtime.\r\n\r\n## Docker\r\n\r\n```bash\r\n# Build\r\ndocker build -t mcpify .\r\n\r\n# Run over HTTP\r\ndocker run --rm -p 3100:3100 \\\r\n  -v \"$PWD/openapi.yaml:/spec/openapi.yaml:ro\" \\\r\n  mcpify /spec/openapi.yaml --transport http --port 3100\r\n```\r\n\r\nPublished images are available at `ghcr.io/bahri-hirfanoglu/mcpify:<version>`.\r\n\r\n## GitHub Action\r\n\r\nUse the composite action to validate specs or spin up an MCP server in\r\na workflow:\r\n\r\n```yaml\r\n- uses: bahri-hirfanoglu/mcpify@v1\r\n  with:\r\n    spec: ./openapi.yaml\r\n    command: validate\r\n```\r\n\r\nSupported commands: `validate`, `dry-run`, `inspect`, `serve`. Pass\r\nadditional flags via `extra-args`.\r\n\r\n## Config File\r\n\r\nCreate a `.mcpifyrc.json` in your project root to avoid repeating CLI flags:\r\n\r\n```json\r\n{\r\n  \"spec\": \"./openapi.yaml\",\r\n  \"transport\": \"stdio\",\r\n  \"bearerToken\": \"sk-...\",\r\n  \"include\": [\"get*\", \"list*\"],\r\n  \"exclude\": [\"delete*\"],\r\n  \"naming\": \"snake_case\",\r\n  \"prefix\": \"myapi_\",\r\n  \"headers\": {\r\n    \"X-Custom-Header\": \"value\",\r\n    \"X-Api-Version\": \"2024-01\"\r\n  },\r\n  \"verbose\": true\r\n}\r\n```\r\n\r\nSupported file names: `.mcpifyrc.json`, `.mcpifyrc`, `mcpify.config.json`\r\n\r\nCLI flags always override config file values.\r\n\r\n## Custom Tool Naming\r\n\r\n```bash\r\n# Convert operationIds to snake_case\r\nmcpify api.yaml --naming snake_case\r\n\r\n# Add a prefix to all tool names\r\nmcpify api.yaml --prefix myapi_\r\n\r\n# Combine both\r\nmcpify api.yaml --naming snake_case --prefix myapi_\r\n# listAllPets → myapi_list_all_pets\r\n```\r\n\r\n## Custom Headers\r\n\r\nSend custom HTTP headers with every API request:\r\n\r\n```bash\r\n# Single header\r\nmcpify api.yaml --header \"Authorization: Bearer sk-...\"\r\n\r\n# Multiple headers\r\nmcpify api.yaml --header \"Authorization: Bearer sk-...\" --header \"X-Api-Version: 2024-01\"\r\n```\r\n\r\nAlso configurable via `.mcpifyrc.json` (`headers` field).\r\n\r\n## Filtering Operations\r\n\r\n```bash\r\n# Only include specific operations\r\nmcpify api.yaml --include \"get*,list*\"\r\n\r\n# Exclude destructive operations\r\nmcpify api.yaml --exclude \"delete*,remove*\"\r\n\r\n# Filter by tags\r\nmcpify api.yaml --tags \"users,pets\"\r\n```\r\n\r\n## Response Schema Hints\r\n\r\nTool descriptions automatically include response structure information extracted from the spec:\r\n\r\n```\r\nlistPets — List all pets\r\n\r\nReturns: array of {id, name, tag}\r\n```\r\n\r\nThis helps AI assistants understand what the API returns before calling a tool.\r\n\r\n## Key Sanitization\r\n\r\nmcpify automatically sanitizes JSON Schema property keys that contain special characters (dots, brackets, hyphens, etc.) to ensure compatibility with all MCP clients. Original keys are restored when making API requests, so the target API always receives the correct parameter names.\r\n\r\n```\r\nX-Request-ID  →  x_request_id  (in tool schema)\r\nfilter[name]  →  filter_name_  (in tool schema)\r\n```\r\n\r\nThis is fully transparent — no configuration needed.\r\n\r\n## Verbose Logging\r\n\r\n```bash\r\nmcpify api.yaml --verbose\r\n```\r\n\r\nLogs HTTP requests and responses to stderr:\r\n\r\n```\r\n→ GET https://api.example.com/pets?limit=10\r\n← ✓ 200 45ms 1.2KB\r\n→ POST https://api.example.com/pets\r\n← ✗ 401 12ms 156B\r\n```\r\n\r\n## Environment Variables\r\n\r\n| Variable | Description |\r\n|----------|-------------|\r\n| `MCPIFY_BEARER_TOKEN` | Bearer token for authentication |\r\n| `MCPIFY_API_KEY_HEADER` | API key header name |\r\n| `MCPIFY_API_KEY_VALUE` | API key value |\r\n| `MCPIFY_OAUTH_CLIENT_ID` | OAuth2 client ID |\r\n| `MCPIFY_OAUTH_CLIENT_SECRET` | OAuth2 client secret |\r\n| `MCPIFY_OAUTH_REFRESH_TOKEN` | OAuth2 refresh token |\r\n\r\n## Programmatic API\r\n\r\n```typescript\r\nimport { parseSpec, generateTools, startServer } from '@bahridev/mcpify';\r\n\r\nconst spec = await parseSpec('./openapi.yaml');\r\nconst tools = generateTools(spec.operations);\r\n\r\nawait startServer({\r\n  spec,\r\n  tools,\r\n  operations: spec.operations,\r\n  baseUrl: spec.defaultServerUrl,\r\n  auth: { type: 'none' },\r\n  transport: 'stdio',\r\n  port: 3100,\r\n  maxResponseSize: 50 * 1024,\r\n});\r\n```\r\n\r\n## How It Works\r\n\r\n1. Parses and dereferences the OpenAPI/Swagger spec\r\n2. Converts each operation to an MCP tool with JSON Schema input\r\n3. Adds response schema hints to tool descriptions\r\n4. Starts an MCP server (stdio or HTTP transport)\r\n5. When a tool is called, builds and executes the corresponding HTTP request\r\n6. Returns the API response as MCP tool output\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}