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

# Custom API

> Beta. Build an MCP server from an OpenAPI 3 spec after an admin turns on Custom API to MCP.

> [!WARNING]
>
> **Custom API** is beta. It stays off until an admin turns on **Custom API to MCP**.

Custom API builds an MCP server from an OpenAPI 3 description of an HTTP API. The server shows a **Custom API** badge. That badge has no translation. Chats and agents call it like any other server on the **MCP** tab. See [Custom MCP](https://docs.tess.im/en/mcp-custom.md).

## Turn it on

Open the admin page titled **Feature Toggles**. That title has no translation. The page links back with **Back to dashboard**.

Turn on **Custom API to MCP**. The label has no translation and carries a beta badge. The switch is unchecked when the setting is missing. Create and update stay behind this switch. It is a platform feature toggle, not a control in workspace settings.

## Where to build it

**Build from Custom API** is in the add menu of MCP Plugins. The same screen is embedded in the Connectors dialog, on the tab labeled **MCP**.

The add control depends on whether any server is already listed:

* None yet: **Add custom MCP**. That label has no translation.
* At least one: **New MCP Server**, with the line **Add a Custom MCP Server**.

The menu also offers **Import by JSON** and **Direct configuration**. Those two labels have no translation. **Build from Custom API** is the third item, and only when the feature switch is on and you can create MCP servers.

You can create one if you can write MCP plugins, or if you can manage them. A workspace owner can manage them.

## What you fill in

The create dialog title is **Build from Custom API**. **Build** stays disabled until the name, the base URL, a specification, and a credential are filled in. While it saves, the button reads **Building...**. Both button labels have no translation.

| Field | Required | What the dialog accepts |
| - | - | - |
| **Server Name** | Yes | Up to 255 characters. Placeholder **e.g., My Custom Server**. The label and placeholder have no translation. |
| **Base URL** | Yes | An `http` or `https` URL, up to 2048 characters. Placeholder `https://api.provider.com/v1`. A blocked address shows **The base URL is not allowed.** The label has no translation. |
| **API specification** | Yes | **URL**, **Upload**, or **Paste**. See below. |
| **Authentication** | Yes | One of four types. The default is **API Key**. |
| **Notes** | No | Up to 1000 characters. Placeholder **Which operations matter, what must not become a tool**. Notes are stored on the server. They do not remove operations from the spec. The label and placeholder have no translation. |
| **Share with workspace** | No | A switch. See sharing below. |

### API specification

OpenAPI 3 only. The `openapi` field must be `3` or start with `3.`. The document needs an `info` object, a non-empty `paths` object, and at least one operation. An operation is `get`, `put`, `post`, `delete`, `patch`, `head`, `options`, or `trace`.

If you have never seen one of these files, start with [What an OpenAPI spec is and how to get one](https://docs.tess.im/en/openapi-spec.md).

| Source | What you enter |
| - | - |
| **URL** | **Spec URL**, an `http` or `https` address up to 2048 characters. A blocked address shows **The API spec URL is not allowed.** **Spec URL** has no translation. |
| **Upload** | `.json`, `.yaml`, or `.yml`, up to 2 MB. The zone says **Drag & drop or click to browse** and **Upload an OpenAPI/Swagger file (JSON or YAML)**. The second line has no translation. A wrong extension shows **Only .json, .yaml and .yml files are supported**. Over 2 MB in the browser shows **File is too large (max 2 MB)**. |
| **Paste** | The spec text. Placeholder **Paste your OpenAPI/Swagger spec**, which has no translation. |

The stored spec is also limited to 2 MB. A larger document shows **This file is larger than the 2 MB limit. Please send a smaller version with only the parts of the API you will use.**

### Authentication

| Type | What to fill |
| - | - |
| **Bearer Token** | The token, up to 4096 characters. Placeholder **API key or bearer token**, untranslated. |
| **API Key** | The same secret field. This is the default. |
| **Custom Header** | The secret, plus **Header name, e.g. X-API-Key**. The header name is required and has no translation. |
| **Token (fetched by request)** | Tess requests a token and renews it. See the next section. |

### Token fetched by request

The dialog says Tess requests a token with the request below and renews it when it expires. Reference a secret as `{{secret.name}}` and the token as `{{access_token}}`.

* **Secrets**. At least one. Up to 20. Each name is letters, numbers, and underscores, up to 64 characters. A bad name shows **Secret names may use only letters, numbers and underscores.** Placeholders are **Name, e.g. api\_key** and **Value**. **Add secret** adds a row.
* **Token request**. **Method** is **POST** or **GET**. **Token URL, e.g. /v1/auth** is a full `http` or `https` URL, or a path that starts with `/`. A bad path shows **Use a full http(s) URL or a path starting with /.** A blocked URL shows **The token URL is not allowed.** Optional headers, up to 20. Optional body, up to 16384 characters.
* **Token response**. **Token field, e.g. access\_token** is required. **Expiry field (seconds), e.g. expires\_in** is required. Each is a dotted name such as `access_token` or `data.expires_in`.
* **Headers sent on every call**. At least one, up to 20. One of them must contain `{{access_token}}`. If it does not, the dialog shows the sentence **Use `{{access_token}}` in at least one header sent on every call.** Using `{{access_token}}` on the token request itself shows **`{{access_token}}` can only be used in the headers sent on every call.** A placeholder that does not match a secret names that placeholder.

## What becomes a tool

Each HTTP operation under `paths` becomes a tool. There is no separate allow-list for a Custom API spec, and **Notes** do not drop operations. Tess names the tool from the operation. The server card lists those tools, and you can turn each one on or off for yourself.

## A small spec

Paste this under **Paste**, with **Base URL** `https://api.example.com`. It is one GET. **Authentication** still needs a credential even if the API is public. Use a placeholder value the API will ignore, or the header the API actually checks.

```json theme={null}
{
  "openapi": "3.0.3",
  "info": { "title": "Status", "version": "1.0.0" },
  "paths": {
    "/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "Read the service status",
        "responses": { "200": { "description": "OK" } }
      }
    }
  }
}
```

## Sharing

On create, **Share with workspace** starts **on** if you can govern MCP (workspace owner, or permission to manage MCP plugins). It starts **off**, and the control is disabled, if you cannot. The disabled hint is **Sharing with the workspace requires MCP governance permission**.

You can change it later from the server card, not from **Edit**. The card hint for someone who can change it is **Shared with workspace — click to change** or **Personal — click to share**. Confirming a share says **All workspace members will be able to use ":name".** The button is **Share**. Making it personal says **Other members will lose access to ":name".** The button is **Make personal**.

A personal server stays with the person who created it. A shared server can be used by workspace members. Opt-in for chat is the same as other Custom MCP servers: [Custom MCP](https://docs.tess.im/en/mcp-custom.md).

## Use it

In chat, open Connectors and the **MCP** tab. Turn the server on, and turn on the tools you want. In Agent Studio, add that MCP server to the agent's connector policy the same way as any other Custom MCP server.

## Edit and delete

The card menu button is titled **More actions**. **Edit** opens a dialog titled **MCP configuration**. **Delete** removes the server. **Delete** is shown when you are allowed to delete it: the creator of a personal server, if they can still create MCP servers, or someone who can govern MCP. A governor can also delete another person's personal server.

On edit you can change the name, the icon, the base URL, the authentication, the specification, and the credential.

* Leave the specification empty: **Leave this empty to keep the current specification.**
* Change the address or the authentication: you must send the specification again. **Send the API specification again to change the address or authentication.**
* Leave the credential blank: **Leave blank to keep the current credential.** Switching to **Token (fetched by request)** and sending a new spec means filling the secrets and the token request again: **To send a new specification, fill in the secrets and the token request again.**
* **Icon** (**optional**). Placeholder **Paste in URL**. An HTTPS address, or empty to clear it. Anything else shows **The icon must be an HTTPS address.**

**Edit** does not include **Share with workspace**. More on the shared edit rules: [Edit a Custom MCP server](https://docs.tess.im/en/mcp-custom.md#edit-a-custom-mcp-server).

## When a spec is refused

A plain-language checklist is in [What an OpenAPI spec is and how to get one](https://docs.tess.im/en/openapi-spec.md).

| What you see | What to change |
| - | - |
| **This file uses an older format (Swagger 2.0). Please send the OpenAPI 3 version, or ask whoever provides the API to update it.** | The file is Swagger 2. Send OpenAPI 3. |
| **This file doesn't look like a valid API documentation (OpenAPI). Please check that you sent the right file.** | Not OpenAPI 3, missing `info`, no `paths`, or no operations. Also covers a spec that is not a JSON or YAML object, invalid JSON or YAML, or nesting deeper than 64 levels. |
| **We couldn't read this file. It uses a YAML shortcut we don't support yet. Please send the JSON version of the API documentation — usually a link or file ending in openapi.json or swagger.json. If you can't find it, ask whoever provides the API to export the documentation as JSON.** | The YAML uses anchors or aliases. Send JSON. |
| **This file is larger than the 2 MB limit. Please send a smaller version with only the parts of the API you will use.** | Cut the spec down. |
| **The API address is not valid or can't be reached from the internet. Please check the address you entered.** | Fix **Base URL**. |
| **The base URL is not allowed.** or **The API spec URL is not allowed.** | The address failed the outbound check. Use a public `http` or `https` URL. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.