MCP deployment
Powerloom deploys Model Context Protocol (MCP) servers as first-class fleet citizens — scoped by organizational unit, audited per tool call, governed by the same RBAC model as agents themselves. This page covers the deployment shape, the template catalog, and how to author your own.
What an MCP deployment is
An MCP server exposes tools to agents. Postgres exposes query and mutate. Slack exposes send_message and read_channel. Files exposes read_file and write_file. The agent calls a tool; the MCP server runs it; the result returns.
In Powerloom, an MCP deployment is the running instance of a server, scoped to an OU. One MCPDeployment resource = one running container = one set of tools available to agents in that scope.
The reconciler manages the lifecycle. You declare the deployment in YAML, apply, and the reconciler stands the container up via Terraform, wires it into your VPC, registers its tools with the control plane, and starts streaming health checks.
Template catalog
Powerloom ships fifteen pre-built templates. Each is a versioned MCP server image with a defined tool surface, parameter schema, and credential requirements.
| Template | Tools surfaced | Common use |
|---|---|---|
postgres | query, mutate, describe_schema | Agent reads or writes a customer database |
slack | send_message, read_channel, search | Notifications, triage agents |
github | list_issues, comment, create_pr, list_files | Code review, issue triage |
jira | list_tickets, create_ticket, transition, comment | Engineering workflow agents |
files | read, write, list, search | Document agents over a shared filesystem |
gmail | send, list, read, search | Outbound communication agents |
s3 | get_object, put_object, list_objects | Asset pipelines |
confluence | read_page, create_page, search | Knowledge agents |
linear | list_issues, create_issue, update_status | Issue tracker agents |
notion | read_page, create_page, query_database | Knowledge agents over Notion |
bigquery | query, describe_table | Analytics agents |
stripe | list_charges, refund, lookup_customer | Finance ops agents |
hubspot | lookup_contact, update_deal, create_note | CRM agents |
datadog | query_logs, query_metrics, list_alerts | SRE agents |
pagerduty | list_incidents, acknowledge, escalate | Incident response agents |
Each template has its own parameter schema — the Postgres template needs a connection string, the GitHub template needs an installation ID, etc. weave describe template/<name> shows the full schema.
Declaring a deployment
apiVersion: powerloom/v1
kind: MCPDeployment
metadata:
name: support-postgres
scope_ou_path: /acme/support
template: postgres
parameters:
connection_string_credential_ref: cred:/acme/support/support-readonly-db
schema: public
description: Read-only access to the support database
Three things are happening here:
-
The deployment lives at
/acme/support. Only agents in that OU or deeper can reach it. An agent in/acme/engineeringcannot call its tools, even though the deployment exists in the same organization. -
The connection string is referenced, not embedded.
connection_string_credential_refpoints at aCredentialresource. Powerloom never sees the raw value — it's stored as wrapped ciphertext under your tenant KMS key, decrypted only inside the MCP container at request time. -
The template determines the tool surface.
postgresexposesquery,mutate, anddescribe_schema. The deployment automatically registers these with the control plane on standup; agents in scope can call them.
weave apply -f deployment-postgres.yaml. The reconciler stands the container up (typically 30-60 seconds for the first deployment of a template, faster on subsequent ones). When status flips to healthy, the tools are live.
Scoping who can use it
By default, every agent in the same OU or below can call every tool the deployment exposes. To restrict further, write a per-tool RBAC binding:
apiVersion: powerloom/v1
kind: RoleBinding
metadata:
principal_ref: agent:/acme/support/triage-bot
role: ToolUser
scope_resource: mcp-deployment:/acme/support/support-postgres
decision_type: allow
conditions:
tool_names: [query, describe_schema] # mutate excluded
The triage bot can read; it cannot write. The mutate tool stays unavailable to it even though the deployment exposes it. Other agents in the OU still have full access unless similarly narrowed.
For mutations specifically, a common pattern is to require a second approver:
apiVersion: powerloom/v1
kind: ApprovalPolicy
metadata:
name: postgres-mutate-requires-approval
scope_ou_path: /acme/support
resource_kind: mcp-tool-call
resource_match:
tool_name: mutate
deployment: support-postgres
approver_role: OUAdmin
ttl_seconds: 3600
Now any agent calling mutate on the support-postgres deployment lands in pending until an OUAdmin signs off. The audit trail records the request, the approver, the comment, and the eventual decision.
Health and observability
/mcp in the console shows every deployment in your org with its current status: pending, provisioning, healthy, degraded, failed. Click any deployment to see its tool list, recent invocations, and error rate.
The reconciler runs a health probe every 30 seconds. A degraded deployment fires a deploy_failed notification (per Phase 34) — owners get an in-app card, an email, and a push if they've opted in.
For raw observability — every tool call payload, every agent that invoked it, every result — see the audit log at /audit. Filter by resource_kind=mcp-tool-call and the deployment name.
Authoring custom templates
If none of the fifteen catalog templates fit, write your own. A custom template is:
- A container image that implements the MCP protocol (see modelcontextprotocol.io for the spec).
- A
MCPTemplatemanifest that declares its tool surface, parameter schema, and image reference.
apiVersion: powerloom/v1
kind: MCPTemplate
metadata:
name: internal-orders-api
display_name: Internal orders API
image: ghcr.io/acme/orders-mcp:1.4.2
parameter_schema:
type: object
required: [api_token_credential_ref, base_url]
properties:
api_token_credential_ref: { type: string, format: credential-ref }
base_url: { type: string, format: uri }
tool_schema:
- name: lookup_order
input_schema: { ... }
- name: refund_order
input_schema: { ... }
Apply the template once per environment. From then on, deployments reference it by template: internal-orders-api like any catalog template.
What this doesn't do
Powerloom doesn't proxy or rewrite tool payloads — when an agent calls query on the Postgres deployment, the SQL goes straight to your database. We govern who can call which tool and log what happened; we don't sit between the agent and the tool's runtime semantics.
Result handling, retry policy, and timeout behavior live in the MCP server image itself. If you need different policy than a template ships with, write a custom template that wraps it.