Skip to main content

Outcome

Your agent’s template carries every credential, MCP server and repository the agent needs, and a session launched from it can reach those systems with the least access that still does the job. You know how to check that a tool made it into the snapshot instead of finding out mid-run.

Decide

The agent never holds tools directly. It points at a template through Default template, and the template is the capability container: tool providers, MCP servers, secrets, repositories, and the context and guardrails covered on the neighbouring pages. Answer these before adding anything. Which systems must the agent read, and which must it never write?
  • Bad: “Give it our Stripe key and the production database URL.”
  • Good: “Stripe with a restricted key limited to read on charges, disputes and refunds. Postgres through the support_readonly role that can only see the payments schema views. Zendesk with an agent-level token. Nothing that can move money.”
Provider or MCP server?
  • A tool provider stores credentials and hands them to the sandbox as environment variables or files, optionally installing a CLI. The agent then uses the vendor’s API, CLI or SDK like an engineer would. Choose this when the vendor has a good API or CLI and you want the agent to write its own queries.
  • An MCP server exposes a fixed set of typed tools to the harness. Choose this when the vendor ships an MCP server you trust, or when you want to constrain the agent to a small tool surface.
  • Bad: “Add both, the agent will figure it out.”
  • Good: “Stripe as a provider because the runbook uses the Stripe CLI for timeline reconstruction. Notion as an MCP server because we only want search and read_page.”
How should the agent reach the vendor? Pick the first surface that covers everything the job needs, and design the provider around it:
  1. CLI. Use the vendor CLI if it covers the job. Declare it as a package on the provider and mise installs it into the snapshot. npm: and github: specs cover most vendors, including CLIs that only ship as GitHub release binaries. A CLI is documented, has --help for the agent to read, and returns structured output.
  2. SDK. If the CLI is missing or incomplete, use the vendor’s SDK from a short script. Install it as a provider package when it ships one (for example an npm: spec), or from the repo’s own dependencies.
  3. API. If there is no usable SDK, call the HTTP API directly with the credential the provider puts in the environment.
  4. Browser. Only as a last resort, when the vendor has no programmatic access at all, use a browser auth method. A person logs in once in a remote browser, the session is saved as Playwright storage state, and the agent drives the web UI with it. This path is the slowest and the most brittle, and it breaks whenever the vendor changes its UI or expires the session.
  • Bad: “Use the browser for Stripe, it’s what the team does by hand.”
  • Good: “Stripe CLI via github:stripe/stripe-cli for disputes and events, the Python SDK for the one report the CLI lacks, and no browser.”
Who else in the org gets these credentials?
  • Default to an agent-scoped connection: it is used only when a session runs as that agent, it skips the skill filter, and rotating it touches one agent. Use a personal connection only when the work must act as a person, and an org-wide one only when many agents genuinely share one read-only credential.
  • An org-scoped connection is available to every template whose skills ask for it. A personal connection is available only to that person’s private sessions: their DMs with an agent and the sessions they open from the dashboard. An agent-scoped connection is available only when a session runs as that agent.
  • Bad: “Org-scoped Snowflake with the analytics service account, we already have it.”
  • Good: “Agent-scoped Snowflake connection for the risk agent using a role that can read fraud.alerts and fraud.attempts.”

How tools reach a session

The Tools and MCP tab of the Context page listing connected tools and MCP servers

Settings > Context > Tools & MCP lists tool providers and MCP servers side by side.

Two mechanisms feed capabilities into a session, and they are attached differently. The important consequence: connecting a tool provider does not by itself give any template access to it. The filter that decides which org or personal connections a session receives is the union of requires.integrations across the skills attached to that template. Agent-scoped connections are exempt because binding a connection to one agent is already the narrowest possible intent. If a template has no skill that requires a provider, the connection is silently left out.

Definition, connection, attachment

Every integration is three separate objects, and only one of them ever holds a secret. Creating a definition attaches it nowhere, and attaching it grants no credentials.

Credentials go to Runtime, never to an agent

