# Get started with connectors

Last validated Jun 15, 2026

> **Note:** Aperture connectors are currently in alpha.

\[Missing snippet: aperture\_mcp\_experimental\_note.mdx]

This guide walks you through adding your first connector, granting access, and verifying the connection. For background on how connectors work, refer to [How connectors work][kb-connectors-how-it-works]. For complete field definitions, refer to the [connectors reference][kb-connectors-reference].

## Prerequisites

Before you begin, you need the following:

* Aperture enabled on your [tailnet][kb-tailnet]. Refer to [Get started with Aperture][kb-aperture-get-started] if you have not set this up.
* Admin access to the Aperture configuration. This guide has you edit its `connectors` and `grants` sections.
* The URL of at least one upstream service such as an MCP server or HTTP API, reachable from the Aperture host.

## Step 1: Add a connector

> **Note:**
>
> For connectors that authenticate, especially `oauth2_authorization_code` and `oauth2_client_credentials`, complete the upstream setup first. Create the OAuth application or API credentials on the MCP server or API provider, register Aperture's callback URL (`https://<aperture-hostname>/aperture/auth/<connector-id>/callback`), and note the client ID, client secret, scopes, and token URLs. You supply these values when you add the connector.

You can add connectors in two ways:

* **From the verified registry**: The dashboard connector picker includes pre-configured defaults for many common providers, for example Salesforce, Atlassian, Slack, GitHub, Notion, and Linear. Open the picker in the dashboard for the current list. Select a provider, and Aperture pre-fills its configuration. Most providers then need only your OAuth client credentials; connectors that use [`oauth2_dcr`][kb-connectors-reference-dcr] (such as Atlassian, Notion, and Linear) need none, because Aperture registers the OAuth client automatically.
* **Custom configuration**: Add a `connectors` section with one or more server entries. Each entry needs a `protocol` (`"mcp"` or `"http"`) and a `url`.

The following example adds an unauthenticated MCP server and an authenticated HTTP API:

```json
{
  "connectors": {
    "servers": {
      "docs": {
        "protocol": "mcp",
        "url": "http://mcp-server.example.ts.net:8185/v1/mcp"
      },
      "github": {
        "protocol": "http",
        "url": "https://api.github.com",
        "description": "GitHub REST API (read-only)",
        "auth": {
          "type": "bearer_token",
          "secret": "github_pat_example"
        }
      }
    }
  }
}
```

Each key in the `servers` map is a connector ID that Aperture uses as a name prefix. Connector IDs must contain only letters and digits, starting with a letter. The IDs `tailscale`, `internal`, and `aperture` are reserved. Refer to the [connectors reference][kb-connectors-reference] for the full ID rules and authentication types.

Aperture supports `bearer_token`, `api_key`, `basic`, `oauth2_client_credentials`, and `oauth2_authorization_code` authentication. Refer to the [connectors reference][kb-connectors-reference] for each type's fields.

> **Tip:**
>
> The Aperture host uses its tailnet HTTP client for connections, so you can use [MagicDNS][kb-magicdns] hostnames (for example, `http://mcp-server.example.ts.net:8080/v1/mcp`) without additional network configuration.

## Step 2: Grant access

Aperture is deny-by-default. Without grants, users cannot access any connector capabilities. Add grants in the `grants` section of your configuration.

The following example grants all users access to every connector capability, including the built-in Aperture tools:

```json
{
  "grants": [
    {
      "src": ["*"],
      "app": {
        "tailscale.com/cap/aperture": [
          {"connectors": ["**"]}
        ]
      }
    }
  ]
}
```

Connector grants use the `connectors` field with `"connectorID/category/resource"` glob patterns. The valid categories are `tools`, `resources`, `templates`, and `proxy`. Both MCP and HTTP connectors require grants. Refer to the [grants configuration reference][kb-aperture-grants] for the full syntax.

## Step 3: Verify the connection

First, verify the connector in Aperture. Open the **Connectors** page in the dashboard, select the connector, and confirm its status shows **Ready** and that the capability list contains the tools, resources, and templates you expect. The Connectors page probes the upstream URL, so a connector that cannot reach its server or list its capabilities surfaces the error here.

### If the connector isn't Ready

If the connector does not show **Ready**, its status indicates the cause:

* **Needs auth**: The connector uses OAuth and no one has authorized it yet. Authorize the connector before calling it.
* **Misconfigured**: A token is stored but cannot be refreshed. Reauthorize the connector and make sure the upstream OAuth application grants offline access.
* **No access**: Your tailnet identity has no grant for this connector. Revisit [Step 2][ar-step-2-grant-access].

If the capability list fails to load, the Connectors page shows an upstream error (such as `502 upstream error`). This means Aperture reached the connector but the upstream URL could not be reached or could not list its capabilities. Confirm the `url` is correct and reachable from the Aperture host.

When you call a connector and receive a `403 access denied` response, the caller's tailnet identity lacks a matching grant. Revisit [Step 2][ar-step-2-grant-access].

Once the connector shows **Ready**, verify access from a client. Run these commands from a device on your tailnet whose identity has the grants from [Step 2][ar-step-2-grant-access]. Aperture authorizes each request from the caller's tailnet identity, and `<aperture-hostname>` is the Aperture host's MagicDNS name.

For MCP connectors, point your MCP client at the Aperture URL and list available tools:

```shell
curl http://<aperture-hostname>/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```

The response contains a `tools` array with prefixed entries from your configured connectors (for example, `docs_search`).

For HTTP connectors, send a request through the Aperture proxy path:

```shell
curl http://<aperture-hostname>/v1/connectors/github/user
```

Aperture forwards the request to `https://api.github.com/user` and injects the configured bearer token automatically.

## Next steps

* [Set up an HTTP API connector][kb-set-up-http-api-connector] to proxy requests to an upstream REST API with automatic authentication.
* [Set up a per-user OAuth 2.0 connector][kb-set-up-per-user-oauth2-connector] to connect agents to services that require individual user authorization.
* [Use a connector][kb-connectors-use] once it is configured, to authorize and call its tools as an end-user.

[ar-step-2-grant-access]: #step-2-grant-access

[kb-aperture-get-started]: /docs/aperture/get-started

[kb-aperture-grants]: /docs/aperture/configuration#grants

[kb-connectors-how-it-works]: /docs/aperture/connectors/how-connectors-work

[kb-connectors-reference]: /docs/aperture/connectors/reference

[kb-connectors-reference-dcr]: /docs/aperture/connectors/reference#dynamic-client-registration-oauth2_dcr

[kb-connectors-use]: /docs/aperture/connectors/use-a-connector

[kb-magicdns]: /docs/features/magicdns

[kb-set-up-http-api-connector]: /docs/aperture/how-to/set-up-http-api-connector

[kb-set-up-per-user-oauth2-connector]: /docs/aperture/how-to/set-up-per-user-oauth2-connector

[kb-tailnet]: /docs/concepts/tailnet
