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

# AI Integration Prompt

> Copy-paste prompt for AI assistants to connect your agent to Civic — works with Anthropic SDK, OpenAI Agents, LangChain, Pydantic AI, Vercel AI SDK, and more

Use this prompt with your preferred AI assistant (Claude, Cursor, ChatGPT, etc.) to connect your AI agent to Civic. The prompt covers guardrails, audit logging, secret management, and access to 95+ MCP servers.

## How to Use

1. **Copy the prompt below** and paste it into your AI assistant
2. **Tell the assistant** which agent framework you're using (Anthropic SDK, LangChain, OpenAI Agents, etc.)
3. **The assistant will walk you through** setting up your MCP connection with the correct code for your framework
4. **Configure security** at [app.civic.com](https://app.civic.com) — guardrails, toolkits, and audit are managed in the platform, not in code

## Integration Prompt

```
# Civic Hub Integration Prompt — Connect Your AI Agent to Civic

## What is Civic Hub?
Civic Hub is a hosted MCP gateway that sits between your AI agent and 85 real-world tool servers (Gmail, Slack, Google Drive, Salesforce, GitHub, databases, and more). It handles security (guardrails), audit logging, secret management, and instant revocation — all server-side. Your code only needs to establish an MCP connection.

## CRITICAL: What NOT To Do
- Do NOT write custom guardrail code, middleware, or interceptors
- Do NOT create audit logging wrappers around tool calls
- Do NOT implement revocation logic in application code
- Do NOT generate mock Civic classes or decorators
Guardrails, audit, and revocation are configured in the Civic platform (app.civic.com), NOT in code.

## Prerequisites
1. Sign up at https://app.civic.com (free trial: 10,000 credits, 14 days)
2. Complete onboarding: select your AI framework and tools
3. On the Install step, generate a Civic token (best for automation)
4. Copy the MCP URL and token

## Environment Variables
Set these in your project:
```

CIVIC\_URL=[https://app.civic.com/hub/mcp?profile=your-toolkit](https://app.civic.com/hub/mcp?profile=your-toolkit)
CIVIC\_TOKEN=your-token-here

````

## Step 1: Identify Your Framework
Ask the user which agent framework or MCP client they're using, then follow the matching section below.

## Step 2: Connect to Civic Hub

### Anthropic SDK (TypeScript)
```typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();
const response = await client.messages.create(
  {
    model: "claude-sonnet-4-5",
    max_tokens: 1024,
    messages: [{ role: "user", content: "List my upcoming calendar events" }],
    mcp_servers: [
      {
        type: "url",
        url: process.env.CIVIC_URL,
        name: "civic",
        authorization_token: process.env.CIVIC_TOKEN,
      },
    ],
  },
  {
    headers: { "anthropic-beta": "mcp-client-2025-11-20" },
  }
);
````

Note: Use `client.messages.create` (NOT `client.beta.messages`). The parameter is `mcp_servers` (not `tools`). Field is `authorization_token`, not `{ type: 'bearer', token }`.

### OpenAI Agents SDK (TypeScript)

```typescript theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
import { Agent, hostedMcpTool, run } from "@openai/agents";

const agent = new Agent({
  name: "Civic Agent",
  tools: [
    hostedMcpTool({
      serverLabel: "civic",
      serverUrl: process.env.CIVIC_URL,
      authorization: process.env.CIVIC_TOKEN, // plain string, NOT { type: 'bearer', token }
    }),
  ],
});

const result = await run(agent, "List my upcoming calendar events");
```

Note: `openai` is bundled as a dependency of `@openai/agents` — no separate install needed.

### LangChain / LangGraph (Python)

```python theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient({
    "civic": {
        "url": os.environ["CIVIC_URL"],
        "transport": "streamable_http",
        "headers": {"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"},
    }
})

tools = await client.get_tools()
agent = create_react_agent("claude-sonnet-4-5", tools)
result = await agent.ainvoke({"messages": [{"role": "user", "content": "List my calendar events"}]})
```

Package: `pip install langchain-mcp-adapters langgraph`

### Pydantic AI (Python)

```python theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP

civic_server = MCPServerStreamableHTTP(
    os.environ["CIVIC_URL"],
    headers={"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"},
)

agent = Agent("anthropic:claude-sonnet-4-6", mcp_servers=[civic_server])

async with agent.run_mcp_servers():
    result = await agent.run("List my upcoming calendar events")
```

Package: `pip install pydantic-ai`

### Vercel AI SDK (TypeScript)

```typescript theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
import { experimental_createMCPClient as createMCPClient } from "ai"; // use @ai-sdk/mcp for v6+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { anthropic } from "@ai-sdk/anthropic";
import { streamText } from "ai";

const transport = new StreamableHTTPClientTransport(
  new URL(process.env.CIVIC_URL),
  {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.CIVIC_TOKEN}` },
    },
  }
);

const mcpClient = await createMCPClient({ transport });
const tools = mcpClient.tools();

const result = streamText({
  model: anthropic("claude-sonnet-4-5"),
  tools,
  prompt: "List my upcoming calendar events",
});
```

Packages: `pnpm install ai @ai-sdk/anthropic @modelcontextprotocol/sdk`
v6+: import `experimental_createMCPClient` from `"@ai-sdk/mcp"` instead of `"ai"`.

### Any Other Framework (Generic MCP)

```python theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async with streamablehttp_client(
    url=os.environ["CIVIC_URL"],
    headers={"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"}
) as (read, write, _):
    async with ClientSession(read, write) as session:
        await session.initialize()
        tools = await session.list_tools()
        # Use tools with your framework's tool-calling mechanism
```

Package: `pip install mcp`

### Interactive Clients (Claude Desktop, Cursor, VS Code, etc.)

No code needed. Add this MCP URL in your client's MCP settings:

```
https://app.civic.com/hub/mcp
```

A browser window will open for OAuth sign-in. That's it.

## Step 3: Configure Security (In the Platform, Not Code)

After connecting, the developer configures security at app.civic.com:

* **Guardrails**: Block PII, credit cards, prompt injection; redact sensitive data from responses
* **Toolkits**: Group MCP servers into focused profiles (e.g., "support" = Gmail + Slack)
* **Audit logs**: Query what the agent did via Civic Chat
* **Revocation**: Instantly block tools, servers, or entire toolkits

None of this requires application code. It's all managed in the Civic platform.

## Error Handling

When integrating Civic, add handling for these failure cases:

**Authentication failures** — Token expired (30-day expiry) or missing. The MCP client will receive an HTTP 401. Handle by prompting the developer to regenerate the token at app.civic.com.

```python theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null} theme={null}
# Python example
try:
    async with agent.run_mcp_servers():
        result = await agent.run(user_message)
except Exception as e:
    if "401" in str(e) or "Unauthorized" in str(e):
        raise RuntimeError("Civic token expired or invalid. Regenerate at app.civic.com")
    raise
```

**Guardrail blocks** — If a guardrail blocks a tool call (e.g., PII detected in the request), the tool call returns an error response — not a crash. The agent will see the error and can inform the user or try a different approach. No special error handling is needed; the agent handles this naturally.

**No tools returned** — The MCP URL may be missing `?profile=your-toolkit`, or the toolkit has no servers configured. Check `CIVIC_URL` includes the profile parameter.

**Transport mismatch** — Civic uses Streamable HTTP. If you see connection errors, verify your framework is not trying to connect via stdio or plain SSE.

## Common Issues

* **Auth errors**: Token may be expired (30-day expiry). Regenerate at app.civic.com
* **No tools**: MCP URL may be missing `?profile=your-toolkit`. Check the toolkit name
* **Connection errors**: Civic uses Streamable HTTP transport, not stdio or plain SSE
* **Docs**: Full framework guides at [https://docs.civic.com/civic/quickstart](https://docs.civic.com/civic/quickstart)

## All Framework Guides

* Anthropic SDK: [https://docs.civic.com/civic/recipes/anthropic](https://docs.civic.com/civic/recipes/anthropic)
* OpenAI Agents SDK: [https://docs.civic.com/civic/recipes/openai-agents](https://docs.civic.com/civic/recipes/openai-agents)
* OpenAI SDK: [https://docs.civic.com/civic/recipes/openai-sdk](https://docs.civic.com/civic/recipes/openai-sdk)
* LangChain: [https://docs.civic.com/civic/recipes/langchain](https://docs.civic.com/civic/recipes/langchain)
* Vercel AI SDK: [https://docs.civic.com/civic/recipes/vercel-ai-sdk](https://docs.civic.com/civic/recipes/vercel-ai-sdk)
* Pydantic AI: [https://docs.civic.com/civic/recipes/pydantic-ai](https://docs.civic.com/civic/recipes/pydantic-ai)
* Google ADK: [https://docs.civic.com/civic/recipes/google-adk](https://docs.civic.com/civic/recipes/google-adk)
* CrewAI: [https://docs.civic.com/civic/recipes/crewai](https://docs.civic.com/civic/recipes/crewai)
* Full list: [https://docs.civic.com/civic/quickstart](https://docs.civic.com/civic/quickstart)

```
```

## Correct vs. Incorrect Output

After pasting the prompt, review what your AI assistant generates. Here's how to tell if it got it right:

<Tabs>
  <Tab title="Correct">
    ```python theme={null}
    # 5-10 lines: connect to Civic via MCP, pass env vars
    from pydantic_ai import Agent
    from pydantic_ai.mcp import MCPServerStreamableHTTP

    server = MCPServerStreamableHTTP(
        os.environ["CIVIC_URL"],
        headers={"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"},
    )
    agent = Agent("anthropic:claude-sonnet-4-6", mcp_servers=[server])
    ```

    The AI generated an MCP connection. Guardrails, audit, and revocation are handled by Civic server-side. No security code needed in your app.
  </Tab>

  <Tab title="Incorrect — Regenerate">
    ```python theme={null}
    # WRONG: custom guardrail middleware
    class CivicGuardrail:
        def __init__(self, rules):
            self.rules = rules
        def validate(self, request):
            for rule in self.rules:
                if rule.matches(request):
                    raise BlockedRequestError(...)

    # WRONG: custom audit logging
    class CivicAuditLogger:
        def log_tool_call(self, tool, params, response):
            self.db.insert({"tool": tool, "params": params, ...})

    # WRONG: custom revocation
    def revoke_agent_access(agent_id, scope="all"):
        requests.post(f"https://api.civic.com/revoke/{agent_id}", ...)
    ```

    If the AI generates guardrail classes, audit wrappers, revocation handlers, or any Civic-specific middleware — **it hallucinated**. None of this exists. Regenerate with the prompt.
  </Tab>
</Tabs>

## Verify Your Integration

After the AI generates code, check these three things before running:

<Steps>
  <Step title="Environment variables, not hardcoded tokens">
    Confirm `CIVIC_URL` and `CIVIC_TOKEN` are read from `process.env` or `os.environ` — never hardcoded in source. If the AI put a token string directly in the code, move it to `.env`.
  </Step>

  <Step title="Correct transport type">
    Civic uses **Streamable HTTP**, not stdio or plain SSE. Look for `streamable_http`, `StreamableHTTPClientTransport`, or `type: "url"` in the generated code. If you see `type: "stdio"` or a subprocess spawn — that's wrong.
  </Step>

  <Step title="No invented APIs">
    The generated code should only call your framework's standard MCP client methods (e.g., `messages.create`, `hostedMcpTool`, `MCPServerStreamableHTTP`). If it imports from `civic`, `@civic/hub`, or `civic-guardrails` — those packages don't exist.
  </Step>
</Steps>

## What the AI Assistant Will Do

When you use this prompt, the AI assistant will:

1. **Ask which framework** you're using (Anthropic SDK, OpenAI Agents, LangChain, etc.)
2. **Generate the connection code** — typically 5-15 lines to connect to Civic via MCP
3. **Set up environment variables** for your MCP URL and token
4. **Point you to app.civic.com** for guardrail and toolkit configuration

## Supported AI Assistants

This prompt has been tested with:

* **Claude** (Anthropic)
* **Cursor** (with Claude)
* **ChatGPT** (OpenAI)
* **GitHub Copilot Chat**

<Info>
  Make sure your AI assistant has the ability to run terminal commands and edit files in your project.
</Info>
