Any service not in the provider list reaches an agent as a custom_mcp integration: a remote MCP server at a URL you supply, with static headers you control. Attaching, allowed_tools and tools_namespace work as on every integration (MCP servers); this page covers what differs.

Connecting one

Create the secret your server’s token lives in first (see secrets), then:
Then run GET /v1/integrations/{integration_id}/mcp-tools to prove the connection and read each tool’s exposed_name before writing the prompt. mcp_config takes only url (required) and headers (an object of strings). Any other key is refused (custom_mcp: unknown config field 'transport').

Credentials

Header values are stored exactly as sent and returned on every read. Unlike other providers’ credential fields, they are not converted into secrets. Write {{secrets.NAME}} yourself.
  • {{secrets.NAME}} resolves in url and in header values. It is the only template root available; there is no per-call or per-caller value.
  • A reference to a secret that does not exist is refused at save (custom_mcp: secret 'NORTHWIND_MCP_TOKEN' does not exist) and again when an agent using it is published.
  • Any other {{…}} token (a typo such as {{secret.TOKEN}}) is refused rather than sent as literal braces.
  • There is no OAuth or dynamic client registration for a custom server. One integration is one set of static credentials.

Requirements for your server

A server that is down when a session starts does not fail the call; the agent runs without its tools.

Lookaround patterns are removed from schemas

A JSON Schema pattern containing lookahead or lookbehind ((?=, (?!, (?<=, (?<!) is removed from your tool schemas before they reach the model, because OpenAI rejects the whole request when it meets one. The tool is kept. Validate arguments in your server and return an error message the model can act on.

Namespacing

A custom server’s default tools_namespace is "", so its tools reach the model under the server’s own names. Generic names (search, get) collide easily with other tools; set a namespace such as crm to get crm_search.

Defining one inline

An agent or task config can define the server instead of naming an integration:
On save it is created as a custom_mcp integration named name, and the entry is stored as {"integration_id": "…"}. The URL and secret checks above run at save. If an integration with that name exists, the save returns 409: reference it by id or rename. tools_namespace defaults to ""; allowed_tools to null.

Example: read-only access

Your server exposes search_customers, get_order and refund_order, and the agent must never refund:
  1. Create the integration above with tools_namespace: "crm".
  2. PATCH it with {"allowed_tools": ["search_customers", "get_order"]} — the tools’ own names.
  3. Attach it to the agent’s mcps and publish.
  4. Write the prompt with crm_search_customers and crm_get_order.
refund_order is now absent from every attached agent’s tool list.

Next

MCP servers

Attaching, approving and namespacing.

Secrets

Creating the secret your headers reference.