Agent Deployment
This guide covers agents and automated clients that run unattended. For interactive clients like Claude Desktop or Cursor, see the Supported Clients page.
Overview
Agents — autonomous AI systems, workflow automations, and custom applications — connect to Civic the same way interactive clients do, but typically need tighter controls. Unlike a human user who can switch toolkits or approve actions on the fly, agents should stay focused on their assigned task.
This page covers the configuration options that matter most for agent deployments: profile locking, skills, and URL parameters.
Connection URL
All agents connect to the same base URL:
https://app.civic.com/hub/mcp
Query parameters
| Parameter | Type | Description |
|---|---|---|
accountId | string | Your Civic account ID (for multi-account users) |
profile | string | Toolkit alias to use (e.g. support, marketing) |
lock | "true" | "false" | Lock the session to the specified toolkit (default: true when a profile is set) |
skills | string | Comma-separated list of skill aliases to load |
Example URLs
# Use the "sales-agent" toolkit, locked (default)
https://app.civic.com/hub/mcp?profile=sales-agent
# Use the "assistant" toolkit but allow the AI to switch
https://app.civic.com/hub/mcp?profile=assistant&lock=false
# Specify a toolkit and load additional skills
https://app.civic.com/hub/mcp?profile=support&skills=escalation,triage
# Use a specific organization account
https://app.civic.com/hub/mcp?profile=ops&accountId=org_abc123
Profile locking
When you specify a toolkit in the connection URL, the session is locked to that toolkit by default. This is a safety and predictability feature designed for agent deployments.
What locking does
When a toolkit is locked:
- The
switch_profiletool is hidden — it doesn't appear in the AI's tool list - Toolkit switching is blocked — if the AI attempts to call it anyway, it receives an error
- Guardrail management is disabled — the AI cannot modify its own safety constraints
- Credential access is restricted — only credentials explicitly assigned to the profile are discovered. Unassigned credentials are invisible to locked profiles, even if they would match. (Unlocked profiles discover all matching credentials regardless of assignment.)
- The lock persists for the entire session
When a locked profile needs a credential that exists but isn't assigned, the system will not prompt for fresh authentication. Instead, it returns a message asking an account admin to assign the credential to the profile. See credential resolution for details.
Why locking is the default
Agents typically serve a specific purpose. If you deploy a customer support agent using the support toolkit, you don't want a prompt injection or unexpected user request to cause it to switch to a billing toolkit with different tools and permissions.
Locking enforces a "stay in your lane" semantic — the AI can only use the tools in the toolkit it was given.
Unlocking with lock=false
Add lock=false to the connection URL to allow the AI to switch toolkits during the session:
https://app.civic.com/hub/mcp?profile=default&lock=false
When unlocked:
- The
switch_profiletool is available to the AI - The AI can see all available toolkits on the account
- The AI (or the user) can switch between toolkits during the conversation
- Guardrail management tools become available — the AI can modify or remove its own safety constraints
Security risk: An unlocked agent can remove its own guardrails, switch to toolkits with broader permissions, and access tools it was not originally intended to use. Only use lock=false when you trust the environment — for example, interactive sessions with a human in the loop. Never unlock agents that are user-facing or exposed to untrusted input.
When to use each
| Scenario | Recommendation |
|---|---|
| Single-purpose agents (support bots, data pipelines) | Locked (default) — keep the agent focused |
| Interactive assistants where users need flexibility | Unlocked (lock=false) — let users switch contexts |
| User-facing agents where security matters | Locked (default) — prevent toolkit escape |
| AI that needs to discover the right toolkit for a task | Unlocked (lock=false) — allow exploration |
Quick reference
| Toolkit specified? | lock parameter | Result |
|---|---|---|
| No | Any | Unlocked (no toolkit to lock to) |
| Yes | Omitted | Locked (default) |
| Yes | lock=true | Locked |
| Yes | lock=false | Unlocked |
When is a profile automatically locked?
In addition to the lock URL parameter, profiles are automatically locked in these scenarios:
| Scenario | Lock behavior |
|---|---|
civic_profile claim in JWT token | Always locked |
END_USER role | Always locked (cannot be overridden) |
Tokens issued via token exchange with a civic_profile claim always result in a locked profile. Credentials authenticated through a profile-scoped token are automatically assigned to that profile.
Skills
You can pre-load skills into an agent session using the skills query parameter. Skills are reusable AI capabilities that encode business knowledge and workflows.
https://app.civic.com/hub/mcp?profile=support&skills=escalation,canned-responses
Skills are resolved from SKILL-type profiles on the account. If a skill alias doesn't match any profile, it is silently ignored.
Authentication
Agents typically authenticate with a Civic token (a bearer token you generate once and pass as an environment variable). Interactive clients embedded in user-facing apps can also use OAuth.
Civic Token (recommended for agents)
Generate a Civic Token
- Log in to app.civic.com
- Click your account name in the bottom left
- Go to Install → MCP URL
- Click Generate Token and copy it immediately — it won't be shown again
Never commit your token to source control. Store it in environment variables or a secrets manager. Tokens expire after 30 days.
Set Environment Variables
CIVIC_TOKEN=your-civic-token-here
CIVIC_URL=https://app.civic.com/hub/mcp
For production agents, lock to a specific toolkit by appending a profile parameter:
CIVIC_URL=https://app.civic.com/hub/mcp?profile=your-toolkit-alias
Use the Token
Pass the token as a Bearer token in the Authorization header:
headers = {"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"}
headers: { Authorization: `Bearer ${process.env.CIVIC_TOKEN}` }
Token generation, URL parameters, OAuth vs token comparison
Minimal connection examples
import os
headers = {
"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}",
"Content-Type": "application/json"
}
url = os.environ["CIVIC_URL"] # https://app.civic.com/hub/mcp?profile=your-toolkit
const headers = {
Authorization: `Bearer ${process.env.CIVIC_TOKEN}`,
};
const url = process.env.CIVIC_URL; // https://app.civic.com/hub/mcp?profile=your-toolkit
For agents embedded in user-facing apps, use the MCP authorization spec. The Hub implements standard OAuth 2.0 — your client initiates the flow and receives a session token automatically. No manual token management required.
See the MCP authorization spec for details.
Best practices
Lock toolkits in production
Always lock toolkits in production agent deployments. This prevents the AI from switching to unintended toolkits and ensures predictable behavior.
Create dedicated toolkits for agents
Don't reuse your interactive toolkits for agents. Create purpose-built toolkits with only the tools the agent needs. This follows the principle of least privilege and reduces AI confusion from having too many tools.
Use guardrails
Apply guardrails to agent toolkits to constrain tool usage. For example, make a support agent's email tool read-only, or block destructive database operations.
Monitor with audit logs
All tool calls made by agents are logged. Use audit logs to verify agents are behaving as expected and to debug issues.
Resources
Set up a focused toolkit for your agent
Generate authentication tokens for agents
Constrain tool usage for safer agent deployments
Ask questions in our developer Slack
Framework-Specific Guides
Python agents using MultiServerMCPClient with streamable_http transport
Native MCP connector via the Anthropic Messages API
hostedMcpTool() for zero-boilerplate agent setup
Function calling with full control over the tool loop
Next.js streaming apps with MCP tool integration
Pydantic AI agents with MCPServerStreamableHTTP
Direct Python MCP client + adapters