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

# Custom MCP servers

> Connect a private or self-hosted MCP server and its tools become available to Henry.

If your team has internal tools behind a [Model Context Protocol](https://modelcontextprotocol.io) server, Henry can use them like any other integration. Add the server once and its tools appear to Henry with the same permission and sharing controls as everything else.

## Requirements

* **Transport:** Streamable HTTP. SSE-only servers are not supported.
* **URL:** `https://` required. `http://` is accepted only for `localhost` and `127.0.0.1` during local development.
* **Reachability:** the server must be on a public address. Private and internal ranges, link-local, loopback (other than localhost in dev), `*.local`, `*.internal`, and URLs with embedded credentials are rejected. Redirects are followed at most 3 times and each hop is checked the same way.
* **Auth:** OAuth, a static header, or none.

## Add a server

In **Integrations**, click **Add custom MCP**. Enter a **Name** (up to 100 characters) and the **Server URL**. Henry immediately performs an MCP `initialize` and `tools/list` within a 10-second budget.

* If the server answers, the connector is **ready** and its tools are cached.
* If it answers 401, Henry starts the OAuth flow described below.
* If it cannot be reached, the connector is still added and shows the error so you can fix the server and retry.

Adding a connector requires being an admin, or a member when the workspace allows members to connect integrations.

## Authentication

<Tabs>
  <Tab title="OAuth">
    Henry is a public OAuth 2.1 client using PKCE. It supports two ways of identifying itself to your authorization server:

    1. **URL-based client ID** (Client ID Metadata Documents). Henry's client ID is the URL `https://app.usehenry.ai/.well-known/oauth-client-metadata`. If your server advertises `client_id_metadata_document_supported`, no registration step is needed.
    2. **Dynamic Client Registration** (RFC 7591) as the fallback.

    Discovery follows RFC 9728 protected-resource metadata to your authorization server metadata.

    Whichever method your server uses, it must allow this redirect URI exactly:

    ```
    https://app.usehenry.ai/api/integrations/custom-connectors/callback
    ```

    Registered client metadata:

    ```json theme={null}
    {
      "client_name": "Henry",
      "redirect_uris": ["https://app.usehenry.ai/api/integrations/custom-connectors/callback"],
      "grant_types": ["authorization_code", "refresh_token"],
      "response_types": ["code"],
      "token_endpoint_auth_method": "none"
    }
    ```

    The authorization `state` is single-use and expires after 10 minutes. The same signed-in person who started the flow must finish it; a forwarded authorization link fails.

    If your authorization server only allows pre-approved clients, contact [support@usehenry.ai](mailto:support@usehenry.ai) to have Henry's client ID registered for your server's origin.
  </Tab>

  <Tab title="Static header">
    For servers that authenticate with a fixed token, add an account to the connector and fill in **API key or token** and **Header name** (default `Authorization`). Values up to 4,096 characters. The value is stored encrypted per workspace and sent as that header on every request.
  </Tab>

  <Tab title="None">
    A server that answers `initialize` and `tools/list` anonymously connects with no further setup.
  </Tab>
</Tabs>

## How tools appear to Henry

* Each tool is exposed under a key of the form `cc_<connector-name-slug>__<tool-name>`, truncated to 60 characters. With several accounts on one connector, the account label is included and tool descriptions are prefixed with the account.
* The `readOnlyHint` annotation decides the default permission: read tools **Run automatically**, everything else **Ask for confirmation**. Set annotations accurately.
* Tool lists are cached. Henry re-lists on first connect, nightly, when a cached tool fails, and when a cache entry is older than 26 hours.
* Tool results longer than 100,000 characters are paged.

## Limits

| Limit                        | Value                                                              |
| ---------------------------- | ------------------------------------------------------------------ |
| Tool sources loaded per turn | 50 (custom connectors are never dropped in favor of other sources) |
| Tools per source             | 200 on eager turns, 1,000 on deferred turns                        |
| Connect timeout per source   | 12 seconds                                                         |
| Probe timeout on add         | 10 seconds                                                         |
| Redirect hops                | 3                                                                  |

## Permissions and sharing

Custom connector tools use the same tri-state as every tool: **Off**, **Run automatically**, **Ask for confirmation**, set on the connector page or from a confirmation card. Permissions are per connector and cover all its accounts.

Accounts on a connector are **team** scope by default. Per-member access levels (**Full access**, **Read-only**, **No access**) apply; read-only members only see tools with `readOnlyHint`.

## Re-authorization

Tokens refresh silently. If a refresh fails because the grant is gone, the account shows **Authorization expired, reconnect** and is excluded from Henry's tools until you click **Authorize**. **Reauthorize** forces a fresh consent screen even when the current token works, which is how you switch upstream accounts or pick up new scopes. The old token keeps working until the new one lands.

## Errors you may see

| Message                                                        | Meaning                                                      |
| -------------------------------------------------------------- | ------------------------------------------------------------ |
| Server URL must be https (http is allowed for localhost only). | Use `https://`.                                              |
| Server URL must be a public address                            | The host resolves to a private, internal, or reserved range. |
| Added, but Henry couldn't reach the server                     | The connector was saved; fix reachability and retry.         |
| The MCP server redirected to a blocked address                 | A redirect landed on a private range.                        |
| The MCP server redirected more than 3 times.                   | Reduce redirect hops.                                        |
| Connector service temporarily unavailable.                     | Henry-side issue; retry shortly.                             |
