Resources

MCP Server Integration

Register remote MCP servers as LLM agent tools via the Model Context Protocol.

Overview

MCP (Model Context Protocol) lets you connect any compliant external server to a chatbot's LLM agent. Once registered, the agent can call the server's tools — order lookups, CRM records, ticketing systems, internal APIs — during a conversation, without you writing custom executor code.

Each chatbot can have multiple MCP servers. During an agent turn the platform calls the server's tools/list endpoint to discover available tools, then dispatches tools/call when the model decides to invoke one. Results flow back to the model as tool outputs before the final reply is composed.

Transport: Streamable HTTP only (current MCP standard). No SSE, no stdio.

Auth: NONE, BEARER, HEADERS. OAuth / Dynamic Client Registration is planned for a future release.


Knowledge Base or MCP?

Both extend what your LLM agent knows or can do — but they serve different needs:

Knowledge BaseMCP Server
Best forAnswering questions from your own contentTaking actions and fetching live data
How it worksRAG — retrieves relevant text chunks and passes them to the modelTool-calling — the model invokes functions on your external server
ExamplesFAQs, product docs, policies, support articlesOrder lookups, CRM queries, booking systems, internal APIs
Data freshnessUpdated when you sync the KBAlways live — data comes from your server at call time
SetupUpload documents or crawl URLs from the dashboardRegister a server URL and credentials here

Use a Knowledge Base when your chatbot needs to answer questions from a fixed body of content. Use an MCP server when your chatbot needs to perform actions or retrieve data that changes in real time.

You can attach both to the same chatbot — the model decides which tool to call based on the user's intent.


Plan limits

MCP access is gated by the mcp_servers_per_chatbot_limit plan feature:

ValueMeaning
0MCP disabled — create/test endpoints return 402
N (positive)At most N MCP servers per chatbot
-1Unlimited

Suggested defaults: FREE=0, STARTER=1, PRO=5, ENTERPRISE=-1.


API reference

All MCP endpoints are scoped to a chatbot:

code
/api/dev/v1/chatbots/{chatbot_id}/integrations/mcp

Authentication: Authorization: Bearer <api-key> on every request.


Register a server

http
POST /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp
Authorization: Bearer <api-key>
Content-Type: application/json

Body

namestringrequired

Label for this server. Used as the tool-name prefix in agent traces (e.g. github__search). Pattern: ^[a-zA-Z][a-zA-Z0-9_\-]*$. No __. Max 100 chars. Must be unique per chatbot.

server_urlstringrequired

HTTPS endpoint of the MCP server.

auth_typestringoptional

One of NONE (default), BEARER, HEADERS.

auth_configobjectoptional

Auth payload — required when auth_type is not NONE. See Auth types below.

descriptionstringoptional

Optional note. Not sent to the model. Max 500 chars.

timeoutnumberoptional

Per-request timeout in seconds (1–120, default 30).

tool_allowlistarrayoptional

Restrict which tool names from the server are exposed to the agent. null = all tools (up to 20). Max 50 names.

enabledbooleanoptional

Set to false to disable without deleting (default true).

Auth types

NONE — no authentication header added.

json
{ "auth_type": "NONE" }

BEARER — adds Authorization: Bearer <token>.

json
{
  "auth_type": "BEARER",
  "auth_config": { "bearer": "<your-token>" }
}

HEADERS — adds arbitrary headers (useful for API-key schemes like X-Api-Key).

json
{
  "auth_type": "HEADERS",
  "auth_config": {
    "X-Api-Key": "<your-key>",
    "X-Tenant-Id": "acme"
  }
}

Auth secrets are stored encrypted at rest. Responses mask secret values with ***.

bash
curl -X POST https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/integrations/mcp \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "github",
    "description": "GitHub issue and PR tools",
    "server_url": "https://api.githubcopilot.com/mcp/",
    "auth_type": "BEARER",
    "auth_config": { "bearer": "ghp_xxxx" },
    "timeout": 20,
    "tool_allowlist": ["create_issue", "search_issues", "list_pull_requests"]
  }'

Response - 201 Created

json
{
  "integration_id": "01JXYZ...",
  "chatbot_id": "01JMXYZ...",
  "name": "github",
  "description": "GitHub issue and PR tools",
  "server_url": "https://api.githubcopilot.com/mcp/",
  "auth_type": "BEARER",
  "auth_config": { "bearer": "***" },
  "timeout": 20.0,
  "tool_allowlist": ["create_issue", "search_issues", "list_pull_requests"],
  "enabled": true,
  "created_at": "2026-05-06T09:00:00Z",
  "updated_at": "2026-05-06T09:00:00Z"
}

List servers

http
GET /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp
Authorization: Bearer <api-key>
bash
curl https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/integrations/mcp \
  -H "Authorization: Bearer <your-api-key>"

Response - 200 OK

json
{
  "count": 2,
  "items": [
    {
      "integration_id": "01JXYZ...",
      "name": "github",
      "server_url": "https://api.githubcopilot.com/mcp/",
      "auth_type": "BEARER",
      "auth_config": { "bearer": "***" },
      "enabled": true
    }
  ]
}

