Last updated April 2026 — refreshed for current package versions, transport guidance, and the official MCP spec (2025-03-26).
The Model Context Protocol (MCP) has become the dominant standard for connecting AI models to external tools and services — growing from 2 million monthly SDK downloads at its November 2024 launch to 97 million by March 2026. This guide shows you exactly how to add MCP client support to any React or Next.js application, using the two most practical approaches available in 2026: CopilotKit (full chat-UI framework, latest stable 1.56.x) and the official use-mcp hook from Anthropic's own modelcontextprotocol org (lightweight, transport-agnostic). It also covers the critical transport shift every developer needs to know: SSE is deprecated; Streamable HTTP is the standard.
What changed since May 2025 — read this if you're updating an existing integrationSSE transport is deprecated. MCP spec 2025-03-26 replaced HTTP+SSE with Streamable HTTP. SSE still works for backward compatibility, but new servers should use Streamable HTTP (/mcpendpoint). Several major platforms (Atlassian Rovo, Keboola, Microsoft Copilot Studio) had firm SSE end-of-life dates in mid-2026.CopilotKit is now at v1.56.x (latest: 1.56.4, released April 27 2026). The v1-to-v2 API migration is underway; all v1 hooks remain as thin compatibility wrappers. React 19 is fully supported without--legacy-peer-depsin most configurations as of v1.50+.The officialuse-mcphook from modelcontextprotocol org is the lightest-weight path for custom UIs. It supports both SSE and Streamable HTTP with automatic protocol detection.MCP Apps + AG-UI: CopilotKit v1.53+ supports the new@ag-ui/mcp-apps-middlewarepackage, letting MCP servers ship interactive UI that renders directly inside your React app.MCP 2026 roadmap: Stateless HTTP transport variant under review; centralized server discovery registry (npm-style) planned; horizontal scaling without sticky sessions is the stated goal.
Want the full picture? Read our continuously-updated AI Coding Agents Complete Guide (2026) — Cursor, Cline, Aider, OpenHands, Claude Code, and how teams deploy them.
TL;DR — which approach to use
| Approach | Package | Best for | Effort |
|---|---|---|---|
| CopilotKit | @copilotkit/react-core + @copilotkit/react-ui |
Full chat UI, agent orchestration, multi-server, tool visualization | Medium (provider + Copilot Cloud key) |
| use-mcp hook | use-mcp |
Custom UI, lightweight integration, any React component | Low (3-line hook call) |
| Direct SDK | @modelcontextprotocol/sdk |
Full control, server-side Node integration | High (build your own transport layer) |
What MCP actually is (and what it is not)
MCP is an open protocol — originally released by Anthropic in November 2024 and now governed as an open standard — that defines how AI models connect to external tools, data sources, and services. Think of it as a USB-C port for AI: any compliant host (Claude Desktop, Cursor, your React app) can connect to any compliant server (Gmail, Linear, your internal APIs) without custom glue code.
Three concepts matter for React developers:
- MCP host — the application that embeds the AI (your React app).
- MCP client — the protocol client inside the host that maintains a 1:1 connection to one server.
- MCP server — exposes tools, resources, and prompts over the protocol. Examples: Composio (250+ integrations), Zapier (8,000+ apps), or your own custom server.
Transport in 2026: Streamable HTTP replaces SSE
The original MCP spec (2024-11-05) used an HTTP+SSE transport with two separate endpoints: one SSE endpoint for receiving and a separate POST endpoint for sending. This design had serious production problems:
- Long-lived SSE connections fought with load balancers and required sticky sessions.
- No built-in reconnection or resumability — dropped connections caused lost messages.
- Protocol incompatibility with HTTP/2 and HTTP/3.
MCP spec 2025-03-26 introduced Streamable HTTP as the replacement. A single /mcp endpoint handles both POST (client-to-server) and GET (server-to-client via optional SSE stream). The spec officially marks HTTP+SSE as deprecated. When migrating:
# Old: SSE transport (deprecated)
# Endpoint: GET https://example.com/sse (opens SSE stream)
# Messages: POST https://example.com/sse/messages
# New: Streamable HTTP (current spec 2025-03-26)
# Single endpoint: POST / GET https://example.com/mcp
For backward compatibility, servers can host both transports simultaneously. Clients should attempt a POST InitializeRequest to the server URL first; if that returns 4xx, fall back to GET for SSE. The use-mcp hook does this automatically.
Approach 1: CopilotKit (full framework)
CopilotKit is the most popular path when you want a ready-made chat UI, multi-server management, and tool call visualization. Version 1.56.x is current as of April 2026.
Step 1 — Install packages
npm install @copilotkit/react-core @copilotkit/react-ui @copilotkit/runtime
Or use the CLI initializer (sets up shadcn/ui components and wires the provider):
npx copilotkit@latest init -m MCP
If you hit peer dependency warnings with React 18, add --legacy-peer-deps. React 19 support is stable in v1.50+.
Step 2 — Wrap your app with the CopilotKit provider
In your root layout (Next.js App Router example):
// app/layout.tsx
import { CopilotKit } from '@copilotkit/react-core';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<CopilotKit publicApiKey={process.env.NEXT_PUBLIC_COPILOT_CLOUD_API_KEY}>
{children}
</CopilotKit>
</body>
</html>
);
}
Get your API key at cloud.copilotkit.ai. A free tier is available. Set the key as an environment variable — never embed it literally in source:
NEXT_PUBLIC_COPILOT_CLOUD_API_KEY=your_key_here
Step 3 — Create an MCP server manager component
This component connects to one or more MCP endpoints at mount time:
// components/McpServerManager.tsx
'use client';
import { useCopilotChat } from '@copilotkit/react-core';
import { useEffect } from 'react';
export default function McpServerManager() {
const { setMcpServers } = useCopilotChat();
useEffect(() => {
setMcpServers([
{
// Use your MCP server's Streamable HTTP endpoint
endpoint: 'https://mcp.composio.dev/gmail',
},
{
endpoint: 'https://mcp.yourdomain.com/mcp', // custom server
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_MCP_TOKEN}`,
},
},
]);
}, []);
return null;
}
Include McpServerManager inside any page or layout that needs MCP access. You can dynamically update the server list — for example, based on user preferences or workspace settings.
Step 4 — Add the chat UI
// app/page.tsx
import { CopilotChat } from '@copilotkit/react-ui';
import '@copilotkit/react-ui/styles.css';
import McpServerManager from '@/components/McpServerManager';
export default function Page() {
return (
<main>
<McpServerManager />
<CopilotChat
instructions="You are a helpful assistant. Use available MCP tools to answer user requests."
labels={{ title: 'AI Assistant', initial: 'How can I help you today?' }}
/>
</main>
);
}
Step 5 — Tool call visualization (optional but recommended for debugging)
Monitor every tool call triggered by the AI in real time:
// components/ToolRenderer.tsx
'use client';
import { useCopilotAction } from '@copilotkit/react-core';
function McpToolCall({ status, name, args }: { status: string; name: string; args: unknown }) {
return (
<details className="border rounded p-2 mb-2 text-sm">
<summary>
<strong>{name}</strong> — <span>{status}</span>
</summary>
<pre>{JSON.stringify(args, null, 2)}</pre>
</details>
);
}
export function ToolRenderer() {
useCopilotAction({
name: '*',
render: ({ status, name, args }) => (
<McpToolCall status={status} name={name} args={args} />
),
});
return null;
}
Bonus: MCP Apps + AG-UI (v1.53+)
Starting with CopilotKit v1.53, you can render interactive UI shipped by the MCP server itself — the server controls the component tree inside your app. This uses the @ag-ui/mcp-apps-middleware package:
npm install @ag-ui/mcp-apps-middleware
// Enable MCP Apps middleware in your CopilotKit runtime
import { enableMcpAppsMiddleware } from '@ag-ui/mcp-apps-middleware';
// Add to your CopilotKit runtime configuration
const runtime = new CopilotRuntime({
middleware: [enableMcpAppsMiddleware()],
});
Approach 2: use-mcp hook (lightweight)
The use-mcp package, maintained in the official modelcontextprotocol GitHub org, is the minimal-dependency path. It supports both SSE and Streamable HTTP with automatic detection, handles OAuth 2.1 authentication, and retries broken connections. The repository was archived in February 2026 (indicating it reached stability, not abandonment — the package continues to work).
npm install use-mcp
// components/MyAiFeature.tsx
'use client';
import { useMcp } from 'use-mcp/react';
export default function MyAiFeature() {
const { state, tools, callTool } = useMcp({
url: 'https://mcp.example.com/mcp', // Streamable HTTP endpoint
clientName: 'My React App',
});
if (state === 'connecting') return <p>Connecting to MCP server…</p>;
if (state === 'failed') return <p>Failed to connect. Check the endpoint URL.</p>;
return (
<div>
<p>Connected — {tools.length} tools available</p>
<button
onClick={() =>
callTool('send_email', {
to: 'user@example.com',
subject: 'Hello from MCP',
body: 'Sent via MCP tool call.',
})
}
>
Send Email via MCP
</button>
</div>
);
}
The hook returns state ('connecting' | 'ready' | 'failed'), tools, resources, callTool, and readResource. Authentication with OAuth 2.1 is handled automatically, including popup-based flows.
Building a custom MCP server (Node.js)
If you need to expose your own backend tools over MCP, the @modelcontextprotocol/sdk package provides server-side primitives. Use StreamableHTTPServerTransport — not the deprecated SSEServerTransport:
// server/mcp-server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
import { z } from 'zod';
const app = express();
app.use(express.json());
const server = new McpServer({ name: 'my-server', version: '1.0.0' });
server.tool(
'get_user_data',
{ userId: z.string() },
async ({ userId }) => ({
content: [{ type: 'text', text: `User data for ${userId}` }],
})
);
// Single endpoint — both POST and GET
app.all('/mcp', async (req, res) => {
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: () => crypto.randomUUID() });
await server.connect(transport);
await transport.handleRequest(req, res);
});
app.listen(3001, () => console.log('MCP server running on :3001/mcp'));
Validate the Origin header in production to prevent DNS rebinding attacks — this is a spec requirement, not optional.
How to choose: decision tree
- Need a ready-made chat UI? → CopilotKit (
@copilotkit/react-core+@copilotkit/react-ui) - Building a custom UI with full control over rendering? →
use-mcphook - Need server-side MCP integration (Node.js API route, worker)? →
@modelcontextprotocol/sdkwithStreamableHTTPServerTransport - Connecting to multiple MCP servers with different auth? → CopilotKit's
setMcpServers(supports per-server headers/auth) - Want the AI to control your UI components? → CopilotKit v1.53+ with AG-UI and MCP Apps middleware
- Embedding in a static site or very small bundle? →
use-mcp(minimal dependencies)
Popular public MCP servers to connect to
| Server | Tools | Auth | Notes |
|---|---|---|---|
Composio (mcp.composio.dev) |
250+ tools, 20,000+ API actions | API key | Gmail, Slack, GitHub, Linear, Notion… |
| Zapier MCP | 8,000+ app integrations | OAuth | 80 tool calls/hour on free tier |
| Cloudflare Agents | Custom tools on Workers | API token | Streamable HTTP native; edge-deployed |
| Custom / self-hosted | Your own APIs | Bearer / JWT | Use @modelcontextprotocol/sdk |
Production deployment checklist
Environment variables
# CopilotKit
NEXT_PUBLIC_COPILOT_CLOUD_API_KEY=your_production_key
# Your MCP servers (never expose bearer tokens as NEXT_PUBLIC_)
MCP_SERVER_TOKEN=your_server_token
Keep server-to-server tokens out of NEXT_PUBLIC_ variables — they are baked into the JavaScript bundle and visible to users. Proxy requests through a Next.js API route if you need to attach server-side secrets.
Transport configuration
- Point all new integrations at Streamable HTTP endpoints (
/mcp), not SSE (/sse). - If you maintain your own MCP server, validate the
Originheader to block DNS rebinding attacks. - Bind local dev servers to
127.0.0.1, not0.0.0.0. - Use JWT or Bearer token auth for any server handling sensitive operations.
Supported deployment targets
- Vercel (recommended for Next.js; edge runtime supports MCP client calls)
- Netlify
- Cloudflare Workers (Streamable HTTP native)
- AWS / Docker containers (full Node.js runtime)
Performance notes
- Streamable HTTP allows MCP servers behind standard load balancers without sticky sessions — a significant improvement over SSE for high-traffic apps.
- The 2026 MCP roadmap includes a stateless HTTP transport variant that will further ease horizontal scaling.
- For latency-sensitive use cases, prefer MCP servers geographically close to your users. Cloudflare's edge-native MCP Workers (via Cloudflare Agents) are the current best option.
- Cache tool schemas at startup — tools don't change between sessions; re-fetching them on every connection adds unnecessary latency.
Common pitfalls and troubleshooting
Still pointing at an SSE endpoint
If your endpoint is /sse instead of /mcp, you're on the deprecated transport. The old pattern required two endpoints; the new Streamable HTTP uses one. The use-mcp hook will try to auto-detect, but mismatches cause silent failures. Check server logs for 405 Method Not Allowed on POST requests.
MCP connection terminates after ~5 minutes
Known issue with CopilotKit's SSE-backed connections (GitHub #2614). Workaround: implement a reconnect loop in your McpServerManager component, or migrate to a Streamable HTTP endpoint which handles disconnects more gracefully.
MCP tools not being invoked by the AI
CopilotKit issue #2595 tracks cases where tool calls silently fail. Common causes: the tool requires POST but the server is receiving GET (check server transport config), or tool argument schema doesn't match what the AI is producing. Use the MCP Inspector (npx @modelcontextprotocol/inspector) to manually trigger tool calls and inspect raw responses.
Local MCP servers and sessionId auth
Some MCP servers require a sessionId passed as a query parameter. CopilotKit's setMcpServers doesn't support query-param auth directly (GitHub #1965). Workaround: embed the session ID in the endpoint URL, or use a header-based auth approach instead.
React 19 peer dependency warnings
CopilotKit v1.50+ resolves most React 19 compatibility issues. If you still see peer dependency warnings on older versions, --legacy-peer-deps is safe to use during installation. The underlying components are compatible; the warning is a versioning declaration lag.
CORS errors connecting to remote MCP servers
Remote MCP servers must set appropriate CORS headers for browser-to-server calls. If you control the server, add Access-Control-Allow-Origin headers. If you don't, proxy MCP requests through a Next.js API route to avoid browser CORS restrictions:
// app/api/mcp-proxy/route.ts
export async function POST(request: Request) {
const body = await request.json();
const response = await fetch('https://your-mcp-server.com/mcp', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.MCP_SERVER_TOKEN}`,
},
body: JSON.stringify(body),
});
return new Response(response.body, {
headers: { 'Content-Type': response.headers.get('Content-Type') ?? 'application/json' },
});
}
Looking for React developers who already know MCP?
If integrating AI tooling into a production React codebase isn't something your current team has bandwidth for, Codersera's vetted React developers include engineers with hands-on MCP and AI agent integration experience — available to extend your team without the full-time hiring overhead. You might also find our posts on MCP vs traditional APIs and the best open-source MCP servers useful for planning your integration.
FAQ
Is MCP free to use?
MCP is an open, royalty-free protocol — there is no cost to implement it in your app. You pay for whatever AI provider (OpenAI, Anthropic, etc.) and MCP server services (Composio, Zapier) you use. CopilotKit has a free tier on Copilot Cloud; self-hosting the runtime is also supported.
Does MCP work with any LLM, or only Claude?
MCP is LLM-agnostic. While Anthropic created it, OpenAI, Google DeepMind, and most major model providers have adopted the protocol. CopilotKit supports OpenAI, Anthropic, and any OpenAI-compatible endpoint as the underlying LLM.
What is the difference between MCP and a regular REST API?
A REST API requires you to write custom integration code for every tool. MCP standardizes the handshake: a model can discover available tools, their argument schemas, and call them using one consistent protocol, regardless of what the underlying service is. See our MCP vs API deep-dive for more.
Can I use MCP without CopilotKit?
Yes. The use-mcp hook (from Anthropic's modelcontextprotocol org) lets you connect to any MCP server from any React component without the CopilotKit provider. The @modelcontextprotocol/sdk package gives you full control on the server side.
What happened to the SSE transport?
SSE (the original HTTP+SSE transport from spec 2024-11-05) is deprecated as of MCP spec 2025-03-26. It still works for backward compatibility, but new servers should implement Streamable HTTP (/mcp endpoint). Some hosted services set formal deadlines in mid-2026 for dropping SSE support.
How do I test my MCP server?
Use the official MCP Inspector: npx @modelcontextprotocol/inspector. It provides a visual UI to connect to any MCP server, list available tools, and manually trigger calls — essential for debugging before wiring up the React client.
Does CopilotKit support streamable HTTP yet?
As of April 2026, CopilotKit's MCP client defaults to SSE. Streamable HTTP support has been requested (GitHub #2319) and is not yet merged. If your MCP server only exposes a Streamable HTTP endpoint, use the use-mcp hook instead, which supports both transports with automatic detection.
How do I securely pass auth tokens to MCP servers from a React app?
For public API keys (like CopilotKit's publicApiKey), NEXT_PUBLIC_ env vars are acceptable. For sensitive bearer tokens or server secrets, proxy MCP requests through a Next.js API route and read the secret from a server-side environment variable. Never embed private credentials in NEXT_PUBLIC_ vars.
References and further reading
- MCP Specification 2025-03-26 — Transports (official)
- 2026 MCP Roadmap — Model Context Protocol Blog
- @copilotkit/react-core on npm (current version)
- use-mcp — official React hook from modelcontextprotocol org
- Cloudflare: Connect any React app to an MCP server in 3 lines
- Why MCP deprecated SSE and went with Streamable HTTP
- CopilotKit GitHub Releases — changelog for all versions
- MCP vs API: Differences, Similarities, and Benefits (Codersera)