LangGraph setup

LangGraph support uses an adapter over the same REST/MCP tool registry used by other Slab5 agent clients.

Adapter model

The adapter should not introduce separate business logic. It should map LangGraph tool calls to Slab5's permissioned tool registry.

Install

Install LangGraph and an MCP adapter in the application that owns the graph runtime:

Node.jsbash
npm install @langchain/langgraph @langchain/core
npm install @modelcontextprotocol/sdk

For Python graph runtimes:

Pythonbash
pip install langgraph langchain-mcp-adapters

Runtime config

Keep the workspace token in the graph runtime environment. For controlled testing, use an MCP token created from the personal workspace. Do not put the token in graph state, logs, checkpoints, or prompts.

Environmentbash
SLAB5_MCP_URL=https://mcp.slab5.com/v1
SLAB5_WORKSPACE_TOKEN=slab5_personal_workspace_mcp_token

Recommended production scopes for a lead-intake graph:

crm:read
crm:write
tasks:write
activity:write

For OAuth-based graph access, use the workspace-scoped MCP server URL and grants from the MCP Clients page.

Tool mapping

LangGraph nodes should call the same tool definitions used by MCP:

  • create_contact
  • search_contacts
  • create_task
  • log_activity
  • get_workspace_summary

Each node should pass a workspace-scoped token and preserve the Slab5 request_id in graph state for debugging.

Example Python adapter shape:

Adapterpy
import os
from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient(
    {
        "slab5": {
            "url": os.environ["SLAB5_MCP_URL"],
            "transport": "streamable_http",
            "headers": {
                "Authorization": f"Bearer {os.environ['SLAB5_WORKSPACE_TOKEN']}"
            },
        }
    }
)

slab5_tools = await client.get_tools()

Bind only the tools the graph needs:

Tool filterpy
lead_intake_tools = [
    tool
    for tool in slab5_tools
    if tool.name in {"search_contacts", "create_contact", "create_task", "log_activity"}
]

Example node flow

lead_intake_node
  -> search_contacts
  -> create_contact if no match
  -> create_task
  -> log_activity
  -> return request IDs

The graph should treat Slab5 as the stateful system of record, not as a reasoning engine.

Contract rules

  • Validate inputs against mcp-tools.json before calling Slab5.
  • Reuse idempotency keys when retrying write nodes.
  • Store request IDs in graph state.
  • Map Slab5 structured errors into recoverable graph branches.
  • Keep the adapter over the same REST/MCP contract; do not fork schemas.

Was this page helpful?