Skip to content
API Reference
Connect agents

Connect coding agents

Put Keycard between Claude Code or Cursor and the tools it uses: through a Gateway with no code, or by starting the agent with the Keycard CLI.

There are two ways to put Keycard between a coding agent and the tools it calls. Pick one, or use both.

  • Through a Gateway, with no code. Console gives you one MCP URL that fronts the MCP servers you choose. Keycard holds their credentials, decides each tool call against your policy, and records it. You install nothing beyond the agent. The walkthrough below takes about 10 minutes.
  • With the Keycard CLI. keycard run starts the agent inside a Keycard session. Credentials for the Resources named in your keycard.toml are minted into environment variables, and the session is recorded. Use this for tools that take an API key or token from the environment: CLIs, and MCP servers that authenticate with a header instead of an OAuth sign-in. See With the Keycard CLI.

An agent started with keycard run can connect to a Gateway, so the two combine.

In about 10 minutes you’ll connect Claude Code to Linear through a Keycard gateway and watch Keycard decide each tool call. Reading issues goes through. Creating one is refused before the request reaches Linear, and both decisions show up in Console. You won’t write code or handle a Linear token: Keycard holds the Linear credential and hands it to the gateway one tool call at a time.

  • A Keycard account. Sign up at console.keycard.ai. This guide creates and activates a policy set, which takes the organization Admin Role or Manager on the Zone (see Roles & Permissions); the account that creates the organization is an Admin.
  • A Linear account. Keycard asks you to authorize Linear the first time you connect. You don’t need to create a Linear OAuth app.
  • Claude Code. Cursor also works; step 5 covers the difference.
  1. Add Linear from the Catalog

    In Console, click Resources, then Add Resource → Explore Resources. Search for Linear and pick Linear MCP. Skip Linear API, which asks for your own Linear OAuth app.

    The setup screen has nothing to fill in. Click Continue with Linear MCP, and Console opens the new Resource when it’s ready.

    The install adds two Resources and a Provider, Linear (MCP). Linear MCP Server stands for Linear’s own MCP endpoint, https://mcp.linear.app/mcp, and carries what Keycard needs to get a Linear credential for it. Linear MCP Proxy, the one Console opens, is a Keycard endpoint for connecting a client to Linear alone. This guide uses Linear MCP Server, so skip the claude mcp add command on the Proxy’s banner: step 5 gives you the gateway’s.

  2. Create a gateway

    Click Applications, then Add Application. Enter study-group-tools as the Name and turn on Proxy MCP Tools below it. The form now shows an optional MCP servers picker. Leave it empty, since you add Linear in the next step, and click Create application.

    A gateway is an Application with its own MCP URL. Clients connect to the gateway, and it forwards each call to the MCP server that owns the tool. The name becomes part of that URL, so you can’t change it later.

  3. Put Linear behind the gateway

    Console opens the gateway on its MCP Servers tab. Click Add MCP Server, select Linear MCP Server, and click Connect.

    The gateway now serves Linear’s tools under a linear__ prefix, such as linear__list_issues and linear__save_issue, so tools from different servers never collide.

  4. Refuse one tool with a policy

    Your Zone starts with a managed policy set, default-zone-policies, that lets every signed-in User call every tool. You can’t edit a managed set, so copy it and add one rule to the copy:

    1. Click Policies and note the Version on the default-zone-policies card; you’ll need it to go back. Open the card’s menu, click Duplicate, and confirm with Duplicate. Console names the copy default-zone-policies-copy and opens it.
    2. In the Add policy… field, choose Create new policy, name it linear-no-issue-writes, and click Add to set.
    3. Switch the policy’s editor to Cedar, replace its contents with the policy below, and click Validate.
    4. Click Save in the bar at the bottom and confirm. Then click Activate and confirm.
    forbid (
    principal is Keycard::User,
    action == Keycard::Action::"mcp::tools/call::save_issue",
    resource
    ) when {
    resource.identifier == "https://mcp.linear.app/mcp"
    };

    The action is mcp::tools/call:: followed by the tool name exactly as Linear publishes it. save_issue is the tool that creates and updates issues. Use the bare name, not the linear__ name the gateway shows clients.

  5. Connect Claude Code to the gateway

    Open the gateway again (Applications → study-group-tools). Click Add to Coding Agent → Claude Code, keep the User scope, and run the command Console shows:

    Terminal window
    claude mcp add --transport http --scope user study-group-tools <mcp-access-url>

    <mcp-access-url> is the gateway’s MCP Access URL, shown in its page header.

    Start claude, run /mcp, select study-group-tools, and choose Authenticate. In the browser, sign in to Keycard and follow the prompts, including authorizing Linear: approve Keycard, then pick the Linear workspace to connect. Back in Claude Code, /mcp lists the gateway’s linear__ tools.

  6. Try a read, then a write

    If /mcp also lists another Linear connection, such as a claude.ai Linear connector, disable it there for this test, so Claude can’t reach Linear around the gateway. Then ask Claude:

    Using study-group-tools, list my five most recently updated Linear issues.

    Claude should call linear__list_issues and get your issues back. If Claude Code asks permission to use a tool, allow it. This step tests Keycard’s decision, not Claude’s.

    Now ask for a write:

    Using study-group-tools, create a Linear issue titled “Reserve the study room for Tuesday”.

    Claude may look up your teams first, and those reads succeed. The linear__save_issue call doesn’t. Keycard refuses it before it reaches Linear, and Claude Code reports the call as an error (Error POSTing to endpoint) whose message includes:

    access denied by policy for https://mcp.linear.app/mcp

    No issue is created.

  7. See both decisions

    In Console, click Policies, then the Activity tab. Keycard records each call through the gateway as a policy evaluation, often as more than one row. Find an Allow row for list_issues and a Deny row for save_issue. Click the Deny row: under Decision, Policy set names default-zone-policies-copy, and Determining policies lists linear-no-issue-writes.

