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

# LangChain / LangGraph

> Connect a LangGraph agent to Civic's MCP Hub using streamable HTTP transport

Connect a LangGraph agent to Civic using the `langchain-mcp-adapters` package, which bridges LangGraph's tool interface with Civic's Streamable HTTP MCP transport.

## Prerequisites

* Python 3.11+
* A Civic account at [app.civic.com](https://app.civic.com) with a configured toolkit
* A Civic token (generate from [Install → MCP URL](https://app.civic.com/web/install/mcp-url))
* An LLM API key (e.g. Anthropic)

## Installation

```bash theme={null}
pip install langgraph langchain-anthropic langchain-mcp-adapters
```

## Environment Variables

```bash theme={null}
# Your full Civic toolkit URL (include profile param for production agents)
CIVIC_URL=https://app.civic.com/hub/mcp?profile=your-toolkit

# Civic token generated from app.civic.com → Install → MCP URL
CIVIC_TOKEN=your-civic-token

# Your LLM provider key
ANTHROPIC_API_KEY=your-anthropic-key
```

<Card title="Get Your Credentials" icon="key" href="/civic/quickstart/credentials">
  How to generate a Civic token and configure toolkit URL parameters
</Card>

## Connecting to Civic

Use `MultiServerMCPClient` to connect your agent to the Civic MCP Hub over Streamable HTTP, then pass the discovered tools to your LangGraph graph:

```python theme={null}
import os
from langchain_anthropic import ChatAnthropic
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import MessagesState, StateGraph, START
from langgraph.prebuilt import ToolNode, tools_condition

async def create_agent():
    client = MultiServerMCPClient({
        "civic-nexus": {
            "transport": "streamable_http",
            "url": os.environ["CIVIC_URL"],
            "headers": {"Authorization": f"Bearer {os.environ['CIVIC_TOKEN']}"},
        }
    })
    tools = await client.get_tools()
    model = ChatAnthropic(model="claude-sonnet-4-5").bind_tools(tools)

    def call_model(state: MessagesState):
        return {"messages": [model.invoke(state["messages"])]}

    graph = (
        StateGraph(MessagesState)
        .add_node("agent", call_model)
        .add_node("tools", ToolNode(tools))
        .add_edge(START, "agent")
        .add_conditional_edges("agent", tools_condition)
        .add_edge("tools", "agent")
        .compile(checkpointer=MemorySaver())
    )
    return graph
```

## Running the Agent

```python theme={null}
import asyncio

async def main():
    agent = await create_agent()
    config = {"configurable": {"thread_id": "session-1"}}

    result = await agent.ainvoke(
        {"messages": [{"role": "user", "content": "What events do I have today?"}]},
        config=config
    )
    print(result["messages"][-1].content)

asyncio.run(main())
```

## Production Configuration

### Lock to a Toolkit

For production agents, always lock to a specific toolkit using the `profile` URL parameter:

```bash theme={null}
CIVIC_URL=https://app.civic.com/hub/mcp?profile=your-production-toolkit
```

When a profile is specified, the session is locked by default — the agent cannot switch toolkits or modify its own guardrails. This prevents prompt injection attacks from escaping the defined tool scope.

### Multi-Account Setup

For organization accounts, include the `accountId` parameter:

```bash theme={null}
CIVIC_URL=https://app.civic.com/hub/mcp?profile=support&accountId=org_abc123
```

### Pre-load Skills

Load specific Skills at session start using the `skills` parameter:

```bash theme={null}
CIVIC_URL=https://app.civic.com/hub/mcp?profile=support&skills=escalation,canned-responses
```

## Environment Variable Reference

| Variable      | Description                                                                                     |
| ------------- | ----------------------------------------------------------------------------------------------- |
| `CIVIC_URL`   | Full Civic toolkit URL including profile and any URL parameters                                 |
| `CIVIC_TOKEN` | Civic token from [app.civic.com → Install → MCP URL](https://app.civic.com/web/install/mcp-url) |

## Reference Implementation

A complete reference implementation including a FastAPI chat UI, streaming responses, and production patterns is available at:

[github.com/civicteam/langchain-nexus-reference-implementation](https://github.com/civicteam/langchain-nexus-reference-implementation)

## Next Steps

<CardGroup cols={2}>
  <Card title="Agent Deployment" icon="robot" href="/civic/quickstart/clients/agents">
    Production deployment guide: profile locking, URL params, authentication
  </Card>

  <Card title="Guardrails" icon="shield" href="/civic/concepts/guardrails">
    Constrain what tools your LangGraph agent can use
  </Card>

  <Card title="Audit Trail" icon="list-check" href="/civic/concepts/audit">
    Query what your agent did via Civic Chat
  </Card>

  <Card title="Get Credentials" icon="key" href="/civic/quickstart/credentials">
    Token generation and URL parameter reference
  </Card>
</CardGroup>
