# How to Integrate External Services Like Linear or Slack with Tambo AI Using MCP

> Integrate external services like Linear or Slack with Tambo AI using MCP. Discover tools, get server keys, and invoke actions via MCPClient callTool or the useMCP hook.

- Repository: [tambo ai/tambo](https://github.com/tambo-ai/tambo)
- Tags: how-to-guide
- Published: 2026-02-16

---

**You can integrate external services like Linear or Slack with Tambo AI by using the Model Context Protocol (MCP) client to discover tools, derive server keys from MCP endpoints, and invoke remote actions via `MCPClient.callTool()` or the `useMCP` React hook.**

Tambo AI is an open-source framework that enables AI applications to interact with external APIs through a standardized protocol. This guide explains how to integrate services like Linear and Slack using the Model Context Protocol (MCP) implementation found in the `tambo-ai/tambo` repository.

## Understanding MCP in Tambo AI

### What is the Model Context Protocol?

The **Model Context Protocol (MCP)** is a lightweight client-server protocol that allows Tambo applications to discover tools, call them, and fetch resources from any service implementing an MCP server. It abstracts transport details so you can switch between HTTP and Server-Sent Events (SSE) without changing your business logic.

### The MCP Client Architecture

At the core of every integration is the `MCPClient` class defined in [`packages/core/src/mcp-client.ts`](https://github.com/tambo-ai/tambo/blob/main/packages/core/src/mcp-client.ts). This client handles capability negotiation, session management, and tool invocation. It supports multiple transport mechanisms via the `MCPTransport` enum.

## Setting Up the MCP Client for Linear Integration

To connect to Linear's MCP server, instantiate the client with the service endpoint and transport type:

```typescript
import { MCPClient, MCPTransport } from "@tambo-ai/core/src/mcp-client";

const client = await MCPClient.create(
  "https://mcp.linear.app/mcp",          // MCP endpoint for Linear
  MCPTransport.HTTP,                     // SSE or HTTP transport
);

```

The `MCPClient.create()` method automatically negotiates capabilities (elicitation, sampling) and opens a session. Once connected, you can enumerate available tools using `listTools()` and execute them with `callTool()`.

## Deriving Server Keys for Service Identification

MCP resources use prefixed identifiers like `linear:issue-123` or `slack:channel-456`. Tambo extracts these prefixes using the `deriveServerKey` utility function found in [`packages/core/src/mcp-utils.ts`](https://github.com/tambo-ai/tambo/blob/main/packages/core/src/mcp-utils.ts):

```typescript
import { deriveServerKey } from "@tambo-ai/core/src/mcp-utils";

const key = deriveServerKey("https://mcp.linear.app/mcp"); // → "linear"

```

The same logic exists in the React SDK at [`react-sdk/src/util/mcp-server-utils.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/mcp-server-utils.ts) for frontend convenience. These utilities ensure consistent naming conventions when registering multiple MCP servers in a single application.

## Using MCP Tools to Invoke External Actions

After establishing a connection, discover available operations using the client's `listTools()` method, which returns a catalog of remote tools (e.g., `linear.createIssue`):

```typescript
const tools = await client.listTools();
// Returns: [{ name: "linear.createIssue", ... }, ...]

```

Invoke a specific tool using `callTool(name, args)`:

```typescript
const result = await client.callTool("linear.createIssue", {
  title: "Bug: UI crashes on resize",
  description: "Steps to reproduce…",
  projectId: "proj_123",
});

```

Tool names follow the **`<serverKey>.<toolName>`** convention, ensuring uniqueness across services.

## Integrating MCP with React Components

The React SDK provides the `useMCP` hook in [`react-sdk/src/mcp/mcp-hooks.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/mcp/mcp-hooks.ts) to fetch MCP resources directly within components:

```tsx
import { useMCP } from "@tambo-ai/react-sdk/src/mcp/mcp-hooks";

export function LinearIssue({ issueId }: { issueId: string }) {
  const { data, error, loading } = useMCP({
    serverKey: "linear",
    resource: `linear:issue-${issueId}`,
  });

  if (loading) return <>Loading…</>;
  if (error)   return <>Error: {error.message}</>;

  return (
    <div>
      <h3>{data?.title}</h3>
      <p>{data?.description}</p>
    </div>
  );
}

```

The hook resolves resource URIs by looking up the registered MCP server, issuing a `readResource` request, and returning the parsed JSON payload. This pattern works for any MCP-compatible service by changing the `serverKey` and URI scheme.

## Slack Integration Patterns

While Slack does not ship with a built-in MCP server in the Tambo repository, you can integrate it using the existing API wrapper or by exposing Slack as an MCP service. The repository includes a lightweight Slack helper in [`apps/web/lib/slack.ts`](https://github.com/tambo-ai/tambo/blob/main/apps/web/lib/slack.ts):

```typescript
import { createSlackChannel } from "@/lib/slack";

await createSlackChannel("my-company", "new-user@example.com");

```

This wrapper authenticates using the `SLACK_OAUTH_TOKEN` environment variable (declared in `docker.env.example`) and implements the `conversations.invite` flow. To expose Slack as an MCP server, create a thin adapter in your API layer (e.g., `apps/api`) that implements the MCP `listTools` and `callTool` contract, forwarding calls to the Slack wrapper.

## End-to-End Integration Workflow

To integrate external services like Linear or Slack with Tambo AI using MCP, follow this complete workflow:

1. **Register MCP servers** using the admin UI component at [`apps/web/components/dashboard-components/project-details/mcp-server-editor.tsx`](https://github.com/tambo-ai/tambo/blob/main/apps/web/components/dashboard-components/project-details/mcp-server-editor.tsx).
2. **Derive server keys** using `deriveServerKey` to ensure consistent resource prefixing (`linear:`, `slack:`).
3. **Consume resources** with the `useMCP` React hook by passing the `serverKey` and resource URI.
4. **Invoke actions** using `MCPClient.callTool` with the `<serverKey>.<toolName>` naming convention.

Because MCP abstracts the transport layer, you can switch between HTTP and SSE transports by changing the `MCPTransport` enum value without modifying your business logic.

## Summary

- **MCPClient** in [`packages/core/src/mcp-client.ts`](https://github.com/tambo-ai/tambo/blob/main/packages/core/src/mcp-client.ts) handles connection, capability negotiation, and tool invocation for external services.
- **deriveServerKey** in [`packages/core/src/mcp-utils.ts`](https://github.com/tambo-ai/tambo/blob/main/packages/core/src/mcp-utils.ts) generates stable prefixes (e.g., `linear`, `slack`) from MCP URLs to identify resources.
- **useMCP** hook in [`react-sdk/src/mcp/mcp-hooks.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/mcp/mcp-hooks.ts) enables React components to fetch MCP resources using resource URIs like `linear:issue-123`.
- Tool names follow the `<serverKey>.<toolName>` pattern (e.g., `linear.createIssue`) to ensure uniqueness across services.
- Slack integration uses the wrapper in [`apps/web/lib/slack.ts`](https://github.com/tambo-ai/tambo/blob/main/apps/web/lib/slack.ts) and can be exposed as an MCP server by implementing the protocol contract.

## Frequently Asked Questions

### How do I register a new MCP server in Tambo AI?

Register a new MCP server through the admin dashboard using the `MCPServerEditor` component located at [`apps/web/components/dashboard-components/project-details/mcp-server-editor.tsx`](https://github.com/tambo-ai/tambo/blob/main/apps/web/components/dashboard-components/project-details/mcp-server-editor.tsx). This UI allows you to input the MCP endpoint URL and configure transport settings (HTTP or SSE). Once saved, Tambo derives the server key automatically using `deriveServerKey` to prefix resources correctly.

### What transport protocols does Tambo's MCP client support?

The `MCPClient` class in [`packages/core/src/mcp-client.ts`](https://github.com/tambo-ai/tambo/blob/main/packages/core/src/mcp-client.ts) supports both **HTTP** and **Server-Sent Events (SSE)** transports via the `MCPTransport` enum. You specify the transport when calling `MCPClient.create(url, transport)`. Switching between transports requires only changing this enum value, as the client abstracts the underlying protocol details.

### How does Tambo handle authentication for Slack integration?

Slack integration uses a lightweight wrapper in [`apps/web/lib/slack.ts`](https://github.com/tambo-ai/tambo/blob/main/apps/web/lib/slack.ts) that authenticates via the `SLACK_OAUTH_TOKEN` environment variable (defined in `docker.env.example`). The `createSlackChannel` function implements Slack's `conversations.invite` flow. To expose Slack as an MCP service, you must create an adapter that implements the MCP `listTools` and `callTool` contract while forwarding calls to this authenticated wrapper.