Set up an authenticated MCP connector
Last validated:
Aperture connectors are in public alpha. The connectors grant syntax and the connectors configuration section may change. The mcp_tools, mcp_resources, and mcp_templates grant fields are deprecated. Use the connectors field instead.
Use this guide to connect Aperture to a remote MCP server that authenticates with a shared, machine-to-machine credential. Aperture stores the credential once and uses it for every authorized request. To add an unauthenticated MCP server, refer to get started with connectors. For connectors where each user authorizes individually, refer to set up a per-user OAuth 2.0 connector instead.
Prerequisites
Before you begin, you need the following:
- Admin access to the Aperture configuration, with the
connectorsfeature flag enabled. Refer to get started with connectors. - The URL of the MCP server, reachable from the Aperture host.
- A credential for the server: either a static token or OAuth 2.0 client credentials (client ID, client secret, and token URL).
Choose an authentication type
A shared MCP credential supports two authentication types:
bearer_token: A static token that Aperture sends as anAuthorization: Bearerheader. Use this when the server issues a long-lived token.oauth2_client_credentials: A machine-to-machine OAuth 2.0 flow. Aperture obtains and auto-refreshes access tokens from the token URL. Use this when the server issues short-lived tokens through a client credentials grant.
Both types share the credential across every user with a matching grant. For credentials scoped to individual users, use the per-user OAuth 2.0 flow.
Add a bearer token connector
Add an entry to connectors.servers with protocol set to "mcp" and an auth block of type bearer_token. The entry's key is the connector ID, which must start with a letter and contain only letters and digits (no underscores or hyphens), because Aperture uses it to prefix tool names:
{
"connectors": {
"servers": {
"snowflake": {
"protocol": "mcp",
"url": "https://mcp.example.com/v1/mcp",
"auth": {
"type": "bearer_token",
"secret": "sk-example-token"
}
}
}
}
}
Add an OAuth 2.0 client credentials connector
For a machine-to-machine OAuth 2.0 flow, use an auth block of type oauth2_client_credentials. Aperture refreshes the access token automatically:
{
"connectors": {
"servers": {
"analytics": {
"protocol": "mcp",
"url": "https://analytics.example.com/v1/mcp",
"auth": {
"type": "oauth2_client_credentials",
"client_id": "aperture-analytics",
"client_secret": "secret-example",
"token_url": "https://auth.example.com/oauth2/token",
"scopes": ["read:data"]
}
}
}
}
}
scopes is optional. Omit it if the provider does not require scopes for the client-credentials grant.
With the client-credentials grant, Aperture mints a fresh access token on demand from the token URL. There is no stored refresh token to renew, so refreshing means re-running the grant. Set token_url to the provider's canonical token endpoint: Aperture refuses redirects from the token endpoint to protect the client secret, so a redirecting URL fails. If the credential is rejected or the token URL is wrong, the failure does not change the connector's status. Instead, the connector's tool list is empty. Check the Aperture logs for the connector to confirm.
The credential on a shared MCP connector is used for every user with a matching grant. There is no per-user isolation. Scope the credential as narrowly as the server lets you.
The auth block rejects unknown fields. A typo in a field name (for example, secert instead of secret) fails validation at load time. Refer to the connectors reference for the required fields of each authentication type.
Grant access
MCP connectors are deny-by-default. Add a connectors grant so users can list and call the server's tools. Refer to grant access to MCP tools.
Verify the connection
Open the Connectors page in the Aperture dashboard and select the connector. The connector's status reflects your authorization to use it, not the health of the upstream connection. To confirm the connector is working, check that its capability list contains the expected tools.
Aperture discovers tools by connecting to the MCP server in the background. If the capability list is empty or missing expected tools, the connection or credential is failing rather than the connector being unauthorized. A misconfigured token URL, an expired or rejected credential, or an unreachable server URL all result in an empty tool list rather than a change in status. Check the Aperture logs for the connector to diagnose the failure.
Once the expected tools appear in the capability list, list them from a client. The /v1/mcp endpoint uses the streamable HTTP transport, so the request must include an Accept header that includes both JSON and event-stream responses. Aperture identifies the caller from the tailnet connection, so the request must originate from within the tailnet and needs no separate authorization header:
curl http://<aperture-hostname>/v1/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
The response contains a tools array with entries prefixed by the connector ID (for example, snowflake_query).
Related
- How connectors work - Understand the connector model, authentication, and capability discovery.
- Connectors reference - Authentication types, MCP protocol behavior, and validation rules.