Unified MCP Server with LangChain and LangGraph

Updated:


September 25, 2026

Use the Unified MCP server's 22,566 tools as LangChain tools in LangChain and LangGraph agents

LangChain and LangGraph give you a framework for building AI agents with tools, memory and multi-step workflows. With the official LangChain MCP adapter, every tool exposed by the Unified MCP server becomes a native LangChain tool. Your agents get real-time read and write access to your customers' CRM, ATS, HRIS, accounting, ticketing, file storage, messaging and commerce data, across all of Unified.to's integrations. You don't need custom integration code.

The adapter converts each Unified MCP tool into a LangChain BaseTool. You can pass the tools to create_agent, bind them to any chat model, or run them in a LangGraph ToolNode.

Prerequisites

  • A Unified.to workspace and your workspace API key
  • At least one end-customer connection (for example, a HubSpot or Greenhouse connection), and its connection ID from Connections
  • Python 3.10+ or Node.js 18+

Install

Python

pip install langchain langchain-mcp-adapters langchain-anthropic

TypeScript

npm install langchain @langchain/mcp-adapters @langchain/anthropic

You can use any LangChain-supported model provider. The examples below use Anthropic, but OpenAI, Google, Mistral and others work the same way.

Quickstart (Python)

Connect LangChain to the Unified MCP server with a few lines of code:

import asyncio
import os

from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient

UNIFIED_API_KEY = os.environ["UNIFIED_API_KEY"]
CONNECTION_ID = os.environ["UNIFIED_CONNECTION_ID"]  # end-customer connection


async def main():
    client = MultiServerMCPClient(
        {
            "unified": {
                "transport": "streamable_http",
                "url": f"https://mcp-api.unified.to/mcp?connection={CONNECTION_ID}",
                "headers": {"Authorization": f"bearer {UNIFIED_API_KEY}"},
            }
        }
    )

    tools = await client.get_tools()
    print(f"Loaded {len(tools)} Unified tools")

    agent = create_agent("anthropic:claude-sonnet-4-5", tools)

    result = await agent.ainvoke(
        {"messages": [{"role": "user", "content": "List the 10 most recently updated deals and summarize their stages."}]}
    )
    print(result["messages"][-1].content)


asyncio.run(main())

The tools available depend on the connection's integration and the permissions granted. A CRM connection exposes tools for contacts, companies, deals, and so on. An ATS connection exposes tools for candidates, applications, jobs, and so on.

Quickstart (TypeScript)

import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({
  mcpServers: {
    unified: {
      transport: "http",
      url: `https://mcp-api.unified.to/mcp?connection=${process.env.UNIFIED_CONNECTION_ID}`,
      headers: { Authorization: `bearer ${process.env.UNIFIED_API_KEY}` },
    },
  },
});

const tools = await client.getTools();

const agent = createAgent({ model: "anthropic:claude-sonnet-4-5", tools });

const result = await agent.invoke({
  messages: [{ role: "user", content: "Find open jobs and count applications per job." }],
});
console.log(result.messages.at(-1)?.content);

await client.close();

Authentication

Send the token in the Authorization: Bearer {token} header; the token URL parameter is deprecated. All other options must be sent as URL parameters. See Authentication for full details.

Use caseTokenOther URL parameters
Your backend runs the agent (recommended)Workspace API key, in the Authorization headerconnection={connectionId}
Token is handed to a less-trusted runtime or end userConnection-scoped signed token from get_unified_connection_mcp_url (mode=user), in the Authorization header; works for one connection onlynone
A workspace API key grants access to all of your connections and your Unified.to account. Keep it server-side, send it only in the Authorization header, and never put it in an MCP URL or a client config.

Controlling which tools the agent sees

Agents choose tools more reliably when they see a smaller, focused list, and a shorter list also saves context. Use these server options as URL parameters to shape the tools LangChain loads:

OptionWhat it does
toolsComma-delimited list of tool IDs. Only these tools are exposed.
permissionsComma-delimited list of Unified.to permissions. Only tools allowed by these permissions are exposed. For example, pass read-only permissions for an agent that should never write.
hide_sensitiveHides PII fields (names, emails, telephones, and so on) from results.
url = (
    "https://mcp-api.unified.to/mcp"
    f"?connection={CONNECTION_ID}"
    "&permissions=crm_contact_read,crm_deal_read"
    "&hide_sensitive=true"
)

