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

# Bring Your Own Integration

> Register any custom REST API by base URL — RouteMCP generates tools from its OpenAPI spec (or a generic passthrough tool) and exposes them as a first-class toolkit your agents can use.

Register your own **custom REST/HTTP API** at runtime. Point RouteMCP at a base URL, optionally
give it an OpenAPI spec, and it generates **one typed tool per operation**, embeds them for
search, and materializes the result as a **first-class toolkit** in your catalog — usable in the
playground, the router, and the chat completion endpoint, just like a built-in integration.

<Info>
  This is the REST-API sibling of [Bring Your Own MCP](/guides/byo-mcp). Use **BYO Integration**
  for a plain HTTP/REST API described by an OpenAPI spec; use **BYO MCP** for a server that speaks
  the Model Context Protocol.
</Info>

## How it works

<Steps>
  <Step title="Register the API">
    In the dashboard, open **Integrations → Add custom integration**. Provide a name, the **base
    URL** (host only — e.g. `https://api.example.com`), optionally an **OpenAPI spec URL**, and its
    authentication (see below).
  </Step>

  <Step title="Pick tools from a spec — or a passthrough tool">
    * **With a spec** → RouteMCP parses it and generates one tool per operation.
    * **Without a spec** → it registers a single generic `<SLUG>_CALL(method, path, query, body)`
      tool the agent drives directly. Good for quick, spec-less APIs.
  </Step>

  <Step title="Authenticate (OAuth only)">
    For OAuth integrations, click **Connect** after saving to complete the authorization handshake.
    `none` / API key / bearer are ready immediately.
  </Step>

  <Step title="Use it">
    The toolkit appears in your catalog. Attach it to a workspace and call it from the chat
    endpoint, or explore it in the playground — see [Using your integration](#using-your-integration-in-chat).
  </Step>
</Steps>

## The OpenAPI spec

RouteMCP generates tools from an OpenAPI/Swagger spec (JSON or YAML). You can supply it as a
**spec URL**, and for **recognized providers the URL is filled in for you** from just the base
URL — for example, typing `https://app.asana.com` auto-fills Asana's published spec, and typing
an Atlassian, Slack, Box, Xero, Spotify, or PayPal host does the same for theirs.

<Note>
  A **documentation page is not a spec.** RouteMCP needs the machine-readable OpenAPI file (a
  `.json`/`.yaml` URL), not the human docs page that lists endpoints or scopes — those can't be
  parsed. If you paste a docs page, you'll get a clear error pointing you to the spec file.
</Note>

Leave the spec blank for a single passthrough tool. Passthrough calls default to a JSON body; for
APIs that require `application/x-www-form-urlencoded` (e.g. **Stripe**), pass `"bodyFormat": "form"`
in the tool arguments.

## Ownership

Choose per integration:

* **Personal** — only you can see and use it.
* **Shared** — usable by everyone in your organization.

<Warning>
  Credentials — including OAuth tokens — are stored **per integration, not per user**. On a shared
  integration, whoever clicks **Connect** authorizes once and every member calls the upstream API
  as that account. Use **personal** ownership if each member should act as themselves.
</Warning>

## Authentication

Pick one auth type when registering. All credentials are encrypted at rest.

| Auth type        | When to use                          | What you provide                                     |
| ---------------- | ------------------------------------ | ---------------------------------------------------- |
| **None**         | Public APIs, no credentials          | —                                                    |
| **API key**      | A static key in a custom header      | The key + header name (defaults to `X-API-Key`)      |
| **Bearer token** | A static long-lived token            | The token (sent as `Authorization: Bearer …`)        |
| **OAuth 2.0**    | APIs that require an OAuth handshake | Client ID/Secret + authorization/token URLs + scopes |

<Tip>
  **Non-standard credential headers** are supported. Set the header name and prefix — e.g. Zoho
  Books uses `Authorization: Zoho-oauthtoken <token>`.
</Tip>

### OAuth 2.0 & scopes

Custom integrations don't support OAuth auto-discovery, so you enter the **Client ID**, the
provider's **Authorization URL** and **Token URL**, and the **scopes** to request.

When the integration has an OpenAPI spec that declares scopes, RouteMCP shows a **scope picker**
instead of a free-text box: search, tick the scopes you need, and (for recognized hosts with
curated defaults) start from a recommended set. A **Select all** control and a manual-add field
are there too, so you're never limited to what the spec happened to declare.

<Warning>
  Scopes must **also be enabled in the provider's own developer console** (e.g. Asana's OAuth app
  settings). RouteMCP can't check that for you — if the connect screen reports a forbidden scope,
  enable it there, then reconnect.
