> ## Documentation Index
> Fetch the complete documentation index at: https://docs.civic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Deployment

> Connect autonomous agents, automation platforms, and custom applications to Civic

<Note>
  This guide covers agents and automated clients that run unattended. For interactive clients like Claude Desktop or Cursor, see the [Supported Clients](/civic/reference/client-compatibility) page.
</Note>

## 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_profile` tool 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](/civic/reference/authorizations#profile-assignment) 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**

<Note>
  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](/civic/reference/authorizations#locked-profiles-restrict-credential-access) for details.
</Note>

### 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_profile` tool 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

<Warning>
  **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.
</Warning>

### 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) |

<Note>
  Tokens issued via [token exchange](/overview/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.
</Note>

## 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

1. Log in to [app.civic.com](https://app.civic.com)
2. Click your account name in the bottom left
3. Go to **[Install → MCP URL](https://app.civic.com/web/install/mcp-url)**
4. Click **Generate Token** and copy it immediately — it won't be shown again

<Warning>
  Never commit your token to source control. Store it in environment variables or a secrets manager. Tokens expire after 30 days.
</Warning>

### Set Environment Variables

```bash theme={null}
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:

```bash theme={null}
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:

```python theme={null}
headers = {"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"}
```

```typescript theme={null}
headers: { Authorization: `Bearer ${process.env.CIVIC_TOKEN}` }
```

<Card title="Full credentials guide" icon="key" href="/civic/quickstart/credentials">
  Token generation, URL parameters, OAuth vs token comparison
</Card>

### Minimal connection examples

<Tabs>
  <Tab title="Python (token)">
    ```python theme={null}
    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
    ```
  </Tab>

  <Tab title="TypeScript (token)">
    ```typescript theme={null}
    const headers = {
      Authorization: `Bearer ${process.env.CIVIC_TOKEN}`,
    };
    const url = process.env.CIVIC_URL; // https://app.civic.com/hub/mcp?profile=your-toolkit
    ```
  </Tab>

  <Tab title="OAuth (interactive)">
    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](https://modelcontextprotocol.io/specification/2025-03-26/basic/authorization) for details.
  </Tab>
</Tabs>

## Best practices

<AccordionGroup>
  <Accordion title="Lock toolkits in production" icon="lock">
    Always lock toolkits in production agent deployments. This prevents the AI from switching to unintended toolkits and ensures predictable behavior.
  </Accordion>

  <Accordion title="Create dedicated toolkits for agents" icon="toolbox">
    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.
  </Accordion>

  <Accordion title="Use guardrails" icon="shield">
    Apply [guardrails](/civic/concepts/guardrails) to agent toolkits to constrain tool usage. For example, make a support agent's email tool read-only, or block destructive database operations.
  </Accordion>

  <Accordion title="Monitor with audit logs" icon="chart-line">
    All tool calls made by agents are logged. Use audit logs to verify agents are behaving as expected and to debug issues.
  </Accordion>
</AccordionGroup>

## Resources

<CardGroup cols={2}>
  <Card title="Create a toolkit" icon="toolbox" href="/civic/concepts/toolkits">
    Set up a focused toolkit for your agent
  </Card>

  <Card title="Civic tokens" icon="key" href="/civic/concepts/tokens">
    Generate authentication tokens for agents
  </Card>

  <Card title="Guardrails" icon="shield" href="/civic/concepts/guardrails">
    Constrain tool usage for safer agent deployments
  </Card>

  <Card title="Get help" icon="slack" href="https://join.slack.com/t/civic-developers/shared_invite/zt-37tv9fyo7-aDT43mUjOFQwdQFmfZLTRw">
    Ask questions in our developer Slack
  </Card>
</CardGroup>

## Framework-Specific Guides

<CardGroup cols={2}>
  <Card title="LangChain / LangGraph" icon="python" href="/civic/recipes/langchain">
    Python agents using MultiServerMCPClient with streamable\_http transport
  </Card>

  <Card title="Anthropic SDK" icon="message" href="/civic/recipes/anthropic">
    Native MCP connector via the Anthropic Messages API
  </Card>

  <Card title="OpenAI Agents SDK" icon="robot" href="/civic/recipes/openai-agents">
    hostedMcpTool() for zero-boilerplate agent setup
  </Card>

  <Card title="OpenAI SDK (manual)" icon="code" href="/civic/recipes/openai-sdk">
    Function calling with full control over the tool loop
  </Card>

  <Card title="Vercel AI SDK" icon="triangle" href="/civic/recipes/vercel-ai-sdk">
    Next.js streaming apps with MCP tool integration
  </Card>

  <Card title="Python + Pydantic AI" icon="python" href="/civic/recipes/pydantic-ai">
    Pydantic AI agents with MCPServerStreamableHTTP
  </Card>

  <Card title="Civic MCP Client (Python)" icon="python" href="/civic/recipes/civic-mcp-client-python">
    Direct Python MCP client + adapters
  </Card>
</CardGroup>
