> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get an MCP Server

> Read one MCP server, without its upstream credential.

Returns one MCP server owned by your tenant. The stored upstream credential is
never included in the response — only the auth *mode*.

Returns `404 not_found` if the server belongs to another tenant, so a probe
cannot distinguish "not yours" from "does not exist".

Requires the `read` capability on `ai_gateway`. See the [control-plane overview](/api-reference/ai-gateway/control-plane-overview#authentication) for authentication, the `{data, meta}` envelope, pagination and error types.


## OpenAPI

````yaml GET /ai-gateway/mcp-servers/{id}
openapi: 3.1.0
info:
  title: KnoxCall Client Management API
  version: '1.0'
  description: >
    The KnoxCall Client Management API provides programmatic access to manage
    your API gateway

    resources including routes, secrets, clients, environments, webhooks, and
    API keys.


    ## Authentication


    All requests must include an OAuth 2.1 access token **or** a legacy API key.
    The

    recommended path for new integrations is the first-party SDKs, which mint,
    cache, and

    refresh OAuth tokens for you (start with `knoxcall login` on a developer
    machine, or

    `KNOXCALL_CLIENT_ID` / `KNOXCALL_CLIENT_SECRET` in CI). You can authenticate
    using any of:


    - **Authorization header (OAuth 2.1 bearer token — recommended)**:
    `Authorization: Bearer <access_token>`

    - **Authorization header (legacy API key)**: `Authorization: Bearer
    tk_xxx_yyy`

    - **x-api-key header (legacy API key)**: `x-api-key: tk_xxx_yyy`


    OAuth 2.1 access tokens (`kc_` prefix) are minted at the root-host token
    endpoint

    `https://api.knoxcall.com/oauth/token` (not under `/v1`) using the
    `client_credentials`

    or `authorization_code` grant. See the `OAuth2` security scheme and the
    `/oauth/*`

    endpoints. Some resources that are managed exclusively through OAuth reject
    API-key auth

    with a `403 use_oauth` error.


    Long-lived API keys remain fully supported. They come in three types:

    - **Standard keys** (`tk_` prefix) are used on the production API
    (`api.knoxcall.com`).

    - **Test keys** (`tk_` prefix, type=test) are used on the sandbox API
    (`sandbox.knoxcall.com`).

    - **Enterprise Access Keys** (`AKE` prefix) follow the format
    `AKE[16chars]:[40chars]`.


    Using a test key on the production API (or vice versa) will return a `403
    wrong_key_type` error.


    ## Request IDs


    Every response — success or error — includes an `X-Request-Id` response
    header (a UUID).

    Its value is identical to the `request_id` field in the response body
    (`meta.request_id`

    on success, `error.request_id` on error). Quote it when contacting support.


    ## API Versioning


    The API is versioned on two axes:


    - **Major version — the `/v1` path prefix.** Breaking changes ship under a
    new major
      (`/v2`). `/v1` never receives a breaking change.
    - **Minor version — the `KnoxCall-Version` header (dated, `YYYY-MM-DD`).**
    Send
      `KnoxCall-Version: 2026-08-05` to pin the behaviour of a specific dated release. Omit
      the header to get the newest minor version. Every response echoes the resolved version
      back in a `KnoxCall-Version` response header.

    Within a major version, **additive changes are not breaking** and may appear
    without a new

    dated version: new endpoints, new optional request fields, new response
    fields, new

    `error.type` values, and new enum members. Clients must tolerate unknown
    response fields

    and unknown `error.type` values (see the `ErrorResponse` schema).


    An **unknown or malformed** `KnoxCall-Version` value returns `400` with

    `error.type: invalid_api_version`.


    ## Rate Limiting


    API keys can have optional rate limits configured. When a limit is
    configured, the

    following headers are emitted on **every** response (not only `429`s):

    - `X-RateLimit-Limit` -- maximum requests allowed per window

    - `X-RateLimit-Remaining` -- remaining requests in the current window

    - `X-RateLimit-Reset` -- epoch seconds at which the window resets


    When the limit is exceeded the API returns `429` (`rate_limit_exceeded` /
    `rate_limited`)

    and additionally sets `Retry-After` (seconds until the window resets).


    ## Idempotency


    All mutating requests (`POST`/`PUT`/`PATCH`/`DELETE`) accept an idempotency
    key so a

    retried request is executed at most once. Supply it as `X-Idempotency-Key`

    (the standard `Idempotency-Key` spelling is also accepted), max 255
    characters.


    - Replaying a completed request with the same key returns the original
    stored response,
      annotated with an `X-Idempotent-Replay: true` response header.
    - A key that is still being processed returns `409 request_in_progress`.

    - Re-using a key with a **different** request body returns `422
    idempotency_key_reuse`.

    - A malformed key returns `400 invalid_idempotency_key`.


    ## Pagination


    List endpoints support pagination with the following query parameters:

    - `page` -- page number (default: 1)

    - `per_page` -- items per page (default: 20, max: 100)

    - `sort` -- field to sort by (varies per endpoint)

    - `order` -- sort direction: `asc` or `desc`


    Paginated responses include a `meta` object with `total`, `page`,
    `per_page`, and `total_pages`.


    ### Offset ceiling


    The server derives its SQL offset as `(page - 1) * per_page` and will not

    exceed 100,000 rows, so `page` is clamped to `floor(100000 / per_page) + 1`

    (1,001 at the maximum `per_page` of 100). Two consequences:


    - `meta.page` echoes the **effective** page, which may be lower than the one
      you asked for. It always matches the rows returned.
    - `meta.total_pages` is capped at that same page, so it is
      `min(ceil(total / per_page), floor(100000 / per_page) + 1)`. A pager that
      walks until `page >= total_pages` therefore terminates.

    `meta.total` still reports the true row count. If `total` exceeds

    `total_pages * per_page` you are being truncated by the ceiling -- narrow

    the result set with a filter (date range, status, resource id) instead of

    paging deeper.


    ## Error Handling


    All errors follow one canonical shape everywhere on `/v1`:

    `{"error": {"type", "message", "request_id"}}`. The `type` field is a
    machine-readable

    category (see the `ErrorResponse` schema for the full enum). Request-body
    validation

    failures are always `400 validation_error`; the one `422` case is
    `idempotency_key_reuse`.
  contact:
    name: KnoxCall Support
    url: https://knoxcall.com
    email: support@knoxcall.com
  license:
    name: Proprietary
    url: https://knoxcall.com/terms
servers:
  - url: https://api.knoxcall.com/v1
    description: Production
  - url: https://sandbox.knoxcall.com/v1
    description: Sandbox (test keys only)
security:
  - OAuth2: []
  - BearerAuth: []
  - ApiKeyAuth: []
tags:
  - name: Routes
    description: Manage proxy routes that forward API requests to upstream targets.
  - name: Secrets
    description: Manage encrypted secrets injected into route headers and bodies.
  - name: Clients
    description: Manage authorized clients (users or servers) with IP-based access control.
  - name: Environments
    description: >-
      Manage deployment environments (e.g. production, staging) for route
      configuration overrides.
  - name: API Keys
    description: Create and revoke API keys for programmatic access.
  - name: Webhooks
    description: Manage webhook subscriptions for real-time event notifications.
  - name: Account
    description: Retrieve account information and usage metrics.
  - name: Audit Logs
    description: Query the immutable audit trail of all API actions.
  - name: Signup
    description: >-
      Headless account creation — the only unauthenticated endpoint, designed so
      scripts and AI agents can onboard without a browser.
  - name: OAuth Clients
    description: Manage OAuth 2.1 clients used to mint access tokens for the API.
  - name: Agents
    description: Manage BYO server agents (self-hosted data-plane / tunnel agents).
  - name: Crypto Keys
    description: >-
      Transit encryption keys — encrypt, decrypt, rewrap, sign, verify, and
      issue JWTs without key material ever leaving KnoxCall.
  - name: Encryption
    description: >-
      Portable structure-preserving encryption — encrypt any JSON into storable
      `kc:` ciphertext strings and decrypt them later.
  - name: Client Tokens
    description: >-
      Single-use client-side capability tokens (`kct_` prefix) that let a
      browser exchange one bound ciphertext or vault token for its plaintext.
  - name: PKI
    description: >-
      Private certificate authority — roots, issuing roles, leaf certificates,
      revocation, and CRLs.
  - name: Dynamic DB Credentials
    description: >-
      Just-in-time database credentials — register connections and roles, then
      mint short-lived leased users on demand.
  - name: Vaults
    description: >-
      Data tokenization vaults — swap sensitive values for format-preserving
      tokens and detokenize them under audit.
  - name: Ephemeral Proxy
    description: >-
      One-shot proxy that resolves vault-token template expressions on the wire
      — no pre-configured route required.
  - name: Wrap Credentials
    description: >-
      Escrow a third-party provider key into KnoxCall custody so it leaves your
      codebase, host-pinned; the ephemeral proxy injects it under
      X-Knox-Upstream-Auth-Secret.
  - name: Opportunities
    description: >-
      Suggestions to turn detected outbound API usage (agent-observed or
      gateway-traffic) into a durable route; accept promotes to a route + secret
      binding.
  - name: Workflows
    description: >-
      Create, manage, and run workflows. Executions are asynchronous; poll
      executions or subscribe a webhook to workflow.execution.completed|failed.
  - name: AI Gateway
    description: >-
      Manage AI egress gateways, their agents, and capability (phantom) tokens,
      plus cost/token spend rollups and FinOps exports.
paths:
  /ai-gateway/mcp-servers/{id}:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The MCP server UUID.
    get:
      tags:
        - AI Gateway
      summary: Get an MCP server
      description: Returns one MCP server, including `connect_url` and `resource`.
      operationId: getAiGatewayMcpServer
      responses:
        '200':
          description: The MCP server.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/AiGatewayMcpServer'
                  meta:
                    $ref: '#/components/schemas/RequestMeta'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    AiGatewayMcpServer:
      type: object
      description: |
        An MCP server KnoxCall proxies and governs. `connect_url` and `resource`
        are deliberately different values — see their descriptions.
      properties:
        id:
          type: string
          format: uuid
        gateway_id:
          type: string
          format: uuid
          nullable: true
        name:
          type: string
        slug:
          type: string
          nullable: true
          description: Lowercase machine handle; the last segment of `connect_url`.
        description:
          type: string
          nullable: true
        server_type:
          type: string
          enum:
            - upstream
            - collection
          description: >-
            Only `upstream` can be created today; `collection` is not served
            yet.
        transport:
          type: string
          enum:
            - streamable_http
            - sse
          nullable: true
        upstream_url:
          type: string
          format: uri
          nullable: true
          description: The upstream MCP endpoint. Always a public `https://` address.
        allowed_tools:
          type: array
          items:
            type: string
          description: >-
            Tool names this server may advertise. EMPTY MEANS IT ADVERTISES
            NOTHING — a client sees an empty tool list.
        pii_inspection:
          type: boolean
          description: Inspect tool arguments and results for PII.
        pii_redact_policy_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            The tenant PII policy whose recognizers apply to this server's tool
            arguments and results (AIGW-151). Null means every enabled
            recognizer this tenant owns, on top of the shipped built-ins. Before
            AIGW-151 the MCP plane used one built-in-only detector stack built
            at boot, so no tenant recognizer ever applied to tool traffic.
        firewall_policy_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            Prompt-injection firewall policy applied to this server's tool
            traffic.
        guardrail_webhook_url:
          type: string
          format: uri
          nullable: true
          description: >-
            The tenant's own external scanner (AIGW-150). https only, no
            embedded credentials, and the destination is SSRF-checked at write
            time and again on every call. Unlike `/v1/ai` there is no streaming
            carve-out — the MCP transport materialises every JSON-RPC message,
            so both directions are always inspectable.
        guardrail_webhook_secret_id:
          type: string
          format: uuid
          nullable: true
          description: KnoxCall secret holding the HMAC key deliveries are signed with.
        guardrail_webhook_mode:
          type: string
          enum:
            - 'off'
            - request
            - response
            - both
          description: >-
            Which directions are offered to the scanner. `request` sees the tool
            ARGUMENTS after PII redaction and before they leave; `response` sees
            the tool RESULT after redaction and before it is returned. A `block`
            verdict refuses the call.
        guardrail_webhook_timeout_ms:
          type: integer
          minimum: 100
          maximum: 10000
        guardrail_webhook_failure_action:
          type: string
          enum:
            - fail_open
            - fail_closed
          description: What happens when the scanner cannot be reached or does not answer.
        auth:
          type: object
          additionalProperties: true
          description: >-
            Upstream auth. Only `{ headers, environment_name }` is supported,
            and every header value must reference a KnoxCall secret, so this
            object never contains a credential.
        sandbox:
          type: boolean
          description: >-
            Which Live/Test space this server lives in (AIGW-152). READ-ONLY: it
            is taken from the mode of the request that created the server (a
            test API key on the sandbox host makes a Test server) and cannot be
            set or changed through the API, for the same reason the mode is
            never a request field anywhere else — a body that could choose it
            would let a Test caller create a Live server whose `auth` reference
            resolves a LIVE secret. Reads and writes are confined to the calling
            key's own space, so a Live key does not see a Test server at all. On
            the data plane the confinement is the capability token's: a
            `kp_test_` token against a Live server is a 404. The same slug may
            exist in both spaces, so an MCP client's configuration does not
            change between them.
        status:
          type: string
          enum:
            - active
            - paused
            - archived
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        connect_url:
          type: string
          format: uri
          description: Where an MCP client points. Served on the tenant data-plane host.
        resource:
          type: string
          format: uri
          description: >-
            The RFC 8707 `resource` a token for this server must be bound to. A
            token bound to a different resource is refused at this server.
    RequestMeta:
      type: object
      description: Metadata included with every API response.
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            Unique identifier for this API request, useful for support and
            debugging.
          example: 550e8400-e29b-41d4-a716-446655440000
      required:
        - request_id
    ErrorResponse:
      type: object
      description: Standard error response envelope.
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              description: >-
                Machine-readable error type. The set is OPEN — endpoints define
                specific types beyond the common ones below, so clients should
                branch on the types they know and fall back to the HTTP status
                class for anything unrecognized. Common values:
                authentication_required, invalid_api_key, wrong_key_type,
                subscription_inactive, rate_limit_exceeded, validation_error,
                forbidden, not_found, conflict, in_use, plan_limit,
                plan_feature, internal_error, invalid_request,
                invalid_definition, not_cancellable, invalid_idempotency_key,
                idempotency_key_reuse, request_in_progress,
                system_client_protected, use_oauth.
              example: validation_error
            message:
              type: string
              description: Human-readable error message.
              example: name and target_base_url are required.
            request_id:
              type: string
              format: uuid
              description: Unique identifier for this request.
              example: 550e8400-e29b-41d4-a716-446655440000
          required:
            - type
            - message
            - request_id
      required:
        - error
  responses:
    Unauthorized:
      description: Authentication is required or the provided API key is invalid.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missing_key:
              summary: No API key provided
              value:
                error:
                  type: authentication_required
                  message: >-
                    API key is required. Use Authorization: Bearer <api_key> or
                    x-api-key header.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            invalid_key:
              summary: Invalid API key
              value:
                error:
                  type: invalid_api_key
                  message: Invalid API key.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    Forbidden:
      description: >
        The key is authenticated but not authorized for this action (missing
        scope), a plan

        limit was reached, or the resource must be managed via OAuth
        (`use_oauth`) / is a

        protected system client (`system_client_protected`).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            forbidden:
              summary: Missing scope
              value:
                error:
                  type: forbidden
                  message: This key is not authorized to list AI gateways.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            use_oauth:
              summary: Resource is OAuth-only
              value:
                error:
                  type: use_oauth
                  message: >-
                    This resource must be managed with an OAuth 2.1 access
                    token.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
            system_client_protected:
              summary: Protected system client
              value:
                error:
                  type: system_client_protected
                  message: >-
                    This client is managed by the platform and cannot be
                    modified.
                  request_id: 550e8400-e29b-41d4-a716-446655440000
    NotFound:
      description: The requested resource was not found.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: not_found
              message: Route not found.
              request_id: 550e8400-e29b-41d4-a716-446655440000
    InternalError:
      description: An unexpected server error occurred.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        KnoxCall-Version:
          $ref: '#/components/headers/KnoxCall-Version'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: internal_error
              message: An unexpected error occurred.
              request_id: 550e8400-e29b-41d4-a716-446655440000
  headers:
    X-Request-Id:
      description: >
        Unique identifier for this request (UUID). Present on **every** response
        and equal

        to the `request_id` field in the response body. Quote it when contacting
        support.
      schema:
        type: string
        format: uuid
      example: 550e8400-e29b-41d4-a716-446655440000
    KnoxCall-Version:
      description: >
        The dated API version (`YYYY-MM-DD`) that served this response. Equals
        the value

        of the `KnoxCall-Version` request header when supplied, otherwise the
        newest version.
      schema:
        type: string
        pattern: ^\d{4}-\d{2}-\d{2}$
      example: '2026-08-05T00:00:00.000Z'
  securitySchemes:
    OAuth2:
      type: oauth2
      description: >
        OAuth 2.1 authentication — recommended for new integrations. Access
        tokens

        (`kc_` prefix) are minted at the root-host token endpoint

        `https://api.knoxcall.com/oauth/token` and passed as `Authorization:
        Bearer <access_token>`.

        Public clients must use PKCE with the `authorization_code` grant;
        confidential

        clients may use `client_credentials`. The first-party SDKs and the

        `knoxcall login` CLI handle token minting, caching, refresh, and DPoP
        for you.
      flows:
        clientCredentials:
          tokenUrl: https://api.knoxcall.com/oauth/token
          refreshUrl: https://api.knoxcall.com/oauth/token
          scopes:
            routes:read: Read routes.
            routes:write: Create, update, and delete routes.
            secrets:read: >-
              Read secret metadata. Does NOT include retrieving a live OAuth2
              access token.
            secrets:oauth_token: >-
              Retrieve a live upstream OAuth2 access token (GET
              /v1/secrets/{id}/oauth2/token). Distinct from secrets:read because
              the call refreshes the credential at the provider.
            secrets:write: Create, update, and delete secrets.
            vaults:detokenize: >-
              Turn a vault token back into its original value. Required by GET
              /v1/vaults/{vault}/tokens/{token}, by a token template reference
              in a /v1/proxy body, and by creating a `detokenize` route action.
              Distinct from vaults:read, which lists vaults and token metadata
              and never returns a value.
            transit:decrypt: >-
              Open a portable `kc:` ciphertext with a tenant transit key.
              Required by creating a `decrypt` route action, which stores a
              standing instruction to open every matching field on every later
              request through that route. It is the same capability name the
              policy engine uses for POST /v1/decrypt. No routes scope satisfies
              it — managing a route is not permission to open the data flowing
              through it.
            proxy:invoke: >-
              Call the one-shot ephemeral proxy (any method on /v1/proxy).
              Required for EVERY verb — the proxy is one capability behind one
              handler, and a bodyless GET spends an escrowed credential exactly
              as a POST does. Neither proxy:read nor proxy:write satisfies it.
            clients:read: Read clients.
            clients:write: Manage clients.
            webhooks:write: Manage webhooks.
            workflows:write: Manage and execute workflows.
            '*:*': Full access (all scopes).
        authorizationCode:
          authorizationUrl: https://api.knoxcall.com/oauth/authorize
          tokenUrl: https://api.knoxcall.com/oauth/token
          refreshUrl: https://api.knoxcall.com/oauth/token
          scopes:
            routes:read: Read routes.
            routes:write: Create, update, and delete routes.
            secrets:read: >-
              Read secret metadata. Does NOT include retrieving a live OAuth2
              access token.
            secrets:oauth_token: >-
              Retrieve a live upstream OAuth2 access token (GET
              /v1/secrets/{id}/oauth2/token). Distinct from secrets:read because
              the call refreshes the credential at the provider.
            secrets:write: Create, update, and delete secrets.
            vaults:detokenize: >-
              Turn a vault token back into its original value. Required by GET
              /v1/vaults/{vault}/tokens/{token}, by a token template reference
              in a /v1/proxy body, and by creating a `detokenize` route action.
              Distinct from vaults:read, which lists vaults and token metadata
              and never returns a value.
            transit:decrypt: >-
              Open a portable `kc:` ciphertext with a tenant transit key.
              Required by creating a `decrypt` route action, which stores a
              standing instruction to open every matching field on every later
              request through that route. It is the same capability name the
              policy engine uses for POST /v1/decrypt. No routes scope satisfies
              it — managing a route is not permission to open the data flowing
              through it.
            proxy:invoke: >-
              Call the one-shot ephemeral proxy (any method on /v1/proxy).
              Required for EVERY verb — the proxy is one capability behind one
              handler, and a bodyless GET spends an escrowed credential exactly
              as a POST does. Neither proxy:read nor proxy:write satisfies it.
            clients:read: Read clients.
            clients:write: Manage clients.
            webhooks:write: Manage webhooks.
            workflows:write: Manage and execute workflows.
            '*:*': Full access (all scopes).
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Legacy long-lived API key authentication via the Authorization header.

        Pass your API key as: `Authorization: Bearer tk_xxx_yyy`.


        Standard keys (`tk_` prefix) are accepted on `api.knoxcall.com`.

        Test keys (type=test) are accepted on `sandbox.knoxcall.com`.

        Enterprise Access Keys (`AKE` prefix) are accepted on both.


        Fully supported, but prefer the `OAuth2` scheme (or the SDKs, which
        handle

        OAuth for you) for new integrations.
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >
        Legacy API key authentication via the `x-api-key` header.

        This is an alternative to Bearer token authentication for clients that
        cannot

        set the `Authorization` header. Prefer the `OAuth2` scheme for new
        integrations.

````