Using Unified tools in a LangGraph workflow

For more control over agent flow, bind the Unified tools to a model and route tool calls through a LangGraph ToolNode:

from langchain.chat_models import init_chat_model
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.graph import StateGraph, MessagesState, START
from langgraph.prebuilt import ToolNode, tools_condition

client = MultiServerMCPClient(
    {
        "unified": {
            "transport": "streamable_http",
            "url": f"https://mcp-api.unified.to/mcp?connection={CONNECTION_ID}",
            "headers": {"Authorization": f"bearer {UNIFIED_API_KEY}"},
        }
    }
)
tools = await client.get_tools()

model = init_chat_model("anthropic:claude-sonnet-4-5").bind_tools(tools)


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


builder = StateGraph(MessagesState)
builder.add_node("call_model", call_model)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "call_model")
builder.add_conditional_edges("call_model", tools_condition)
builder.add_edge("tools", "call_model")
graph = builder.compile()

result = await graph.ainvoke(
    {"messages": [{"role": "user", "content": "Which candidates applied this week, and for which roles?"}]}
)

Multi-tenant agents

If your product serves many end customers, each customer has their own Unified connection. Create the MCP client per request or session, scoped to the current customer's connection, so an agent can only reach that customer's data:

def unified_client_for(connection_id: str) -> MultiServerMCPClient:
    return MultiServerMCPClient(
        {
            "unified": {
                "transport": "streamable_http",
                "url": f"https://mcp-api.unified.to/mcp?connection={connection_id}",
                "headers": {"Authorization": f"bearer {UNIFIED_API_KEY}"},
            }
        }
    )


async def handle_request(customer, prompt: str):
    tools = await unified_client_for(customer.unified_connection_id).get_tools()
    agent = create_agent("anthropic:claude-sonnet-4-5", tools)
    return await agent.ainvoke({"messages": [{"role": "user", "content": prompt}]})

Because Unified normalizes data across integrations, the same agent code works whether one customer uses Salesforce and another uses HubSpot.

Calling tools directly

Unified tools are standard LangChain tools, so deterministic workflows can call them without an agent:

tools_by_name = {t.name: t for t in await client.get_tools()}
contacts = await tools_by_name["list_crm_contacts"].ainvoke({"limit": 50})

Tool names vary by integration and category. Print [t.name for t in tools] to see what a connection exposes.

Regions

RegionStreamable HTTP endpoint
UShttps://mcp-api.unified.to/mcp
EUhttps://mcp-api-eu.unified.to/mcp
AUhttps://api-au.unified.to/mcp
Use the endpoint for the region where your Unified.to workspace is hosted. A credential works only on its own region's host.

Troubleshooting

  • 401 / unauthorized: Check that the token is a valid workspace API key or a correctly signed end-user token. When you use a workspace API key, make sure the connection parameter is also present.
  • Fewer tools than expected: The tool list reflects the connection's integration, the scopes granted when the customer authorized it, and any tools or permissions filters in the URL.
  • Agent picks the wrong tool: Narrow the tool list with tools or permissions, and describe the task more specifically in your system prompt.
  • Options not applied: Only the token can go in a header. Every other option must be a URL parameter.
