eCMRhub.docs

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 URLhttps://api-ecmr-dev.lucaspiera.com/functions/v1/mcp
TransportStreamable HTTP, stateless, JSON responses
Sign-inOAuth 2.1; clients register themselves (Dynamic Client Registration)
Protected resource metadatahttps://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.

  1. Open Customize > Connectors and click Add custom connector.
  2. 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.
  3. Click Add, then Connect.
  4. 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/mcp

Then 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.

  1. Go to chatgpt.com/plugins, select the plus button, then Add custom MCP server.
  2. Enter a name and, under Connection, the server URL https://api-ecmr-dev.lucaspiera.com/functions/v1/mcp.
  3. Choose OAuth authentication. ChatGPT registers itself.
  4. Read the risk warning, select I understand and want to continue, then Create as a plugin.
  5. Install the plugin, sign in to Hub, choose the permissions.
  6. 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.publish becomes draft_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 readOnlyHint and destructiveHint, so a client can ask you to confirm writes on its side.
  • Every writing tool has an optional approvalId argument. Pass it only after a result with status: "approval_required".
  • A tool fails when the connection lacks its permission.
  • document_pdf returns 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:

statusErrorMeaning
approval_rejectedyesThe person rejected it; ask the user what to change
approval_expiredyesOlder than 24 hours; call again without approvalId
approval_mismatchyesThe arguments differ from the approved ones
erroryesAny other error, with code, httpStatus and retryable

Sign-in errors

AnswerMeaning
401 with WWW-Authenticate: Bearer resource_metadata="..."No token: the client starts the OAuth sign-in
401 CONNECTION_REVOKEDThe company disconnected this client
401 CONNECTION_REQUIREDThe token is not from a connection or an API key (for example a dashboard session)
401 API_KEY_INVALIDThe API key is wrong, revoked or expired
503 AUTH_UNAVAILABLESign-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.

On this page