Skip to main content

LangChain.js / LangGraph

Connect a LangGraph agent to Leadovaro using @civic/mcp-client with the built-in LangChain adapter. The adapter returns DynamicStructuredTool instances ready to drop into createReactAgent, the legacy AgentExecutor, or any custom LangGraph graph.

Prerequisites​

  • Node.js 20+
  • A Leadovaro account at app.leadovaro.com with a configured toolkit
  • A Leadovaro token and an LLM API key (e.g. Anthropic or OpenAI)

Installation​

pnpm add @civic/mcp-client @langchain/core @langchain/anthropic @langchain/langgraph

Environment Variables​

LEADOVARO_TOKEN=your-leadovaro-token
ANTHROPIC_API_KEY=your-anthropic-key
LEADOVARO_PROFILE_ID=your-profile-id # optional: lock agent to a specific toolkit
Get Your Credentials

How to generate a Leadovaro token and configure toolkit URL parameters

Connecting to Leadovaro​

Use LeadovaroMcpClient with langchainAdapter() to get tools, then pass them to createReactAgent:

import { LeadovaroMcpClient } from "@civic/mcp-client";
import { langchainAdapter } from "@civic/mcp-client/adapters/langchain";
import { ChatAnthropic } from "@langchain/anthropic";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const client = new LeadovaroMcpClient({
auth: { token: process.env.LEADOVARO_TOKEN! },
});

const tools = await client.getTools(langchainAdapter());

const agent = createReactAgent({
llm: new ChatAnthropic({ model: "claude-sonnet-4-6" }),
tools,
});

Running the Agent​

async function main() {
const result = await agent.invoke({
messages: [{ role: "user", content: "What events do I have today?" }],
});

console.log(result.messages.at(-1)?.content);
await client.close();
}

main().catch(console.error);

Production Configuration​

Lock to a Toolkit​

For production agents, scope to a specific profile:

const client = new LeadovaroMcpClient({
auth: { token: process.env.LEADOVARO_TOKEN! },
leadovaroProfile: process.env.LEADOVARO_PROFILE_ID,
});

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-Turn Conversations​

Pass a checkpointer to createReactAgent to retain conversation history across invocations:

import { MemorySaver } from "@langchain/langgraph";

const agent = createReactAgent({
llm: new ChatAnthropic({ model: "claude-sonnet-4-6" }),
tools,
checkpointer: new MemorySaver(),
});

const config = { configurable: { thread_id: "session-1" } };

const result = await agent.invoke(
{ messages: [{ role: "user", content: "What events do I have today?" }] },
config
);

Next Steps​