A connection is the only object that holds a secret, so it is the one step an agent must not do for a person. A coding agent (or a Runtime agent) setting up an integration builds the definition and the attachment, then hands the person a link to create the connection themselves. The secret goes from the person’s browser straight to Runtime, where it is stored encrypted. It never appears in a chat, a prompt, a transcript, a shell history or a repo.
  • Bad: “Paste your Stripe key here and I’ll run runtm-api tools create for you.”
  • Good: “The Stripe provider is created and required by the refund-investigation skill. Open this link to add the key: https://app.runtm.com/connect?provider=stripe&scope=agent&agent=<agent_id>.”
The /connect link opens Settings > Context > Tools & MCP with the provider selected and its connect dialog open and filled in. If the provider is a catalog provider the org has not added yet, the link adds it first. If the person is signed out, they go back to the link after signing in. Pass agent=<agent_id> whenever the connection is for a roster agent, which should be almost always. Use scope=personal or scope=org only when the job requires it. The link opens in the person’s active organization, so hand it to someone who is working in the right org. It only fills in the form. The person still picks the credential, confirms any sharing warning, and clicks connect. MCP server connections have no link yet: send the person to the server under Tools & MCP and ask them to click Add connection. runtm-api tools create --credentials exists for scripts a person runs themselves, such as CI or a bootstrap script reading from a secret manager. It is not for an agent relaying a secret it was handed.

Who the agent acts as: the credential hierarchy

Every connection, whether it belongs to a tool provider or to an MCP server, lives at exactly one of three scopes. Together they form a tree with the organization at the root. Start every roster agent’s tools at agent scope. Reach for personal when the work must be attributed to a person, and for org-wide only when a separate credential per agent is not practical. Each level has its own colour: the organization is black, agents are violet, tools are green, people are amber. Solid nodes hold a credential. Dashed nodes hold none. The root holds the org-wide connections: a restricted read-only Stripe key and a read-only Snowflake role. For a run of an agent that touches a tool, start at that agent’s tool node: if it is solid, the agent credential is used. Otherwise, only in a DM, if the person’s leaf under it is solid, their personal credential is used. Otherwise the org-wide credential at the root is the floor.

How a run picks a credential

When a session starts, Runtime resolves one connection per provider, walking the tree from the most specific scope outward:
  1. Agent. If the run is attributed to a roster agent and that agent has its own connection for the provider, it wins. Agent connections are never used by runs that are not that agent’s.
  2. Personal, private sessions only. Otherwise, if the session is private (a DM with the agent, or a dashboard session) and its person has a personal connection for the provider, that is used. Team-visible runs skip this step.
  3. Org-wide. Otherwise the org-wide connection is used.
  4. Unmet. If none exists, the provider shows up as an unmet requirement in the session manifest and the run starts without it.
Two facts decide the outcome:
  • Which agent the run belongs to. A Slack mention, a DM, an email, a Linear assignment or a cron tick all run as the agent behind that trigger. A session someone opens from the dashboard runs as no agent, so agent connections never apply to it.
  • Whether the session is team-visible or private. A run the agent does in a shared place (a Slack channel or group DM, an email, a Linear or GitHub trigger, a schedule) is team-visible and acts purely as the agent: agent connection, then org-wide, never anyone’s personal credential. This is the same rule GitHub follows: tagged in a channel, an agent opens pull requests as its own GitHub App bot, and a reviewer agent reviews as its own account. A DM with the agent is private to the person in it, so their personal connections can fill in where the agent has none, and on GitHub their commits are authored as them with the agent as co-author. Slack matches the DM sender to a Runtime account by email; a sender with no account falls back to the trigger’s service user, which has no personal connections.

The example, run through

Northstar has two agents. Support Agent’s runbook requires zendesk and stripe; Risk Agent’s requires stripe and snowflake. Read the first and third rows together: in #support Ana’s personal Zendesk token is never considered, because the run is team-visible, but in his DM Ben’s personal Snowflake role fills the gap the agent leaves. If the agent must act as itself even in DMs, give it an agent connection for every provider it touches. Read the last row the same way: the org-wide credential is the floor everyone falls back to, so it should be the least privileged one in the tree.

