Create custom connector
/connector
Authors a new org-owned connector, either from a catalog `config` or — bring your own — from a remote streamable-HTTP MCP server (`remote_mcp`). Send exactly one of the two. Requires `connector:create` and the `custom_connectors` plan feature. The config is schema-validated: a malformed one answers 422 with the exact issues. The slug is permanent and must be unique within the catalog. A remote MCP connector is private to its creator until shared (the ordinary connector grants), and its tools are discovered per connection, not at creation. `remote_mcp.url` must be https, must not name Elaichi itself, and is immutable afterwards. `auth_mode` says how members sign in: `oauth_auto` (Elaichi registers itself with the server's authorization server — Client ID Metadata Document first, else dynamic registration; 400 when neither exists), `oauth_client` (your own `client_id` and optional `client_secret`), `custom` (an `auth_config` declaring a token form, no OAuth) or `none`. Absent, it is inferred: `client_id` means `oauth_client`, `auth_config` means `custom`, and otherwise the server is probed (OAuth metadata means `oauth_auto`, even when it also answers anonymously; a server with no sign-in at all answers 400 `sign_in_not_offered` unless you send `auth_mode: "none"`; anything else answers 400 `remote_mcp_auth_required`). A field that does not belong to the mode is a 400. The OAuth client is stored as the organization's own app for the connector, never in the connector entry. An organization may hold 25 remote MCP connectors (409 `remote_mcp_server_limit`). The 201 is the connector detail, with `kind: "remote_mcp"`, `remote_mcp` (`url`, `auth_mode`, `oauth_registration`) and `auth` (what sign-in the connector declares, names only — never a secret).
Request Body
Mutually exclusive with config.
custom only: credentials (an api_key form), authorization, headers, query — the shape of a connector config minus resources. Values are placeholders ({{api_key}}); a literal secret is refused.
oauth_autooauth_clientcustomnone
oauth_client only.
oauth_client only. Write-only.
OAuth modes only (400 for custom and none). Off by default. true makes a token refresh send no scope (RFC 6749 §6: omitted means the original grant); the RFC 8707 resource is still sent. For a server that rejects a scope on refresh, such as Close (400 invalid_scope). Echoed as auth.omit_refresh_scope.
OAuth only. Defaults to what the server advertises.
The server's streamable-HTTP MCP endpoint (https).
Connector definition (resources, methods, auth). Mutually exclusive with remote_mcp; config.remote_mcp is reserved.
remote_mcp only.
remote_mcp only. An https URL.
Lowercase letters, digits and hyphens. new is reserved.
curl -X POST 'https://api.elaichi.ai/connector' \
-H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"remote_mcp":{},"logo":"your_logo","description":"your_description","slug":"your_slug","label":"your_label","config":{}}'const body = {
"remote_mcp": {},
"logo": "your_logo",
"description": "your_description",
"slug": "your_slug",
"label": "your_label",
"config": {}
};
const response = await fetch('https://api.elaichi.ai/connector', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const data = await response.json();
console.log(data);import os
import requests
url = "https://api.elaichi.ai/connector"
headers = {
"Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
"Content-Type": "application/json",
}
payload = {
"remote_mcp": {},
"logo": "your_logo",
"description": "your_description",
"slug": "your_slug",
"label": "your_label",
"config": {}
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())