</Warning>

<Note>
  Scope strings are case- and format-sensitive. Most providers use a **colon** (`users:read`), not
  a dot. Copy them exactly as the provider documents them.
</Note>

After saving an OAuth integration, click **Connect** — you'll be redirected to the provider to
authorize, then returned to the dashboard.

<Warning>
  Add RouteMCP's callback to your OAuth app's **Authorized redirect URIs**:
  `https://api.routemcp.io/api/v1/connect/oauth/callback`
</Warning>

## Using your integration in chat

A registered integration becomes a **toolkit** identified by a **toolkit slug**
(`chttp_<name>_<hash>`). As with any toolkit, you attach it to a workspace, then chat with that
workspace.

<Steps>
  <Step title="Attach the toolkit to a workspace">
    In the dashboard, add the toolkit to a workspace's integrations. Or via the API, pass its slug
    in `integrations`:

    ```bash theme={null}
    curl -X POST https://api.routemcp.io/api/v1/mcp/workspaces \
      -H "Authorization: Bearer $ROUTEMCP_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "name": "My workspace", "integrations": ["chttp_asana_a1b2c3d4"] }'
    ```

    <Tip>Omit `integrations` (or pass `[]`) to expose **all** of your org's toolkits — your custom integration included.</Tip>
  </Step>

  <Step title="Chat with the workspace">
    Call the chat endpoint with the workspace's `serverId`:

    ```bash theme={null}
    curl -X POST https://api.routemcp.io/api/v1/mcp/{serverId}/chat \
      -H "Authorization: Bearer $ROUTEMCP_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "message": "List my Asana workspaces" }'
    ```

    The agent discovers your integration's tools via `SEARCH_TOOLS` and runs them via
    `MULTI_EXECUTE_TOOL`, wrapped in the platform's resilience stack.
  </Step>
</Steps>

## Managing an integration

From the integration's **⋯ menu** on the Integrations page:

* **Edit** — update the name, base URL, docs URL, and ownership. These take effect immediately
  (tools use paths relative to the base URL, so no re-import is needed). Auth type, spec, and
  credentials can't be changed in place — remove and re-add to change those.
* **Edit scopes** (OAuth) — add or remove requested scopes. Saving sets the integration back to
  **pending**; reconnect to grant the new set.
* **Remove** — deletes the integration and archives its tools.

## Insufficient-scope errors

If a tool call is refused for a missing OAuth scope, RouteMCP returns a precise, actionable
message: it names the **exact scope needed** and the scopes the connection **currently grants**,
and hands the agent the reconnect step. If the connection already grants every scope the spec
expects but the call still fails, that's usually a scope not enabled in the provider's developer
console — the message says so, rather than guessing.

## Notes & limits

* **Hybrid tools** — a spec generates typed tools (capped at 200 per integration; overflow is
  logged, never silently dropped); no spec gives one generic passthrough tool.
* **Resilience** — every call goes through the same circuit breaker, rate limiting, retry, and
  timeout stack as built-in integrations.
* **Security** — credentials are encrypted at rest and never returned to the browser; upstream
  error bodies are surfaced to the agent so failures are diagnosable.
