MCP & connectors
Connect Claude, ChatGPT or another MCP client to a company account through the Hub remote MCP server, and how its tools behave.
In build (MCP server)
The remote MCP server is part of phase 1 and not released yet. Address, sign-in and tool behaviour below are the agreed contract.
Hub runs a remote MCP server. A chat assistant connected to it works in one company's account, with the permissions a person granted during sign-in.
| Server URL | https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp |
| Transport | Streamable HTTP, stateless, JSON responses |
| Sign-in | OAuth 2.1; clients register themselves (Dynamic Client Registration) |
| Protected resource metadata | https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp/.well-known/oauth-protected-resource |
Claude (web, desktop, mobile)
On Free, Pro and Max plans you add the connector to your own account. The Free plan allows one custom connector.
- Open Customize > Connectors and click Add custom connector.
- Enter a name (for example "eCMR Hub") and the server URL
https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp. Leave the OAuth client fields empty: Claude registers itself. - Click Add, then Connect.
- Sign in to Hub in the window that opens, choose the permissions and keep "Require my approval" on. Claude can now use the Hub tools.
On Team and Enterprise plans an Owner adds the connector under Organization settings > Connectors (Add, then Custom, type Web), and each member connects with their own Hub account under Customize > Connectors.
Source: Anthropic, "Add a connector that isn't in the directory" (claude.com/docs/connectors, read 19 October 2026).
Claude Code
claude mcp add --transport http ecmr-hub https://api-ecmr-dev.lucaspiera.com/functions/v1/mcpThen run /mcp in Claude Code, choose the server and Authenticate in the browser. For a
terminal agent the CLI is an alternative with the same operations.
ChatGPT
Custom MCP servers are added on ChatGPT on the web. Whether you can add one depends on your plan and on your workspace's settings.
- Go to chatgpt.com/plugins, select the plus button, then Add custom MCP server.
- Enter a name and, under Connection, the server URL
https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp. - Choose OAuth authentication. ChatGPT registers itself.
- Read the risk warning, select I understand and want to continue, then Create as a plugin.
- Install the plugin, sign in to Hub, choose the permissions.
- In a conversation type
@and pick the plugin.
ChatGPT asks you to confirm each write tool call on its side. That confirmation is separate from Hub's approval in the dashboard: issuing still needs the person's approval in Hub.
Source: OpenAI, "Add custom MCP server" (developers.openai.com, read 19 October 2026).
Other MCP clients
Any client with Streamable HTTP and OAuth 2.1 sign-in works the same way: point it at
https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp and let it register. A typical configuration file:
{
"mcpServers": {
"ecmr-hub": { "url": "https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp" }
}
}Prefer OAuth. A client that only supports a fixed header can send a company API key instead:
claude mcp add --transport http ecmr-hub https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp \
--header "Authorization: Bearer $ECMR_HUB_API_KEY"The server signs in with the key for you; the key's permissions and approval setting apply. Keep the key out of shared configuration files.
Tools
Tools come from the same operation catalog as the CLI:
- The tool name is the operation name with dots replaced by underscores:
draft.publishbecomesdraft_publish. - Only operations Hub executes on the server and a connection may call are tools: about 40 of the catalog. Operations reserved for a person or the owner (approving, managing people, keys and connections, deleting an account) and operations of the eCMR app screen are not.
- Each tool carries
readOnlyHintanddestructiveHint, so a client can ask you to confirm writes on its side. - Every writing tool has an optional
approvalIdargument. Pass it only after a result withstatus: "approval_required". - A tool fails when the connection lacks its permission.
document_pdfreturns the PDF as an embedded resource (application/pdf) with its SHA-256.
The list your client sees comes from tools/list, and it is the final word.
When a tool needs approval
A tool that needs a person's approval does not fail. It returns a normal result:
{
"structuredContent": {
"status": "approval_required",
"approvalId": "6f1c2a9e-...",
"url": "https://ecmrhub-v2.lucaspiera.com/dashboard/approvals/6f1c2a9e-...",
"expiresAt": "2026-10-20T10:00:00.000Z",
"operation": "draft.publish"
}
}The text content says the same in words. Show the link to the user. After they approve, call the
same tool with the same arguments plus "approvalId": "6f1c2a9e-...". The rules are on
Human approvals.
Other results a tool may return, each with a text explaining the next step:
status | Error | Meaning |
|---|---|---|
approval_rejected | yes | The person rejected it; ask the user what to change |
approval_expired | yes | Older than 24 hours; call again without approvalId |
approval_mismatch | yes | The arguments differ from the approved ones |
error | yes | Any other error, with code, httpStatus and retryable |
Sign-in errors
| Answer | Meaning |
|---|---|
401 with WWW-Authenticate: Bearer resource_metadata="..." | No token: the client starts the OAuth sign-in |
401 CONNECTION_REVOKED | The company disconnected this client |
401 CONNECTION_REQUIRED | The token is not from a connection or an API key (for example a dashboard session) |
401 API_KEY_INVALID | The API key is wrong, revoked or expired |
503 AUTH_UNAVAILABLE | Sign-in could not be checked; retry |
Server instructions
On connect the server sends short instructions to the model: approvals come from a person and the model must not try to approve; never invent data, ask the user; eFTI support is validation and a list of gaps only. Agents should follow them in every conversation.
Disconnecting
The company sees every connected client in the dashboard under Connections and can disconnect
it. After that the client's calls fail with 401 CONNECTION_REVOKED; connecting again needs a new
sign-in.