Convert Command

The core pipeline: OpenAPI spec in, MCP server out. Every option, every flag, every output mode.

Basic Usage

npx @migrateforce/cli convert \
  --spec <path-to-openapi-spec> \
  [--base-url <target-api-base-url>] \
  [--output <directory>] \
  [--cloud] \
  [--save-project] \
  [--dry-run] \
  [--json] \
  [--include <pattern>] \
  [--exclude <pattern>] \
  [--force]

Options

FlagRequiredDescription
--spec <path>YesPath to OpenAPI spec file (JSON or YAML). Supports OpenAPI 3.0 and Swagger 2.0. Multi-file specs with $ref pointers to external files are resolved automatically — just point to the root document.
--base-url <url>ConditionalBase URL of the REST API the MCP server will proxy to. If omitted, the CLI derives the URL from the servers[] array in your OpenAPI spec. Required when the spec has no servers field or you want to override it.
--output <dir>NoOutput directory. Defaults to ./mcp-server. Must be empty unless --force is set.
--cloudNoSend spec to MigrateForce API for enrichments (readiness score, advice, skill matching). Requires API key. See Local vs Cloud.
--dry-runNoPrint the endpoint → tool mapping table without writing any files.
--jsonNoOutput the full GeneratedMcpServer object as JSON to stdout. No files written. Good for piping.
--include <pattern>NoOnly include endpoints matching pattern. Format: "METHOD /path*". Can be repeated.
--exclude <pattern>NoExclude endpoints matching pattern. Applied after --include.
--forceNoOverwrite output directory if it already contains files.
--save-projectNoSave the conversion as a project in the web dashboard for later editing. Requires --cloud (ignored without it). The project appears in your dashboard under the spec title.

What Happens Under the Hood

01

Parse

Read the spec file, resolve any external $ref pointers, detect version (OpenAPI 3.0 or Swagger 2.0), validate structure. If --base-url is omitted, the first entry in servers[] is used. Fails fast if the spec is malformed or no base URL can be determined.

02

Extract

Pull every endpoint with its method, path, parameters, request body, and response schemas.

03

Filter

Apply --include and --exclude patterns. If neither is set, all endpoints are included.

04

Map

Generate MCP tool names for each endpoint. Names are lowercase, snake_case, verb-first (get_user_profile, create_order). Uses operationId when available, falls back to path analysis.

05

Generate

Build the MCP server code from mappings. Produces 6 files: main.py, Dockerfile, requirements.txt, README.md, .env.example, mcp-manifest.json.

06

Enrich (--cloud only)

Send spec to MigrateForce API. Receive readiness score, improvement advice, and skill catalog matches. Print alongside file output.

Multi-file specs and base URL derivation
The CLI resolves external $ref pointers automatically — just point --spec at the root document and sibling files are pulled in. If your spec includes a servers[] array, the CLI uses the first entry as the base URL, so --base-url becomes optional.

Endpoint Filtering

Use --include and --exclude to control which endpoints become MCP tools. Patterns match against METHOD /path with simple wildcard (*) support.

# Only GET endpoints
npx @migrateforce/cli convert --spec api.yaml --base-url https://api.example.com \
  --include "GET *"

# Everything except admin endpoints
npx @migrateforce/cli convert --spec api.yaml --base-url https://api.example.com \
  --exclude "* /admin/*"

# Only user-related endpoints, excluding DELETE
npx @migrateforce/cli convert --spec api.yaml --base-url https://api.example.com \
  --include "* /users*" \
  --exclude "DELETE *"

Include runs first (whitelist), then exclude runs on the result (blacklist). If no --include is set, all endpoints start as included.

Dry Run

Preview the mapping without writing any files:

npx @migrateforce/cli convert --spec api.yaml --base-url https://api.example.com --dry-run

Output:

Method  Path                    MCP Tool Name
──────  ──────────────────────  ─────────────────────
GET     /users                  list_users
GET     /users/{id}             get_user
POST    /users                  create_user
PUT     /users/{id}             update_user
DELETE  /users/{id}             delete_user
GET     /orders                 list_orders
POST    /orders                 create_order

7 endpoints → 7 MCP tools (dry run — no files written)

JSON Output

For CI pipelines or custom tooling, get the full generated server as JSON:

npx @migrateforce/cli convert --spec api.yaml --base-url https://api.example.com --json | jq '.toolCount'

The JSON includes the complete GeneratedMcpServer object: all file contents, tool mappings, and metadata. When combined with --cloud, it also includes enrichments.

Tool Naming Rules

Every tool name follows these conventions:

Lowercase, snake_case: get_user_profile
Verb-first: create_order, delete_invoice, list_products
Derived from operationId when available, path otherwise
No REST verbs in names: GET_users
No generic names: process_data, handle_request
No version numbers: get_user_v2

CRUD Mapping Reference

RESTMCP Tool
GET /userslist_users
GET /users/{id}get_user
POST /userscreate_user
PUT /users/{id}update_user
DELETE /users/{id}delete_user
GET /users/{id}/orderslist_user_orders
POST /search/productssearch_products

Generated Files

my-mcp-server/
├── main.py              # MCP server entry point (FastAPI)
├── Dockerfile           # Production-ready container
├── requirements.txt     # Python dependencies
├── README.md            # Setup, usage, and tool reference
├── .env.example         # API_KEY, BASE_URL placeholders
└── mcp-manifest.json    # MCP tool definitions

The main.py file is the only one you need to run. It starts a FastAPI server that exposes each mapped endpoint as an MCP tool. The mcp-manifest.json file is what MCP clients (Claude Desktop, Cursor, etc.) read to discover available tools.

Deployment

Local

cd my-mcp-server
cp .env.example .env     # set your API credentials
pip install -r requirements.txt
python main.py           # starts on localhost:8000

Docker

cd my-mcp-server
docker build -t my-mcp-server .
docker run -d -p 8000:8000 --env-file .env my-mcp-server

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "my-api": {
      "command": "python",
      "args": ["main.py"],
      "cwd": "/absolute/path/to/my-mcp-server"
    }
  }
}

CI Pipeline Integration

Use --json in CI to validate conversions without writing files:

# GitHub Actions example
- name: Validate MCP conversion
  run: |
    npx @migrateforce/cli convert \
      --spec openapi.yaml \
      --base-url ${{ vars.API_BASE_URL }} \
      --json > mcp-output.json

    # Check tool count
    TOOLS=$(jq '.toolCount' mcp-output.json)
    echo "Generated $TOOLS MCP tools"

    # Fail if no tools generated
    if [ "$TOOLS" -eq 0 ]; then
      echo "::error::No MCP tools generated"
      exit 1
    fi

Lint Command

Check your spec for MCP readiness without converting:

npx @migrateforce/cli lint openapi.yaml

Returns grouped issues (errors, warnings, info) and exits with 0 for warnings-only or 2 for errors. Useful as a pre-commit hook or CI gate.

Dashboard Alternative

Prefer a visual editor?
Everything the CLI does is also available in the web dashboard. Upload your spec, edit tool names and descriptions in a table, toggle endpoints on/off, then download the generated server. The dashboard also supports running the AI Migration Agent for automated spec analysis.

Next: Local vs Cloud — understand what the --cloud flag adds and when to use it.