Where each scope is set

  • Org-wide and personal: Settings > Context > Tools & MCP, connect the provider and pick Teams or Personal. Personal connections are visible only to their owner.
  • Agent: in the same connect dialog choose the agent scope and pick the roster agent. Agent connections show the agent’s avatar on the connection row. A /connect link with agent=<agent_id> opens the dialog already on the agent scope with that agent selected.
  • MCP servers follow the same three scopes on their connection rows, with the same agent, then personal, then org order.
Agent connections are the one scope exempt from the skill filter: they reach the agent’s sessions whether or not an attached skill lists the provider in requires.integrations. Org-wide and personal connections still need a skill to ask for them.

Do it

Connect a tool provider

1

Open the catalog

Go to Settings > Context > Tools & MCP and click New tool or MCP server. The chooser asks What do you want to add? Pick Tool for a provider or MCP server for MCP.
Dialog asking what to add, with Tool and MCP server options

Tools and MCP servers are configured differently, so the chooser separates them.

2

Pick a provider from the catalog

Add a provider lists the built-in providers your org has not added yet: BigQuery, Datadog, Google Cloud, Notion, Phone, PostHog, Slack, Trigify and Zendesk. Pick one and click through to the credentials form.
Add a provider dialog showing the built-in provider catalog

The catalog. You fill in credentials after picking.

If the vendor is not in the catalog, create a custom provider instead (next section) and it appears here for everyone in the org.
3

Enter credentials

Fill in the provider’s auth method. Static methods take the fields the provider declares (an API key, a token and email, a service account file). OAuth methods open the vendor’s consent screen. Pick the scope: Personal or Teams.Use the least privileged credential the vendor offers. For Stripe that is a restricted key with read permissions only. For Postgres it is a dedicated read-only role. The agent never needs write access to investigate.
4

Make a skill require it

Open the skill your agent uses (see Skills and runbooks) and declare the provider slug under requires.integrations. Without this the connection is never materialized for the template, unless the connection is agent-scoped.

Create a custom provider

Anything outside the catalog becomes a custom provider. Stripe, Postgres, Snowflake, Intercom, HubSpot, Jira, Sentry, Grafana, MySQL, MongoDB and Airtable have ready-made static schemas that the onboarding flow creates for you when you pick them during Set Up Your First Agent. For other vendors, or when you skipped onboarding, define the provider yourself.
1

Describe the provider

In Tools & MCP, choose Tool, then skip the catalog and define a custom provider. Give it a display name, a category (documents, data, observability, project management, CRM, support, messaging, meetings, sales or custom), a description and a logo URL (--logo on the CLI; the dashboard card is blank without one).
2

Declare the auth method and fields

Add one auth method. Kind static takes user-facing fields (string, secret, multiline, file_contents) and a materialization that maps them to environment variables, files or setup commands. Kind oauth takes authorize and token URLs. Kind browser takes a login URL for a browser-auth flow.A minimal static Stripe provider:
3

Optionally install a CLI

Add binary dependencies to have mise install the vendor CLI into the snapshot. Specs are latest, npm:pkg, github:owner/repo, cargo:crate or ubi:owner/repo. Prefer a CLI whenever it covers the job (see How should the agent reach the vendor?). github: works for vendors that only publish release binaries.
4

Connect it

The provider now appears in Add a provider. Connect it with credentials exactly like a built-in one, then require it from a skill.

Add an MCP server

1

Define the server

In Tools & MCP, choose MCP server. For a local server give a command, ordered arguments and environment variables. For a remote server give the URL and headers, with transport http or sse. The definition is written verbatim into the harness’s MCP configuration at session start.
2

Add a connection for its credentials

Open the server and add a connection. Static kinds are api_token, headers and env. For servers that publish OAuth metadata, use the OAuth flow and the platform discovers the endpoints. Scope the connection to the org, yourself, or one agent. Credentials on a connection are injected at session start and never baked into the template snapshot. Connections are managed in the dashboard and through the /api/agent-directives/{id}/connections endpoints; the CLI does not create them today.
3

Attach it to the template

Attach the server to the agent’s template, to a repo, or org-wide. Then rebuild the template.

Add template secrets

Template editor Secrets tab with environment variables

The template Secrets tab. Values are encrypted at rest and injected into every session.

1

Open the template's Secrets tab

Go to Templates, open the agent’s template and pick Secrets. This tab is admin-only: Secrets are admin-only. Members never see the values.
2

Add variables the environment needs

Add names and values, or paste a .env. Prefer provider connections for anything that identifies a vendor account, and keep template secrets for build-time and environment configuration such as private registry tokens or a base URL.

Attach repositories

Template editor Overview tab for the Support template

A template's Overview: repository and branch, working directory, owning group, services, coding agents and sandbox tier.

Template editor Context tab showing inherited org skills

The template Context tab. Skills, MCP, Docs and Knowledge are inherited from the org and marked Enforced by org.

A template is created From a repository or as a Blank environment. Repository access comes from the org’s GitHub App installation, so install the app on the repos first under Settings > Integrations > GitHub. Linked repos are cloned alongside the primary repo. Repo-scoped skill and MCP attachments follow the repo into any template that includes it.

Build

Every attachment above lands in the snapshot only at build time. After attaching, build once, and rebuild whenever attachments_changed_since_build is true.

Verify

  1. The tool is connected. Under Tools & MCP the provider shows as connected with a healthy status rather than an error.
  2. The template knows about it. The template detail lists the attached skills and MCP servers, and the skill that requires the provider is among them.
  3. The build is current. The template build status is ready and it is not flagged as changed since the last build.
  4. A session sees it. Launch a session from the template and run env | grep <VAR> in the terminal, or runtm-api session exec <session_id> --json -- env. For an MCP server, ask the harness to list its tools.
If step 4 fails while steps 1 to 3 pass, the connection was filtered out. Check that an attached skill requires the provider slug, or scope the connection to the agent.

Gotchas

  • Attached after the last build. Attaching a skill or MCP server does not change the running snapshot. attachments_changed_since_build: true on the template means sessions are still booting the old set. Rebuild.
  • Connected but not required. An org or personal connection reaches a template only when an attached skill lists the provider in requires.integrations. The unmet requirement shows up in the session manifest as a warning and never blocks boot, so the agent starts and then fails when it calls the vendor.
  • Personal key on an org resource. runtm-api tools, mcp and template commands need an org-scoped API key. --org cannot substitute for one. A personal key returns 403 or lists an empty set.
  • MCP server without a connection. The server definition is attached and appears in the harness configuration, but every call fails with an auth error because no connection was added. Add one and check it with the connection’s test action.
  • Write-capable credentials. Nothing in the platform downgrades a credential. If you connect a full-access Stripe key, the agent has full access. Use the vendor’s restricted keys and database roles, then add allowlist rules for defense in depth (see Guardrails and approvals).
  • OAuth providers need the dashboard. runtm-api tools create handles static credentials. OAuth connections are completed in the dashboard because they need a browser. Send the person a /connect?provider=<slug>&method=<oauth_method_id> link (see Credentials go to Runtime, never to an agent).
  • A secret pasted to an agent is already leaked. It is now in the transcript, the session history and possibly the model provider’s logs. Rotate it, then have the person connect the new one through a /connect link.
  • template create --skip-agent implies --build. The clone-only fast path builds immediately, so anything attached afterwards needs a rebuild. Create without --build when you plan to attach first, then build once.
  • Attach merges; --replace overwrites. skills attach and mcp attach add to the existing set. skills import can attach in the same call (--attach-template, --attach-repo, --attach-all); skills create cannot, so create-then-attach is two steps.
  • Templates are not only for coding agents. A support agent’s template may clone no repo at all; it exists to carry skills, MCP servers, credentials and guardrails.