Share
All guidesAdvertising Report Metrics by IntegrationATS to Vector DB: How to Power Talent Intelligence with Real-Time DataBuilding AI applications with Unified and LangbaseConcur & Concur (Company) — Connection GuideConfigure Greenhouse Native Candidate WebhooksConnect Amazon Seller Central to Unified.toConnecting BambooHR via OAuth 2Connecting Google Workspace Integrations with a Service AccountCorrect WelcomeKit Scopes for Jungle IntegrationCreating Ads using the Unified Ads APICreating Walmart Items via UnifiedEnd-Users, Integrations, and ConnectionsEnriching Unified Objects with Custom MetadataEnterprise-managed authorization (EMA) with a static keyEnterprise-managed authorization (EMA) with a workspace secretEnterprise-managed authorization (EMA) with Microsoft Entra IDExtended observability — pushing API logs to ClickHouseExtended observability — pushing API logs to Grafana / LokiExtended Observability - Pushing API Logs to your Datadog InstanceFacebook Messenger Webhook SetupFireflies Integration GuideGetting started with WorkableHandling Delegated vs. Application Scopes in Microsoft IntegrationsHiBob & Unified: connection and time off guideHow long are logs retainedHow to access employees and usersHow to add API support for the Create Activity in CrelateHow to Associate a Connection ID with Your End-UserHow to build a Candidate Assessment product withHow to build a candidate sourcing or job board app with Unified.toHow to build a Discord support bot with Unified.to and LangbaseHow to Build a Fintech Application with Unified's Payments APIHow to Build an E-Commerce Product Integration with UnifiedHow to build an invoicing system with Unified.toHow to build Enterprise Search using RAGHow to configure Bullhorn Redirect URI for creating a connectionHow to configure webhooks in HubSpotHow to configure webhooks in Thrive LearningHow to configure webhooks in Toast for UnifiedHow to Connect Anthropic to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Cohere to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Google Gemini to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect LLMs to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect OpenAI to Real-Time SaaS Data with Unified.to MCP ServerHow to Connect Zoom and Zoom PhoneHow to create a Connection In Microsoft TeamsHow to create a token-based connection in HighlevelHow to Create a Unified.to Connection to HighLevelHow to Create a Xero Connection in Unified.toHow to create and configure webhooksHow to create Connection with HubspotHow to customize portal URLs for Stripe and GoCardlessHow to filter webhook eventsHow-to Get a Private Support Channel for Your Unified IntegrationHow to get your 8x8 Connect API Key and Account ID: Step-by-step guideHow to get your ADP Workforce Now Oauth2 client ID, Oauth2 client secret, Oauth2 PEM certificate and Oauth2 private key: Step-by-step guideHow to get your Amazon S3 AWS Region, AWS S3 Key and AWS S3 Secret: Step-by-step guideHow to get your Ashby API Key: Step-by-step guideHow to get your Brex API token: Step-by-step guideHow to get your Bullhorn OAuth2 Client ID, OAuth2 Client Secret, API Username and API Password: Step-by-step guideHow to get your Ceridian Dayforce Username, Password and Client Namespace: Step-by-step guideHow to get your Crelate API key: Step-by-step guideHow to get your Dashlane API Key: Step-by-step guideHow to get your Deel Access Token: Step-by-step guideHow to get your Dialpad API Key: Step-by-step guideHow to get your Discord OAuth 2 credentials and bot tokenHow to get your ELMO client ID and client secret: Step-by-step guideHow to get your Gainsight Client ID, Client Secret and Gainsight API Domain: Step-by-step guideHow to get your Greenhouse API Key and Job board token: Step-by-step guideHow to get your Helpscout API Key: Step-by-step guideHow to get your HiBob Service User ID and Service User Token: Step-by-step guideHow to get your HighLevel API Key and Location ID: Step-by-step guideHow to get your HubSpot developer key and OAuth 2 credentials (Legacy Apps)How to get your Humaans API Key: Step-by-step guideHow to get your iCIMS API Username, API Password and Customer ID: Step-by-step guideHow to get your JobDiva Client ID, Username/email and Password: Step-by-step guideHow to get your Jobvite API Key, API Key Secret and Email: Step-by-step guideHow to get your Lever API Key: Step-by-step guideHow to get your Loxo Agency slug, API Key and Agency ID: Step-by-step guideHow to get your Microsoft Active Directory / Entra ID Client ID, Client Secret and Tenant ID: Step-by-step guideHow to get your Microsoft Azure AD OAuth 2 credentialsHow to get your OAuth 2 credentials for GmailHow to get your OAuth 2 credentials for Microsoft Dynamics 365How to get your OAuth 2 credentials in PipeDriveHow to get your OpenAI API Key: Step-by-step guideHow to get your Paycom SID/Username and Token/Password: Step-by-step guideHow to get your PCRecruiter Username, Password, Database ID, App Key and App ID: Step-by-step guideHow to get your SAP SuccessFactors (OpenID Connect) Username, Password, Client ID, Client Secret, Dependency Name, IAS Host and API URL: Step-by-step guideHow to get your SAP SuccessFactors Username, Company ID, Password and API URL: Step-by-step guideHow to get your Shopify Admin API access token and Store ID: Step-by-step guideHow to get your Wayfair Client ID, Client Secret and Vendor Encrypted Key: Step-by-step guideHow to get your Workable API Token and Subdomain: Step-by-step guideHow to get your yotpo APP Key / Store ID and Secret Key: Step-by-step guideHow to Handle Attachments in Invoice, Bill and Credit MemoHow to migrate or import your integrations into Unified.toHow to obtain your GitHub OAuth2 credentialsHow to Power Claude with Live Customer Data Using Unified MCPHow to receive assessment orders from an ATS withHow to register a Google developer app and get OAuth 2 credentialsHow to register a Salesforce developer app and get OAuth 2 credentialsHow to register a Slack developer account and get OAuth 2 credentialsHow to Register a Workday Developer App and Get OAUTH2 CredentialsHow to Register a Workday Developer App and Get OAUTH2/ SOAP CredentialsHow to Register a ZendeskSell Developer App and Get OAUTH2 CredentialsHow to Register a Zoho Developer App and Get OAUTH2 CredentialsHow to Register an ADP Developer App and Get OAUTH2 CredentialsHow to Register an Atlassian Developer App and Get OAUTH2 CredentialsHow to Register your Facebook OAuth2 ApplicationHow to Register your Google Ads OAuth2 ApplicationHow to Register your MetaAds OAuth2 applicationHow To Request & Write Raw Integration DataHow to Retrieve Microsoft Dynamics 365 Business Central CredentialsHow to set up a custom API URL with a CNAMEHow to set up a HiBob marketplace installHow to Set Up a Microsoft Teams Bot with UnifiedHow to set up and configure NotionHow to set up Google Business Profile API access and get OAuth 2 credentialsHow to Set Up LinkedIn Webhooks with UnifiedHow to set up native webhooks for QuickBooks Online with UnifiedHow to set up Slack webhooks using event subscriptionsHow to set up Telegram (bot) with Unified.toHow to set up your scopes in HubSpotHow to setup a Freshbooks developer appHow to setup a TikTok Shop applicationHow to Setup AWS Assume Role for AWS Secret ManagerHow to setup Oracle JD EdwardsHow to Setup Quickbooks DesktopHow to setup Sage 100 with Unified.toHow to troubleshoot unhealthy connectionsHow to troubleshoot unhealthy webhooksHow to use SCIM with the Unified APIHow to use the Passthrough APIHow to Use Unified.to's Generative AI API with OpenAI and ClaudeHow to use User Provisioning and Verification with UnifiedHow virtual webhook retry and recovery worksIntegration set-up guide for LeverManaging custom validation rules in SalesforceNetSuite Authentication Setup for UnifiedNotice of Deprecation of Fields and Objects (Nov 2025)Oracle HCM / Taleo OAuth Credentials GuideRetrieval-Augmented Generation (RAG)SalesForce (External Client Apps) on Multiple OrganizationsSAML Single-Sign-OnScaling MCP Tools with Anthropic's (& OpenAI's) Defer LoadingSet Environments for your Unified.to WorkspaceSetting up a Slack Bot Connection with Unified.toSetting up OAuth 2 Credentials for Greenhouse's APIsTrello Connection Guide in UnifiedUnderstanding OAuth2 Authorization flowsUnderstanding Response Time Headers in the Unified APIUnified Assessment API: Embed Assessments Inside ATS PlatformsUnified's MCP ServerUnlock real-time data with virtual webhooksUse Unified to sign in your users into your applicationWorkable: Creating candidates and attaching them to jobsWorkday vs Workday Legacy — Why Unified.to Supports BothWorking with hierarchical tree data in Storage, Messaging, and KMS APIs
Are we missing anything? Let us know
Was this page helpful?