Get a server

http
GET /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp/{integration_id}
Authorization: Bearer <api-key>

Update a server

All fields are optional. Omitted fields are left unchanged.

http
PATCH /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp/{integration_id}
Authorization: Bearer <api-key>
Content-Type: application/json
bash
curl -X PATCH https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/integrations/mcp/<integration-id> \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": false }'

Renaming a server

Renaming a server (changing name) does not automatically update any flow JSON that references the old name via collection. Update flow JSON manually after renaming.


Delete a server

http
DELETE /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp/{integration_id}
Authorization: Bearer <api-key>

Response - 204 No Content

Delete blocked by flows

A 409 Conflict is returned if the integration is still referenced by one or more flows. The response lists the blocking flow names. Remove the MCP tool from those flows before deleting.

json
{
  "detail": "This MCP server is still used by the following flows: \"Order Assistant\", \"Support Flow\". Remove the MCP tool from those flows before deleting the server."
}

Test a saved server

Opens a live session, calls tools/list, and returns the full tool inventory. Use this to verify credentials and connectivity after saving.

http
POST /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp/{integration_id}/test
Authorization: Bearer <api-key>

Response - 200 OK

json
{
  "server_name": "GitHub MCP Server",
  "server_version": "1.0.0",
  "tool_count": 3,
  "tools": [
    {
      "name": "create_issue",
      "description": "Create a GitHub issue in a repository",
      "input_schema": {
        "type": "object",
        "properties": {
          "repo": { "type": "string" },
          "title": { "type": "string" },
          "body": { "type": "string" }
        },
        "required": ["repo", "title"]
      }
    }
  ]
}
StatusMeaning
400URL validation failed or server returned an unexpected response
401Authentication failed (wrong or missing token)
403Server denied access
502Server is unreachable or timed out

Rate limited to 15 probe calls per user per minute.


Probe without saving

Test connectivity before creating an integration.

http
POST /api/dev/v1/chatbots/{chatbot_id}/integrations/mcp/test
Authorization: Bearer <api-key>
Content-Type: application/json
bash
curl -X POST https://beta-api.sarufi.io/api/dev/v1/chatbots/<chatbot-id>/integrations/mcp/test \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "server_url": "https://mcp.example.com/mcp",
    "auth_type": "BEARER",
    "auth_config": { "bearer": "tok_xxx" }
  }'

Same response shape as the saved-server test endpoint.


Using MCP tools in a flow

Referencing in LLM_AGENT

Add the MCP integration to an LLM_AGENT action's tools array. Use name: "mcp" with collection set to the integration's name field:

json
{
  "type": "LLM_AGENT",
  "name": "Order Assistant",
  "system_prompt": "You are a helpful order assistant. Use tools to look up order status and update records.",
  "tools": [
    {
      "name": "mcp",
      "collection": "github",
      "enabled": true
    }
  ]
}

collection must exactly match the integration's name. At runtime the platform looks up the integration for this chatbot by that name, fetches the tool list (from cache or live), and exposes each tool to the model.

Multiple MCP servers can be included in one agent:

json
"tools": [
  { "name": "mcp", "collection": "github" },
  { "name": "mcp", "collection": "jira" }
]

Built-in tools

Built-in tools (calculator, web_search, search, document_search, current_datetime) are auto-injected and do not need to be listed. Only list tools that carry config such as MCP or knowledge-base collection pins.


Tool name namespacing

At runtime, each MCP tool is exposed to the model as {integration_name}__{tool_name} (double underscore separator). For example, with collection: "github" and a server tool named search_issues, the model sees github__search_issues.

This prevents collisions when two MCP servers expose a tool with the same bare name. It is also why integration name values cannot contain __.


Tool allowlist

The tool_allowlist on the integration controls which tools from the MCP server are ever loaded. A null allowlist exposes everything the server advertises (up to 20 tools per server). A non-null list exposes only the named tools.

json
{
  "name": "github",
  "tool_allowlist": ["create_issue", "search_issues"]
}

Caching

Tool lists are cached per (chatbot_id, integration_id) for 5 minutes. On a cache miss the platform opens a live session to tools/list. Updating or deleting an integration immediately invalidates its cache entry.


Security

  • Server URL must be HTTPS.
  • Outbound connections go through an SSRF-safe transport that validates DNS before connecting. Private and loopback IP ranges are blocked.
  • Auth secrets are encrypted at rest and masked in all API responses.
  • Redirect responses from the MCP server are not followed.

Error reference

ErrorStatusCause
Plan limit reached402mcp_servers_per_chatbot_limit reached or is 0 for this plan
Name already in use409Another MCP integration on this chatbot has the same name
Integration referenced by flows409Delete blocked — remove the tool from flows first
URL not allowed400Server URL failed SSRF or HTTPS validation
Auth failed401/403Wrong credentials on connection test
Server unreachable502Timeout or DNS failure on connection test