Skip to content

Latest commit

 

History

History
181 lines (136 loc) · 4.45 KB

File metadata and controls

181 lines (136 loc) · 4.45 KB
title description type prerequisites
MCP (Model Context Protocol)
Discover and invoke tools from remote MCP servers directly from your chat bot handlers.
guide
/docs/usage

Chat SDK can connect to remote MCP servers to discover and invoke tools. This lets your bot call APIs like Sentry, Linear, Notion, and Figma through a standard protocol.

Installation

The MCP SDK is an optional peer dependency:

pnpm add @modelcontextprotocol/sdk

Configuration

Pass mcpServers when creating your Chat instance:

import { Chat } from "chat";

const bot = new Chat({
  userName: "mybot",
  adapters: { slack },
  state,
  mcpServers: [
    {
      name: "sentry",
      transport: {
        type: "http",
        url: "https://mcp.sentry.dev/mcp",
        headers: {
          Authorization: `Bearer ${process.env.SENTRY_AUTH_TOKEN}`,
        },
      },
    },
  ],
});

MCP servers are connected lazily on the first webhook request.

Listing tools

Discover all tools available across connected servers:

const tools = await bot.mcp.listTools();

for (const tool of tools) {
  console.log(`${tool.serverName}/${tool.name}: ${tool.description}`);
}

Each tool includes name, description, inputSchema (JSON Schema), and serverName.

Calling tools

Invoke a tool by name from any handler:

bot.onNewMention(async (thread, message) => {
  const result = await bot.mcp.callTool("search_issues", {
    query: message.text,
  });

  const text = result.content
    .filter((c) => c.type === "text")
    .map((c) => c.text)
    .join("\n");

  await thread.post(text);
});

Transport types

Type Config value Description
Streamable HTTP "http" Default. Modern bidirectional transport over HTTP.
Server-Sent Events "sse" Legacy SSE-based transport. Use if the server doesn't support Streamable HTTP.

Authentication

Service-level (static headers)

The bot uses a shared API key for all requests. Configure headers directly in the transport:

mcpServers: [
  {
    name: "sentry",
    transport: {
      type: "http",
      url: "https://mcp.sentry.dev/mcp",
      headers: { Authorization: `Bearer ${process.env.SENTRY_AUTH_TOKEN}` },
    },
  },
];

Per-tenant

Look up the tenant's token at call time and pass it via the headers option. A temporary connection is created with those headers for the duration of the call:

bot.onNewMention(async (thread, message) => {
  const tenantToken = await lookupTenantToken(thread.id);

  const result = await bot.mcp.callTool(
    "search_issues",
    { query: message.text },
    { headers: { Authorization: `Bearer ${tenantToken}` } }
  );

  await thread.post(result.content[0].text);
});

Per-user

Same pattern — resolve the user's OAuth token and pass it per-call:

bot.onNewMention(async (thread, message) => {
  const userToken = await getUserOAuthToken(message.author.id);

  const result = await bot.mcp.callTool(
    "create_issue",
    { title: message.text },
    { headers: { Authorization: `Bearer ${userToken}` } }
  );

  await thread.post(`Created: ${result.content[0].text}`);
});

Multiple servers

Tools from all configured servers are merged. The SDK routes each callTool to the correct server automatically:

mcpServers: [
  {
    name: "sentry",
    transport: { type: "http", url: "https://mcp.sentry.dev/mcp" },
  },
  {
    name: "linear",
    transport: {
      type: "http",
      url: "https://mcp.linear.app/mcp",
      headers: { Authorization: `Bearer ${process.env.LINEAR_API_KEY}` },
    },
  },
];

Refreshing tools

If a server's tool list changes at runtime, re-fetch it:

await bot.mcp.refresh();

Graceful degradation

If a server fails to connect during initialization, a warning is logged and the remaining servers continue normally. Your bot won't crash because one MCP server is down.

Error codes

Code When
MCP_TOOL_NOT_FOUND callTool is called with a tool name that doesn't exist on any connected server.
MCP_NOT_CONFIGURED callTool is called but no mcpServers were configured.
MCP_SDK_NOT_INSTALLED @modelcontextprotocol/sdk is not installed.