You signed in to your Zone as a User, and Claude Code received a token for the gateway. It never received a Linear token. The gateway is an Application, and Linear is a Resource it depends on.

On every tool call, the gateway asks Keycard for a Linear credential for that call, naming the tool it’s about to run. Keycard evaluates the Zone’s active policy set against who is asking (you, and the gateway acting for you), which Resource the call is for, and which action it is (mcp::tools/call::<tool>). On allow, Keycard issues the credential and the gateway forwards the call. On deny, no credential is issued and Linear never sees the request. Either way, the decision is recorded.

Keycard denies anything no policy permits. The managed policies you copied permit signed-in Users everything, and your forbid takes save_issue back out, because a forbid always overrides a permit. A policy change applies from the next call, with nothing to redeploy and nothing to change in Claude Code.

None of this is specific to Linear or to Claude Code. Any MCP server in the Catalog, or one you build and register as a Resource with MCP Server turned on, goes behind a gateway the same way, and any MCP client can use the gateway’s URL.

keycard run starts Claude Code inside a Keycard session and puts credentials from Keycard into the session’s environment. That’s the path for MCP servers that don’t use a standard OAuth sign-in: servers that take an API key or token in a header, or local servers that read one from the environment. The server reads the credential from the session, so it starts already signed in.

An MCP server that uses standard OAuth, such as a Catalog MCP install or the gateway above, doesn’t need the CLI. Claude Code registers itself with the server and signs you in through the browser, so the connection needs no credential from keycard run. Use the gateway path for those.

  1. Install the CLI and its Claude Code plugin

    In the root of your project, run:

    Terminal window
    brew install keycardai/tap/keycard
    keycard plugin install claude

    Claude Code turns the plugin on for that directory only. The plugin adds Skills Claude uses to work with Keycard from inside the session.

  2. Sign in

    Terminal window
    keycard auth signin --org <org-id> --zone <zone-id>

    Both IDs are under Settings → Connection in Console.

  3. Name the credentials the session needs

    In a keycard.toml at the project root, map each environment variable to the Keycard Resource that fills it:

    [org]
    id = "<org-id>"
    [zone]
    id = "<zone-id>"
    [[credentials.default]]
    env_var = "LINEAR_API_KEY"
    resource = "<linear-api-key-resource>"

    resource is the Identifier of the Keycard Resource that holds the credential. If you don’t have one for your Linear API key yet, register it as in Add a custom resource, with any URN as its Identifier (for example urn:linear:api-key): choose Zone Vault Provider as its Credential Provider, then add the key on its Credentials tab with Add credential.

    With [org] and [zone] set, you can leave the flags off keycard auth signin.

  4. Pass the credential to the MCP server

    In the project’s .mcp.json, reference the variable in the server’s header. Claude Code expands ${VAR} from its environment when it starts:

    {
    "mcpServers": {
    "linear": {
    "type": "http",
    "url": "https://mcp.linear.app/mcp",
    "headers": {
    "Authorization": "Bearer ${LINEAR_API_KEY}"
    }
    }
    }
    }
  5. Start Claude Code in a Keycard session

    Terminal window
    keycard run claude

    The first run opens a browser so you can grant the CLI consent. The credentials listed in keycard.toml are minted into the session’s environment, and Keycard records the session: open Sessions in Console to see it.

Continue with: