Skip to main content
This guide builds the core Barndoor workflow as code: an MCP server your organization can reach, a credential connection for it, a registered AI Agent, and an access policy that governs what that agent may do.
Estimated time: 20–30 minutes. Complete Getting Started first — this guide assumes a working provider configuration.

Before You Begin

  • A configured provider "barndoor" block (see Getting Started)
  • An API key for the service your MCP server fronts (this guide uses a non-OAuth server)
  • The catalog slug or name of the MCP server you want to onboard and the name of the agent you want to register — directory entries are looked up by data source, so no IDs need to be copied from the app

Step 1: Onboard the MCP server

If the server is new to your organization, create it from its directory entry. If it was already onboarded in the portal, look it up with a data source instead — don’t manage the same server from both places.
References: barndoor_mcp_server resource, data source, barndoor_mcp_server_directory data source
Server names are unique within an organization (case- and whitespace-insensitively), and destroying a barndoor_mcp_server soft-deletes it: its connections and stored credentials are torn down, and the name is freed for reuse.

Step 2: Connect it tenant-wide

A barndoor_connection stores a service-account-owned credential for the server, so every authorized agent can use it without each user connecting individually:
Reference: barndoor_connection
OAuth servers can’t be connected by Terraform — the interactive browser consent can’t happen inside a declarative apply. Terraform supports the non-OAuth credential providers (api_key, bearer_token, basic_auth, generic); connect OAuth servers in the Barndoor app. Also note: an organization can have at most one tenant-wide connection per server, and changing any credential attribute replaces the connection.

Step 3: Register the AI Agent

Registration attaches the agent’s directory entry to your organization and creates the service account that policies bind to:
References: barndoor_agent, barndoor_agent_directory data source An agent directory entry can have one live registration per organization. To reference an agent registered outside Terraform, use the barndoor_agent data source.

Step 4: Govern access with a policy

The policy is where the three pieces meet: it binds the agent (application_ids) to the server (mcp_server_id) and defines what’s allowed:
Reference: barndoor_policy
Always set actions and roles explicitly on every rule. If you omit either list, the platform API defaults it to ["*"]everything. An “allow” rule you meant to scope narrowly becomes an allow-all. Write ["*"] only when you mean it.

Requiring approval for a tool

A tool can be granted outright or granted subject to user approval. The distinction lives in the action string:
  • tools/call:<tool> — runs without confirmation.
  • tools/call:<tool>:approve — the user approves the specific call before it runs.
A tool listed in no applicable rule is not granted at all.
Use one form per tool, and check the whole rule set before relying on an :approve grant. Where several rules apply to the same principal the most permissive grant wins (tools/call:X beats tools/call:X:approve beats absence), so a broad plain grant elsewhere in the policy silently removes the approval gate you configured here.
Approval prompting happens on Barndoor’s tool-router path. A client connecting straight to the MCP endpoint executes an :approve-only grant without prompting — omit the tool instead if you need it stopped on every path. See Granular Tool Use Confirmations for the behaviour end to end.

Conditional rules

Rules accept an optional condition tree, passed as JSON. Each node has exactly one of expr or a combinator (all / any / none) with of = [...]:
Start new policies in DRAFT (the default), review the result in the Barndoor app under MCP Gateway → Policies, then flip status to ACTIVE in a follow-up apply — the same draft-then-activate flow the portal uses.

Lifecycle notes

  • Destroy archives, it doesn’t delete. Destroying a barndoor_policy moves it to ARCHIVED — the platform’s terminal lifecycle state, kept for audit history. The name is freed for non-archived reuse.
  • mcp_server_id is immutable on a policy; changing it forces a replacement (a new policy is created and the old one archived).
  • Importing existing objects: all four resources support terraform import. Policies, servers, and agents import by ID; connections import by their server ID (or slug). See Best Practices → Importing.

Complete example