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

# Build an AI Agent

> Use LangGraph and the HoopAI MCP server to build a multi-agent automation system with contacts, conversations, calendars, and more.

Connect any LangGraph agent to HoopAI using the MCP server and the `langchain-mcp-adapters` library. Your agent gets all 36 HoopAI tools automatically — no manual tool wrappers needed.

## Installation

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

## Quickstart

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

async def main():
    async with MultiServerMCPClient(
        {
            "hoopai": {
                "transport": "streamable_http",
                "url": "https://services.leadconnectorhq.com/mcp/",
                "headers": {
                    "Authorization": f"Bearer {os.environ['HOOPAI_API_KEY']}",
                    "locationId": os.environ["HOOPAI_LOCATION_ID"],
                },
            }
        }
    ) as client:
        tools = client.get_tools()
        model = ChatAnthropic(model="claude-sonnet-4-6")
        agent = create_react_agent(model, tools)

        result = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "Show me my last 5 contacts"}]}
        )
        print(result["messages"][-1].content)

asyncio.run(main())
```

Set these environment variables before running:

```bash theme={null}
export HOOPAI_API_KEY=your_private_integration_token
export HOOPAI_LOCATION_ID=your_location_id
export ANTHROPIC_API_KEY=your_anthropic_api_key
```

## Multi-agent architecture

For production use, split tools across specialist agents controlled by a router. This keeps each agent focused and prevents accidental cross-domain actions.

```mermaid theme={null}
flowchart TD
  U[User] --> R[Router Agent]
  R --> C[Contacts Subagent]
  R --> M[Conversations Subagent]
  R --> A[Calendar Subagent]
  R --> O[Opportunities Subagent]
  R --> P[Payments Subagent]

  C --> MCP[(HoopAI MCP)]
  M --> MCP
  A --> MCP
  O --> MCP
  P --> MCP
```

## Specialist subagents

Give each subagent an allowlist of tool names so it can only call the tools relevant to its domain:

```python theme={null}
def make_specialist(client, allowed_tools: list[str], system_prompt: str):
    """Create a specialist agent with a restricted tool set."""
    all_tools = client.get_tools()
    tools = [t for t in all_tools if t.name in allowed_tools]
    model = ChatAnthropic(model="claude-sonnet-4-6")
    return create_react_agent(model, tools, state_modifier=system_prompt)

# Contacts specialist — read/write contacts and tags only
contacts_agent = make_specialist(
    client,
    allowed_tools=[
        "contacts_get-contacts",
        "contacts_get-contact",
        "contacts_create-contact",
        "contacts_update-contact",
        "contacts_upsert-contact",
        "contacts_add-tags",
        "contacts_remove-tags",
        "contacts_get-all-tasks",
    ],
    system_prompt=(
        "You manage contacts. Always confirm before creating or updating records. "
        "Never delete contacts. Return structured summaries."
    ),
)

# Conversations specialist — search and send messages
conversations_agent = make_specialist(
    client,
    allowed_tools=[
        "conversations_search-conversation",
        "conversations_get-messages",
        "conversations_send-a-new-message",
    ],
    system_prompt=(
        "You handle conversations and messaging. "
        "Always confirm the recipient and message content before sending. "
        "Never send bulk messages without explicit user approval."
    ),
)
```

## Recommended subagents

| Subagent          | Tools to include                                     | Guardrails                                        |
| ----------------- | ---------------------------------------------------- | ------------------------------------------------- |
| **Contacts**      | get, search, create, update, upsert, add/remove tags | Confirm before write; never bulk-delete           |
| **Conversations** | search, get messages, send message                   | Validate recipient; confirm before send           |
| **Calendar**      | get events, get appointment notes                    | Require timezone; confirm before booking          |
| **Opportunities** | search, get pipelines, get, update                   | Require reason text for stage/value changes       |
| **Payments**      | get order, list transactions                         | Read-only by default; gate writes behind approval |

## Router pattern

The router classifies intent and delegates to one specialist:

```python theme={null}
ROUTER_PROMPT = """
You are a router. Delegate to exactly one specialist based on the user's intent.
Never call MCP tools directly — only route.

Routing rules:
- Contact lookup, tagging, segmentation → contacts
- Messages, inbox, follow-ups → conversations
- Appointments, scheduling → calendar
- Deals, pipelines, stages → opportunities
- Invoices, transactions, payments → payments

If locationId is missing, ask for it before routing.
If the task is destructive (delete, bulk-update), ask for explicit confirmation first.
"""
```

## Full multi-agent example

```python theme={null}
import asyncio
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage

SPECIALISTS = {
    "contacts": [
        "contacts_get-contacts", "contacts_get-contact",
        "contacts_create-contact", "contacts_update-contact",
        "contacts_add-tags", "contacts_remove-tags",
    ],
    "conversations": [
        "conversations_search-conversation",
        "conversations_get-messages",
        "conversations_send-a-new-message",
    ],
    "opportunities": [
        "opportunities_search-opportunity",
        "opportunities_get-pipelines",
        "opportunities_get-opportunity",
        "opportunities_update-opportunity",
    ],
}

async def run_multi_agent(user_message: str):
    async with MultiServerMCPClient(
        {
            "hoopai": {
                "transport": "streamable_http",
                "url": "https://services.leadconnectorhq.com/mcp/",
                "headers": {
                    "Authorization": f"Bearer {os.environ['HOOPAI_API_KEY']}",
                    "locationId": os.environ["HOOPAI_LOCATION_ID"],
                },
            }
        }
    ) as client:
        all_tools = client.get_tools()
        model = ChatAnthropic(model="claude-sonnet-4-6")

        # Build specialist agents
        agents = {}
        for name, allowed in SPECIALISTS.items():
            tools = [t for t in all_tools if t.name in allowed]
            agents[name] = create_react_agent(model, tools)

        # Router decides which specialist to use
        router_tools = [t for t in all_tools if t.name == "locations_get-location"]
        router = create_react_agent(model, router_tools, state_modifier=(
            "You are a router. Respond with only the specialist name: "
            "contacts, conversations, or opportunities."
        ))

        route_result = await router.ainvoke(
            {"messages": [HumanMessage(content=f"Route this: {user_message}")]}
        )
        specialist_name = route_result["messages"][-1].content.strip().lower()

        agent = agents.get(specialist_name, agents["contacts"])
        result = await agent.ainvoke(
            {"messages": [HumanMessage(content=user_message)]}
        )
        return result["messages"][-1].content

result = asyncio.run(run_multi_agent("Find all contacts tagged as 'New Lead' added this week"))
print(result)
```

## Implementation checklist

* One shared MCP client, reused across all subagents
* Per-subagent tool allowlists
* Approval middleware for write operations
* Log all MCP calls with `locationId`, tool name, timestamp, and status
* Add replay tests for common workflows (contact search, send message, move opportunity)
