MCP Server#
ec-mcp-api serves the
Model Context Protocol, so an AI agent can
manage the platform with the same credentials and permissions as a direct API
client. On an installation the endpoint is
https://<your-domain>/api/core/v1/mcp; the service itself answers at
http://127.0.0.1:11014/v1/mcp.
It is a service of its own, next to the User API rather than part of it. A tool call becomes an ordinary HTTP call to the User API carrying the caller's credentials, so the User API decides what the call may do, exactly as it does for a direct client. This service holds no credentials and reaches no database: without a caller's token it can do nothing.
The endpoint implements the stateless subset of the Streamable HTTP
transport: each JSON-RPC message is one POST, answered with one JSON
response. There are no sessions, no server-sent events, and no batching.
Authentication#
Every request needs an Authorization: Bearer <token> header with an IAM
access token; without the header the endpoint answers 401. Tool calls run
as the token's owner, so IAM permissions and security rules apply exactly as
they do to direct API calls. X-OTP is passed on as well, along with the
headers the security rule verifiers read (X-Firebase-AppCheck,
X-Goog-Firebase-AppCheck and X-Captcha). Nothing else is passed on.
Configuration#
user_api_url is the base the service calls the User API under. It can be an
internal address: the service forwards the caller's Host header so
API-generated absolute URLs retain the public host.
Tools#
Resource tools#
The resources agents reach for most have a tool per operation, named
list_<resources>, get_<resource>, create_<resource>,
update_<resource> and delete_<resource>, with every field of the request
spelled out in the tool's input schema. The resources are nodes, node sets,
configs, values, secrets, elements, users, projects, organizations and roles.
get, update and delete take the resource uuid; list takes the
endpoint's filters, including q, whose syntax the server sends once in
its instructions (timestamps are filtered through q alone); create and
update take the fields of the resource itself. Read-only fields, such as
project_id, are not arguments — the API fills them in.
Generic tools#
Everything the resource tools do not cover is reachable through these.
| Tool | Purpose |
|---|---|
list_endpoints |
Lists METHOD path - summary lines, filtered by an optional search substring. |
describe_endpoint |
Returns the OpenAPI operation for method and a path template, with all $refs resolved. |
call_api |
Calls method on a concrete /v1/... path with optional query and JSON body, and returns the HTTP status and response body. |
The endpoint list and the resource tools' schemas come from the same OpenAPI
document as the User API reference, so they
cannot drift from the API. The resource tools leave out what only documents
a field — examples, titles, string lengths and patterns; the API still
checks them. disk_spec of nodes and node sets offers the root disk alone;
several disks go through call_api.
The first tools/list, list_endpoints or describe_endpoint call in each
worker builds the document, which takes a few seconds.
Connecting clients#
Access token#
Obtain an IAM access token as shown in
Local Deployment; the ttl parameter sets
how long the token lives. When it expires, the client's tool calls fail
with 401, so issue a new token and update the client.
The examples below use https://<your-domain>/api/core/v1/mcp. Where a
client can read the token from the environment, they take it from
EXORDOS_TOKEN:
Clients without environment variable substitution need the token written into their configuration file; keep that file private.
Copilot CLI#
copilot mcp add --transport http \
--header "Authorization: Bearer $EXORDOS_TOKEN" \
exordos https://<your-domain>/api/core/v1/mcp
The command writes the server to ~/.copilot/mcp-config.json. Alternatively,
run /mcp add inside a session, choose HTTP, and enter the URL and
{"Authorization": "Bearer <token>"} as HTTP Headers. To keep the token
out of the file, edit the entry by hand:
{
"mcpServers": {
"exordos": {
"type": "http",
"url": "https://<your-domain>/api/core/v1/mcp",
"headers": {
"Authorization": "Bearer ${EXORDOS_TOKEN}"
},
"tools": ["*"]
}
}
}
GitHub Copilot in other IDEs#
JetBrains IDEs, Visual Studio, Eclipse, and Xcode share one format: a
servers object with the header under requestInit.headers. None of them
documents variable substitution, so the token is written as is:
{
"servers": {
"exordos": {
"type": "http",
"url": "https://<your-domain>/api/core/v1/mcp",
"requestInit": {
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
}
Where to put it:
- JetBrains: Copilot Chat in Agent mode, the tools icon, Add MCP
Tools; this opens
mcp.json. - Visual Studio 17.14 or later: Copilot Chat in Agent mode, the tools
icon, +. Fill in the URL and add an
Authorizationheader in the dialog, or edit%USERPROFILE%\.mcp.json(all solutions) or<solution>\.mcp.json. - Eclipse: Preferences > GitHub Copilot > MCP, paste the JSON into Server Configurations, and click Apply.
- Xcode: Copilot for Xcode settings, MCP tab, Edit Config.
Claude applications#
Claude Code — add the server from the command line:
claude mcp add --transport http exordos \
https://<your-domain>/api/core/v1/mcp \
--header "Authorization: Bearer $EXORDOS_TOKEN"
This stores the expanded token in ~/.claude.json. To share the server with
a project without sharing the token, commit a .mcp.json at the project
root instead:
{
"mcpServers": {
"exordos": {
"type": "http",
"url": "https://<your-domain>/api/core/v1/mcp",
"headers": {
"Authorization": "Bearer ${EXORDOS_TOKEN}"
}
}
}
}
Claude Desktop — claude_desktop_config.json starts local servers
only, so connect through the mcp-remote
bridge (requires Node.js). Edit
~/Library/Application Support/Claude/claude_desktop_config.json on macOS or
%APPDATA%\Claude\claude_desktop_config.json on Windows, then restart the
application:
{
"mcpServers": {
"exordos": {
"command": "npx",
"args": [
"mcp-remote",
"https://<your-domain>/api/core/v1/mcp",
"--transport",
"http-only",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer <token>"
}
}
}
}
Keep Authorization:${AUTH_HEADER} without a space: some clients do not
quote arguments.
If your organization has request headers for custom connectors (a limited
beta), you can instead add a custom connector at Customize > Connectors >
Add custom connector with no sign-in and an authorization header of
Bearer <token>. Such connectors are called from Anthropic's cloud, so the
installation must be reachable from the internet.
Codex#
codex mcp add exordos \
--url https://<your-domain>/api/core/v1/mcp \
--bearer-token-env-var EXORDOS_TOKEN
This adds the following to ~/.codex/config.toml, which the Codex CLI, the
IDE extension, and the desktop app share. Codex reads EXORDOS_TOKEN when it
connects:
[mcp_servers.exordos]
url = "https://<your-domain>/api/core/v1/mcp"
bearer_token_env_var = "EXORDOS_TOKEN"
Cursor#
Add the server to ~/.cursor/mcp.json, or to .cursor/mcp.json in a
project:
{
"mcpServers": {
"exordos": {
"url": "https://<your-domain>/api/core/v1/mcp",
"headers": {
"Authorization": "Bearer ${env:EXORDOS_TOKEN}"
}
}
}
}
OpenCode#
Add the server to ~/.config/opencode/opencode.json, or to opencode.json
in a project:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"exordos": {
"type": "remote",
"url": "https://<your-domain>/api/core/v1/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer {env:EXORDOS_TOKEN}"
}
}
}
}
Windsurf#
Add the server to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"exordos": {
"serverUrl": "https://<your-domain>/api/core/v1/mcp",
"headers": {
"Authorization": "Bearer ${env:EXORDOS_TOKEN}"
}
}
}
}
Zed#
Open the settings with zed: open settings file (~/.config/zed/settings.json)
and add the server; Zed does not substitute variables here. The same entry
can be created from Settings > AI > MCP Servers > Add Remote Server.
{
"context_servers": {
"exordos": {
"url": "https://<your-domain>/api/core/v1/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
Rovo Dev CLI#
Run acli rovodev mcp to open ~/.rovodev/mcp.json and add the server;
variables are not substituted here either. Check it with /mcp in a
session.
{
"mcpServers": {
"exordos": {
"url": "https://<your-domain>/api/core/v1/mcp",
"transport": "http",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
MCP Inspector#
To try the tools in MCP Inspector,
import server.json
from the repository root, an MCP Registry description of both endpoints.
The Inspector asks for the domain (or host) and the token.