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

# Set up a Product MCP from the dashboard

> Create a Product MCP, upload your OpenAPI document, configure how callers authenticate, and activate the public endpoint — step-by-step from the Armature dashboard.

This guide walks through publishing a Product MCP from the Armature dashboard. By the end, you have a live public MCP URL at `https://mcp.<org-slug>.armature.tech/<source-slug>` that wraps your product API.

If you have not yet read [Product MCP overview](/product-mcp/overview), start there for the concepts.

## Prerequisites

Before you begin, make sure you have:

* **An HTTPS base URL** for your product API. Plain `http://` is rejected except for `localhost` during local development.
* **An OpenAPI document** (JSON, up to 6 MB) describing the operations you want to expose as MCP tools.
* **A validation endpoint** on the same origin as your base URL — ideally a "who am I" or token-introspection route that returns `2xx` for valid credentials and `401`/`403` for invalid ones. You can skip this only if you accept the security trade-off of `presence_only` mode.
* The **editor**, **admin**, or **owner** role on your Armature organization.

## 1. Create the Product MCP

<Steps>
  <Step title="Open the Product MCPs page">
    In the dashboard sidebar, select **Product MCPs**, then click **New Product MCP**.
  </Step>

  <Step title="Name your endpoint">
    Enter a descriptive **name** (for example, `Acme Public API`) and a **slug**. The slug becomes the path on your public MCP URL — pick lowercase letters, digits, hyphens, or underscores, 2–80 characters.

    The dashboard previews the public URL as you type:

    ```text theme={null}
    https://mcp.<your-org-slug>.armature.tech/<slug>
    ```
  </Step>

  <Step title="Enter your base URL">
    Paste the **base URL** of your product API, for example `https://api.acme.example.com`. Armature forwards tool calls to paths under this origin.

    <Warning>
      The base URL must use `https://`. The only exception is `localhost` for local development.
    </Warning>
  </Step>

  <Step title="Create the endpoint">
    Click **Create**. The Product MCP is created in the **Needs setup** state — it is not yet servable. You complete setup with the next two steps.
  </Step>
</Steps>

## 2. Upload your OpenAPI document

Armature parses your OpenAPI document into MCP tools, capability descriptions, and a search index that callers use to discover the operations you expose.

<Steps>
  <Step title="Open the API docs panel">
    From the Product MCP detail page, click **Upload API docs**.
  </Step>

  <Step title="Upload the OpenAPI JSON">
    Select your OpenAPI document (up to 6 MB). Armature validates it on upload and rejects malformed documents with a clear error.
  </Step>

  <Step title="Review the generated capabilities">
    Once parsed, the **API docs** card shows the number of capabilities (one per operation), any warnings raised during generation, and the last sync time. Re-upload at any time to refresh.
  </Step>
</Steps>

A Product MCP with zero capabilities cannot be activated. If the capability count is `0`, check the warnings — usually a missing `operationId`, an unsupported request body, or an unreachable `$ref`.

## 3. Configure the API Connection

The **API Connection** controls how the caller's product credential reaches your MCP endpoint and how Armature forwards it upstream.

<Steps>
  <Step title="Open the API Connection panel">
    On the detail page, click **Configure API Connection**.
  </Step>

  <Step title="Choose where the caller sends the credential">
    Pick the **credential location** and **credential name**:

    <Tabs>
      <Tab title="Header (default)">
        Callers send the credential in an HTTP header. The default name is `Authorization` for `bearer` format and `X-API-Key` for `raw` format. Change the name to match how your customers already authenticate against your product.
      </Tab>

      <Tab title="Query parameter">
        Callers send the credential as a query parameter on the MCP URL — for example `?api_key=...`. Use this only when callers cannot set headers (rare for MCP).
      </Tab>
    </Tabs>

    Then pick the **token format**:

    * **`bearer`** — the value must include the `Bearer ` scheme. Anything else returns `401 product_mcp_credential_malformed`.
    * **`raw`** — the value is forwarded as-is.
  </Step>

  <Step title="Choose how Armature forwards the credential upstream">
    * **Same** — Armature forwards the credential to your upstream API in the same location, name, and format the caller used. This is the right default when your MCP authentication is the same as your product API authentication.
    * **Custom** — remap to a different header or query name and/or strip the `Bearer ` prefix. Use this when your product API expects, for example, `X-API-Key: <raw>` even though callers send `Authorization: Bearer <raw>` to the MCP endpoint.
  </Step>

  <Step title="Pick a validation mode">
    * **`validate_before_tools`** (recommended) — enter a **validation endpoint** on the same origin as your base URL. Armature calls it with the caller's credential before serving `tools/list` or any tool call. `2xx` means valid; `401`/`403` means invalid; network failure or `5xx` fails closed with `503`.
    * **`presence_only`** — accept any well-formed credential without validating. Enabling this requires checking the security-risk acknowledgment in the dashboard.

    Validation results are cached in memory for 5 minutes by default, keyed by a one-way fingerprint of the credential. Adjust **Validation cache TTL** between 1 second and 1 hour if you need different cache behavior.
  </Step>

  <Step title="Save the configuration">
    Click **Save API Connection**. The **API Connection** card on the detail page now shows the configured location, name, format, validation mode, and last sync time.
  </Step>
</Steps>

### Example: same forwarding with bearer tokens

```json theme={null}
{
  "credentialLocation": "header",
  "credentialName": "Authorization",
  "tokenFormat": "bearer",
  "validationMode": "validate_before_tools",
  "validationEndpoint": "https://api.acme.example.com/v1/me",
  "upstreamForwarding": { "mode": "same" }
}
```

A caller sends `Authorization: Bearer <token>` to the MCP endpoint. Armature validates against `/v1/me`, and on every tool call forwards the same header to your upstream API.

### Example: custom remapping

```json theme={null}
{
  "credentialLocation": "header",
  "credentialName": "Authorization",
  "tokenFormat": "bearer",
  "validationMode": "validate_before_tools",
  "validationEndpoint": "https://api.acme.example.com/v1/me",
  "upstreamForwarding": {
    "mode": "custom",
    "location": "header",
    "name": "X-API-Key",
    "tokenFormat": "raw"
  }
}
```

Callers still send `Authorization: Bearer <token>` to MCP. Armature unwraps the `Bearer ` prefix and forwards the raw token upstream as `X-API-Key: <token>`.

## 4. Activate the endpoint

Once **API docs** shows at least one capability and **API Connection** is configured, the **Activate** button on the detail page becomes available. Click it to publish.

The status moves to **Live** and the public MCP URL begins serving traffic. Pause at any time by clicking **Pause** — paused endpoints return `403` until you resume them.

## What callers see

A connected MCP client sees:

* **`tools/list`** — one tool per OpenAPI operation, with arguments derived from the operation's parameters and request body schema.
* **`tools/call`** — Armature executes the operation against your base URL, forwarding the caller's credential.
* **A `WWW-Authenticate` challenge** advertising the same header or query parameter you configured. A compliant MCP client knows to attach the right credential without any Armature-specific OAuth flow.

## Runtime health and security

The detail page surfaces two ongoing signals:

* **Runtime health** — requests in the last 24 hours, broken down by outcome. Useful for confirming traffic and spotting upstream errors.
* **Security warning** — present whenever the endpoint is configured for `presence_only` validation. Switch to `validate_before_tools` to clear it.

Raw credentials are never written to the dashboard database, telemetry, or any sandboxed code path. The validation cache and runtime events are keyed by a one-way SHA-256 fingerprint of the credential, so even an exfiltrated cache cannot be replayed.
