---
title: "Import tools from an MCP server"
method: POST
path: "/groups/{groupId}/artifacts/{artifactId}/mcp-import"
tags: ["Artifacts", "AI"]
---

# Import tools from an MCP server

`POST /groups/{groupId}/artifacts/{artifactId}/mcp-import`

## Request

- The document declares no server URL.
- Auth: none declared

**Experimental.** Connects to a live MCP server over the Streamable HTTP transport, lists its tools with `tools/list`, and publishes each tool as an `MCP_TOOL` artifact. The artifact named in the path must be an `MCP_SERVER`; a new version of it references every imported tool whose definition is stored.

Each tool is published like any other version: configured rules, such as `COMPATIBILITY`, apply, and a tool rejected by a rule is reported as `REJECTED` with the violations, without changing what is stored. A tool whose definition is unchanged is reported as `UNCHANGED`. A tool referenced by the previous `MCP_SERVER` version but no longer listed by the server is reported as `REMOVED`; its artifact is left as it is. With `dryRun`, nothing is written and the same report is returned.

The registry connects only to hosts in `apicurio.mcp-import.allowed-hosts`, never to loopback, link-local or cloud metadata addresses, and does not follow redirects. Headers in the request are sent to the MCP server only; they are not stored, returned or logged.

This operation can fail for the following reasons:

* The import feature is disabled, or the storage is read-only (HTTP error `409`)
* No artifact with this `artifactId` exists (HTTP error `404`)
* The artifact is not an `MCP_SERVER`, or the URL or its host is not allowed (HTTP error `400`)
* The MCP server could not be reached, timed out, sent a response that is too large or invalid, or listed too many tools (HTTP error `502`)
* A server error occurred (HTTP error `500`)

## Request body

- McpToolImportRequest: Where to reach an MCP server, and where to publish its tools.
  - `url` string, required: The MCP server endpoint, for the Streamable HTTP transport. Its host must be allowed by `apicurio.mcp-import.allowed-hosts`.
  - `headers` object: HTTP headers to send to the MCP server, for example `Authorization`. Sent to the MCP server only: never stored, returned or logged.
  - `toolGroupId` string: The group to publish the `MCP_TOOL` artifacts in. Defaults to the group of the `MCP_SERVER` artifact.
  - `dryRun` boolean: When `true`, the server is contacted and the report is returned, but nothing is written.

## Response `200`

The result of the import, for the server and for each tool.

- McpToolImportResult: The result of importing tools from an MCP server.
  - `groupId` string: An ID of a single artifact group.
  - `artifactId` string: The ID of a single artifact.
  - `version` string: The `MCP_SERVER` version that references the imported tools. Absent when nothing was written.
  - `status` 'CREATED' | 'NEW_VERSION' | 'UNCHANGED' | 'REJECTED' | 'REMOVED': The outcome of an MCP import for one artifact. * `CREATED` - a new artifact was created * `NEW_VERSION` - a new version was added to an existing artifact * `UNCHANGED` - the stored version already matches * `REJECTED` - a rule rejected the new definition; nothing was stored * `REMOVED` - the tool was referenced by the previous server version but is no longer listed; its artifact is left as it is
  - `tools` McpToolImportToolResult[]: The outcome for each tool.
    - `name` string: The tool name, as listed by the MCP server.
    - `groupId` string: An ID of a single artifact group.
    - `artifactId` string: The ID of a single artifact.
    - `version` string: The version that matches the tool's definition. Absent when the tool was rejected or removed, or when nothing was written.
    - `status` 'CREATED' | 'NEW_VERSION' | 'UNCHANGED' | 'REJECTED' | 'REMOVED': The outcome of an MCP import for one artifact. * `CREATED` - a new artifact was created * `NEW_VERSION` - a new version was added to an existing artifact * `UNCHANGED` - the stored version already matches * `REJECTED` - a rule rejected the new definition; nothing was stored * `REMOVED` - the tool was referenced by the previous server version but is no longer listed; its artifact is left as it is
    - `causes` RuleViolationCause[]: The rule violations, when the tool was rejected.
      - `description` string
      - `context` string
      - `code` string: The checker's identifier for the kind of difference, for example a JSON Schema difference type or an Avro schema incompatibility type. Meaningful together with the artifact type. Informational: it identifies the explanation to look up, and may change between minor versions. Clients must not build logic on specific values.
      - `direction` 'BACKWARD' | 'FORWARD' | 'BOTH': Which compatibility a difference breaks.
      - `proposed` DifferenceLocation: A location within one of the two documents compared by a rule. Locations are labelled by document - proposed or existing - rather than by the checker's original and updated schemas, so that the direction of the check does not change their meaning. Clients must tolerate a pointer that does not resolve in the content as written, falling back to the deepest part that does.
        - `pointer` string, required: A JSON Pointer, in that document's own keywords. When the two documents use different drafts, each pointer uses its own document's spelling.
        - `reference` string: When set, the location is in a referenced artifact, named as in the version's artifact references, and `pointer` points into that artifact. Absent means the location is in the document itself.
        - `version` string: The existing version the difference was found against, when known - always the latest version for the non-transitive compatibility levels. Not set on a proposed location.
      - `existing` DifferenceLocation: A location within one of the two documents compared by a rule. Locations are labelled by document - proposed or existing - rather than by the checker's original and updated schemas, so that the direction of the check does not change their meaning. Clients must tolerate a pointer that does not resolve in the content as written, falling back to the deepest part that does.
        - `pointer` string, required: A JSON Pointer, in that document's own keywords. When the two documents use different drafts, each pointer uses its own document's spelling.
        - `reference` string: When set, the location is in a referenced artifact, named as in the version's artifact references, and `pointer` points into that artifact. Absent means the location is in the document itself.
        - `version` string: The existing version the difference was found against, when known - always the latest version for the non-transitive compatibility levels. Not set on a proposed location.

## Other responses

- `400`: Common response for all operations that can return a `400` error.
- `401`: Common response for all operations that can return a `401` error indicating authentication is required.
- `403`: Common response for all operations that can return a `403` error indicating the user is authenticated but not authorized.
- `404`: Common response for all operations that can return a `404` error.
- `409`: Common response used when an input conflicts with existing data.
- `500`: Common response for all operations that can fail with an unexpected server error.
- `502`: The MCP server could not be reached, or its response could not be used.

## Changes

- **2026-11-04** `a3998401ffa9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/apicurio/apis/apicurio-registry-api-v3/changes/groups/:groupId/artifacts/:artifactId/mcp-import/post.md)

---

[API](https://skmtc.dev/apicurio/apis/apicurio-registry-api-v3.md) - [All operations](https://skmtc.dev/apicurio/apis/apicurio-registry-api-v3/llms.txt) - [OpenAPI document](https://skmtc.dev/apicurio/apis/apicurio-registry-api-v3/revisions/952cb20d3c0d?raw)
