Outbound servers
Mount a third-party MCP server into your workspace so your own agents can call its tools, with trust, refresh and reconnect under your control.
Your workspace can be an MCP client too. Connect a remote server and every tool it serves becomes available to the agents that opt in, next to their built-in tools. This has no effect on the inbound endpoint described on MCP: connecting a server outward exposes nothing inward.
Every operation on this page needs the connectors system permission on your key or session: read to list, create to connect, update to refresh, trust or reconnect, delete to disconnect.
Connect a server
Two sources:
- The catalog. Four curated entries, all on their official hosted endpoints and all OAuth: PostHog, Notion, Linear and GitHub. Picking a card starts OAuth at once and brings you back to the same page after consent.
- A custom server. Any MCP server reachable over HTTPS. You give it a name, a slug, the URL and an auth mode.
A connection is all-or-nothing. The server is saved only after its first tools/list succeeds, so a listed server was reachable and authenticated at least once.
Auth modes
| Mode | What Standards sends |
|---|---|
none | Nothing. The server takes unauthenticated requests. |
header | One header, headerName: secret, verbatim on every request. Include the Bearer prefix in the secret yourself when the server expects one. The secret is write-only: once saved it is never shown again, including to you. |
oauth | The server's own OAuth flow, Authorization Code with PKCE. Tokens are stored encrypted and refreshed for you. |
From a terminal, standards mcp connect takes --auth-type none or header; OAuth servers are connected from the app. See CLI: MCP servers.
Visibility
visibility is workspace or private. A workspace server is visible to every member and to every agent that opts in. A private server is visible to you alone and only to an agent acting on your behalf. To anyone else it does not exist: no error, no id in a log, the same rule that applies to private records.
Slug and tool names
The slug is the server's identifier and the prefix of every tool it mounts. It is lowercase letters, digits and hyphens, starting with a letter or digit, unique per workspace. Underscores are not allowed, which is what keeps the tool name unambiguous:
mcp__<slug>__<tool>A server with slug notion that serves search mounts mcp__notion__search. Two servers can both serve search without colliding.
Egress policy
Standards applies the same egress rules to every outbound MCP request:
- the URL must be
https://; localhost,*.localhost, loopback and private IP addresses are refused, and the resolved address is pinned for the connection;- an optional hostname allowlist can restrict which hosts may be connected at all;
- at most three redirects are followed, each hop re-validated against the rules above;
- the auth header is dropped the moment a hop changes origin, so a credential is never replayed to a host you did not configure;
- an OAuth credential request must not redirect at all.
Trust
A newly connected server is untrusted. Its tools ask for your approval before every call, with no way to approve once for the session.
Marking a server trusted puts its tools in the mutation tier: the same tier as a built-in tool that writes data, approved once per session. A remote tool is never placed in the outward tier. The annotations the server declares about its own tools (readOnlyHint, destructiveHint, and so on) are shown in the tool's description for you to read and are never used to decide the tier: they are written by the party being fenced.
Trust is explicit. It is not implied by connecting, and a server cannot grant it to itself. From a terminal: standards mcp trust <id> and standards mcp trust <id> --revoke.
Tool groups and refresh
Each server is an on-demand tool group. An agent loads it when it needs it rather than carrying every remote tool in every turn.
The tool list is synced when you connect and whenever you ask for a refresh: the Refresh action in the app, POST /mcp-servers/:id/refresh, or standards mcp refresh <id>. A refresh never disarms an agent:
- if it fails, the previous tool list stays in place and the error is stored in
lastSyncError, shown on the server's row until a later refresh succeeds; - if a trusted server changed a tool's description or input schema, or added a tool, the server is demoted to untrusted. The new definitions are stored; what you vetted is no longer what the server serves, so its tools go back to per-call approval until a person trusts it again. A tool that merely disappeared does not demote the server.
One resync is automatic. When an agent calls a tool and the remote answers that it does not know it (unknown_tool), Standards refreshes the server once and checks the refreshed list. If the tool is gone, the agent is told the catalog was stale and has been refreshed. If it is still there, the underlying remote error is reported as is.
Status and reconnect
A server is active, needs_reauth or error.
needs_reauth means the remote rejected the stored credential. For a header server, replace the secret. For an oauth server, start a reconnect attempt with POST /mcp-servers/:id/oauth/attempts; it reuses the server row, so nothing has to be removed and added again. An attempt can carry either completionMode or returnUrl, not both, and its progress is readable at GET /mcp-servers/oauth/attempts/:id.
When the flow returns to your returnUrl, three query parameters report the outcome:
| Parameter | Value |
|---|---|
mcp_oauth_status | connected or error. |
mcp_server_id | The server's id, on success. |
mcp_oauth_error | An error code such as mcp_oauth_needs_reauth, on failure. |
Which agents can use a server
An agent gets a server's tools only by opting in with mcpServers: a list of server ids, or "all". An agent with no opt-in gets none, so connecting a server never changes an existing agent. Opt-in runs first and visibility runs last: naming a server the agent's viewer cannot see does nothing.
import { agent } from "@stndrds/schema";
export const assistant = agent({ name: "assistant" })
.mcpServers(["<notion-server-id>", "<linear-server-id>"]);Next steps
- CLI: MCP servers —
standards mcp list,connect,refresh,trustanddisconnect. - MCP — the inbound direction: Standards as a server.
- Tools — the built-in tools your agents carry next to the remote ones.
- Workspaces and API keys — where the
connectorspermission lives.