Skip to content

OpenAPI Import

OpenAPI import onboards a REST service as a set of federated MCP tools without writing a native MCP server. One OpenAPI operation becomes one MCP tool.

View as Markdown Open the plain-text version of this page.

Import a document#

Import takes the spec from a public specUrl (a link) or from specText (the uploaded document contents) — exactly one of the two. It does not accept an inline OpenAPI object.

bash
curl "$PROVON_API_URL/projects/$PROJECT_ID/mcp/openapi/import" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Acme CRM",
    "specText": "{\"openapi\":\"3.0.0\",\"paths\":{\"/contacts/{id}\":{\"get\":{\"operationId\":\"getContact\",\"summary\":\"Get a contact\"}}}}"
  }'

Or point at a public document instead of uploading its text:

bash
curl "$PROVON_API_URL/projects/$PROJECT_ID/mcp/openapi/import" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "displayName": "Acme CRM", "specUrl": "https://api.acme.example/openapi.json" }'

The body is { "displayName"?: string, "specUrl"?: string, "specText"?: string } with exactly one of specUrl or specText. The route creates an openapi-source server and one draft tool per operation, and returns the server record plus a list of tool records. A specUrl document must be reachable over HTTP(S), stays under the 10 MB import cap, and allows at most five redirect hops during download.

Imported operations land as drafts on purpose: they are not discoverable or callable until you explicitly publish them (see Managing imported tools below). A bulk import cannot silently expose every REST operation at once.

Import is normalization only — it does not call the upstream service — so it works on both the self-hosted Node runtime and the hosted edge.

How operations become tools#

For every path and HTTP method (get, put, post, delete, options, head, patch, trace) that defines an operation:

  • Tool name is the normalized operationId, or METHOD /path when there is no operationId. Names are lowercased and reduced to [a-z0-9_-]: other characters become _, repeated separators collapse, surrounding separators trim, and the result caps at 128 characters; an empty result falls back to tool.
  • Title is the operation summary; description is the operation description.
  • Input schema is built from the operation's path and query parameters plus the application/json request-body schema. Required parameters are flagged required.

The stored tool keeps its httpMethod and httpPath template.

How arguments map to a REST call#

When the tool gateway invokes an imported tool:

  1. Path parameters in the template (for example /contacts/{id}) are substituted from the matching argument, URI-encoded.
  2. For GET and HEAD, the remaining arguments become query parameters.
  3. For POST, PUT, PATCH, and other write methods, the remaining arguments become the JSON request body (Content-Type: application/json).

The sealed upstream credential is injected as Authorization: Bearer <secret> server-side. Inbound headers are never forwarded, tool-call redirects are not followed, and private or loopback hosts are blocked — see Security.

Managing imported tools#

  • Re-importing or re-syncing upserts tools by normalized name. Newly discovered operations land as draft; existing tools keep their publish state.
  • Tools no longer present upstream are archived on sync, so the tool gateway stops invoking them.
  • Imported tools start as draft. Publish the operations you want discoverable:
bash
curl -X PATCH "$PROVON_API_URL/projects/$PROJECT_ID/mcp/servers/$SERVER_ID/tools/$TOOL_ID" \
  -H "Authorization: Bearer $PROVON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "publishState": "published" }'

Success checks#

  1. The import response lists one tool per expected operation, each in draft.
  2. tools/list on the federation connection shows nothing until a tool is published and an allow policy covers the caller.
  3. After publishing, tools/list returns the tool with its input schema, and tools/call returns the upstream response; a missing allow policy surfaces as -32001.
  4. Re-running sync after an upstream spec change keeps published tools intact and archives removed operations.