Remote MCP servers
Register your organization's own MCP servers and serve their tools through the same authenticated surface.
An organization admin can register any HTTPS MCP server as a remote
connector. Its tools appear as org__<slug>__<tool> on the org's /mcp
surface (the org__ marker is what lets your slug coexist with a same-named
built-in connector) — same authentication, same holds, same activity trail as
every built-in capability. Registration is org-scoped: nothing you
register is visible to any other organization.
Register from Dashboard → Connectors,
with the manage__remote_add MCP tool, or via POST /connectors/org.
Three auth modes:
oauth— each member authorizes their own account against the server's authorization server; CoreSpeed stores and refreshes the grant. A member can share their account with another member, an agent, or the whole organization (see Sharing an account).static_bearer— one org-wideAuthorization: Bearer <token>sent upstream; the token is encrypted at rest.none— no credential; anyone who knows the URL can call the server.
OAuth mode and the callback URL
On an oauth registration CoreSpeed discovers the server's authorization
server (RFC 9728) and — when that AS advertises a registration_endpoint —
registers an OAuth client automatically (RFC 7591 dynamic client
registration). The client is always registered with this exact redirect URI:
https://app.corespeed.io/connectors/callbackThe path is always /connectors/callback under the environment's dashboard
origin.
Servers that implement registration without the optional RFC 7592 management
extension — Cloudflare Access, Neon, and everything built on Cloudflare's
workers-oauth-provider — work normally: the client registers and activates.
The one consequence is on removal: CoreSpeed deletes everything on its side,
but the inert client record stays on the authorization server, because that
server offers no way to delete it.
Many authorization servers restrict registration: some offer no dynamic
registration at all, and some accept it only for redirect URIs already
allowlisted in their configuration (Cloudflare Access behaves this way — its
registration endpoint answers invalid_client_metadata for any redirect URI
the Access application has not been told about). Either setup works:
- Allow the redirect URI, keep automatic registration. Add the redirect
URI above to the authorization server's allowed redirect URIs, then
register the connector in
oauthmode — dynamic registration proceeds on its own. - Pre-register a client yourself. Create a client in the authorization
server's console with the redirect URI above, grant types
authorization_code+refresh_token, and response typecode; then pass itsclient_id(andclient_secret, unless it is a public PKCE-only client) with the registration.
When an OAuth registration fails
- The authorization server rejects the registration (an HTTP 4xx error
response): the error carries the HTTP status, plus the server's
machine-readable error code whenever the answer uses a registered one (the
RFC 7591 registration errors or the generic OAuth vocabulary — free-text
detail stays confined to the server). Nothing is left behind and the slug
stays free — fix the configuration using one of the two setups above and
register again. In the rare case the cleanup itself fails mid-flight, the
slug falls back to a
dcr_pendingreservation; clear it as below. - The outcome is unknown (network failure, timeout, or a 5xx answer): the
slug is held by a
dcr_pendingreservation so that a blind retry cannot create a duplicate client on the upstream server. An organization admin clears it withmanage__remote_remove, passingexpected_status=dcr_pendingand the reservation'sregistration_idfrommanage__remote_listasexpected_registration_id, then registers again.
After a successful registration each member authorizes their own account from
the dashboard. The server's tools appear in tools/list once a member's
authorization has fetched them.
Sharing an account
On an oauth server, a member who authorized can share that account like any
other connected account: choose Share on it on the server's page, or call
manage__accounts_share with connector: "org__<slug>" and the slug as
alias. A share allows every tool or a list you pick (org__<slug>__<tool>),
and can require your approval on every call.
A call acts under the caller's own account. A caller with no account of their
own acts under the account shared with them. When two or more members shared
theirs and the caller has none, the call fails with ambiguous_account:
connect your own, or call from an environment
that holds one of them. A static_bearer or none server needs no sharing:
every member already uses it.