10 分钟内将任何 React 应用转变为 MCP 客户端
AI 代理已经解锁了强大的用例,因此开发人员正在自动化复杂的工作流程。
但有时您只是想构建智能的东西而不需要额外的复杂性,这可以使用无代理架构来实现。
今天,我们将了解它的含义、MCP 如何适应整个场景,以及如何使用带有 Composio 服务器的 CopilotKit(框架)构建我们自己的无代理应用程序。
让我们开始吧。
涵盖哪些内容?
简而言之,我们正在详细介绍这些主题。
- 什么是无代理架构?
- MCP及其核心组件介绍。
- 如何在三十分钟内运行 Next.js + MCP 客户端。
- 构建工作记忆项目来管理来自 Linear 等工具的任务和项目。
- 一些具有用例的真实示例。
注意:Copilotkit(用于构建 AI Copilots 的框架)最近推出了对 MCP 的内置支持,我们将在本指南中使用它。
为了使事情变得简单,我们将它连接到Composio,它提供了具有内置身份验证和最少设置的即用型 MCP 服务器。
我们将涵盖很多内容,让我们开始吧。
1.什么是无代理架构?
Agentless architecture
指前端(通常是 Web 或移动客户端)直接与智能后端(例如 MCP 服务器)交互的系统设计,无需部署或维护自定义agent
来管理状态、工具或操作。
在 AI 应用领域,这意味着您的 React 前端可以向兼容 MCP 的服务器发送结构化的提示和上下文,并接收智能响应,而无需托管您自己的 AI 代理。
您无需编写后端逻辑来处理工具、内存或操作(它们都是 MCP 的一部分),只需向现有的 MCP 服务器发送请求,它就会为您处理智能内容。
🧠 示例:React 应用中 AI 任务助手
假设您正在构建一个基于 React 的项目管理应用程序。
采用无代理架构:
- 您添加一个聊天框。
- 用户类型:
Create a new task for our launch checklist
。 - 您的应用将其转发到像 CopilotKit 这样的 MCP 服务器。
- MCP 服务器理解该请求,连接到您的工具(例如 Linear),并回复:
Task Finalize Launch Assets has been created in the Marketing project.
无需托管您自己的 AI 代理或编写编排逻辑。它就是这么简单。
何时采用无代理模式,何时采用基于代理模式?
这取决于用例的复杂程度。以下是一个简单的比较:
无代理架构 | 基于代理的架构 |
---|---|
易于设置,无需后端代理 | 需要额外设置来托管和管理代理 |
非常适合简单的前端、静态站点或快速演示 | 最适合需要内存的复杂工作流程、工具或应用程序 |
没有内置记忆,大多无状态 | 支持记忆、历史和不断发展的背景 |
非常适合 AI 聊天 UI、助手或小助手 | 非常适合开发代理、RPA 机器人和完全自主代理 |
只需要访问兼容 MCP 的服务器 | 需要自己的后端或容器运行时 |
只需部署前端即可轻松跨用户扩展 | 需要针对多个并发代理的后端扩展策略 |
我的建议是两种方法都试试,看看哪种有效。至少,这样你就能大致了解每种方法可能带来的问题。
了解了Agentless架构之后,我们来快速了解一下MCP以及其核心组件。
2.MCP及其核心组件介绍。
模型上下文协议 (MCP) 是一种新的开放协议,它标准化了应用程序向 LLM 提供上下文和工具的方式。
可以将其视为 AI 的通用连接器。MCP 作为 Cursor 的插件系统,允许您通过将其连接到各种数据源和工具来扩展 Agent 的功能。
MCP 帮助您在 LLM 之上构建代理和复杂的工作流程。
例如,Obsidian 的 MCP 服务器可帮助 AI 助手搜索和阅读 Obsidian 保险库中的笔记。
您的 AI 代理现在可以:
→ 通过 Gmail 发送电子邮件
→ 在 Linear 中创建任务
→ 在 Notion 中搜索文档
→ 在 Slack 中发布消息
→ 在 Salesforce 中更新记录
所有这些都通过标准化界面发送自然语言指令来实现。
想想这对生产力意味着什么。以前需要在 5 个以上应用之间切换的任务,现在只需与客服人员进行一次对话即可完成。
从本质上讲,MCP 遵循客户端-服务器架构,其中主机应用程序可以连接到多个服务器。
核心组件。
以下是任何通用 MCP 服务器的核心组件。
-
MCP hosts
- 想要通过 MCP 访问数据的 Claude Desktop、Cursor、Windsurf 或 AI 工具等应用程序。 -
MCP Clients
- 协议客户端与 MCP 服务器保持 1:1 连接,充当通信桥梁。 -
MCP Servers
- 轻量级程序,每个程序通过标准化模型上下文协议公开特定功能(如读取文件、查询数据库......)。 -
Local Data Sources
- 您计算机上的 MCP 服务器可以安全访问的文件、数据库和服务。例如,浏览器自动化 MCP 服务器需要访问您的浏览器才能运行。 -
Remote Services
- MCP 服务器可以连接的外部 API 和基于云的系统。
如果您有兴趣了解该架构,请查看官方文档。它涵盖了协议层、连接生命周期、错误处理以及整体实现。
我们将涵盖所有内容,但如果您有兴趣了解有关 MCP 的更多信息,请查看以下两个博客:
- Builder.io 团队的“模型上下文协议 (MCP)”是什么?
- MCP:它是什么以及它为什么重要 作者:Addy Osmani
3. 如何在三十分钟内运行 Next.js + MCP 客户端。
在本节中,我们将讨论如何使用 CopilotKit 为您的 Next.js 项目添加 MCP 支持。
我们将集成 Copilotkit,它内置了对模型上下文协议 (MCP) 的支持。这将使我们能够创建一个前端,直接连接到兼容 MCP 的外部服务器。
如果您有兴趣自己阅读,请阅读docs.copilotkit.ai/guides/model-context-protocol上的文档。如果您不想读也没关系;我会详细解释所有步骤和概念。
🎯 使用 CLI 的一行命令安装 MCP 支持
如果您没有现有的 Next.js 应用程序,则可以使用npx create-next-app@latest
终端中的命令创建一个。
项目准备就绪后,集成 MCP 支持的最快方法是使用CopilotKit CLI
。只需在终端中运行以下命令即可。
npx copilotkit@latest init -m MCP
这个命令在后台做了很多事情:
- 安装所有必需的 CopilotKit 依赖项
- 设置一个可立即使用的接口,用于与 MCP 服务器交互
- 添加组件以集成 MCP 并安装 shadcn/ui 进行 UI 样式设置
它将指导您安装所需的软件包,并建议您使用 Copilot Cloud 进行部署(无需额外设置)。
它将验证配置并检测现有的 Next.js 应用是否有效。之后,您可以选择 或default project
(mcp demo
这是 Copilotkit 团队制作的一个展示项目)。
我已经尝试使用 CLI,但在本指南的范围内,我们将使用默认项目。
然后它会提示您安装shadcn/ui
内置组件样式。
由于我们使用的是React 19
,它非常新。某些库可能尚未正式支持它,并且 npm 可能会因为版本冲突(称为peer dependency issues
)而显示错误。
为了解决这个问题,CLI 建议使用--legacy-peer-deps
,它告诉 npm 忽略这些版本警告并继续安装。
这是一种通常可以很好地发挥作用的解决方法,特别是对于仍在获得支持的较新 React 版本而言。
安装完成后,您将看到已添加内容的摘要。
您可以使用本地启动服务器npm run dev
并导航至http://localhost:3000/copilotkit
以查看您的 MCP 就绪前端。
📧 连接到 Gmail MCP 服务器(演示)
您需要输入您希望使用的 MCP 服务器的 SSE 网址。您可以在mcp.composio.dev上找到 100 多个可用的托管 MCP 服务器列表。
让我们简单检查一下流程。我使用的 Gmail 服务器是mcp.composio.dev/gmail。
复制您从 Composio 服务器页面生成的 MCP 服务器 URL,并将其粘贴到Enter MCP server URL
页面上的占位符字段 ( ) 中。此 URL 属于敏感信息,仅供个人使用,因此我对其进行了模糊处理。
我已经给出了发送一封电子邮件的提示,并在电子邮件正文中说明了hi@anmolbaranwal.com
主题。working demo of copilotkit mcp
composio server works
它将调用适当的 MCP 服务器(如果您有多个),并根据您的提示采取正确的操作。
由于没有活动连接,它将首先建立一个连接(如上图所示)。您需要通过在浏览器中复制 OAuth URL 来进行身份验证。
💡 建议先用虚拟账户测试一下,尤其是在实验的时候。一旦满意,就可以用主账户自动执行操作。
您必须提供对服务器的访问权限,以便它可以根据您的提示采取行动。
一旦您通过身份验证,您将在浏览器中看到确认信息。
你只需输入一些信息done
,代理就可以验证你的活动连接。让我惊讶的是,它在发送电子邮件之前仍然会请求批准,这确保了你仍然掌控着一切。
获得批准后,代理将继续发送电子邮件。
不知何故,它没有提供主题,但我们收到了带有适当正文回复的电子邮件。
耶!🎉 您现在已经使用 CopilotKit 完成了与 MCP 服务器的端到端集成。
您可以对所有其他 MCP 服务器执行相同操作并创建多步骤工作流程。
接下来:我们将从头开始手动构建此流程,以便更好地理解底层组件。
🎯 从头开始设置整个集成
让我们从头开始演示如何设置 CopilotKit 集成以使用 MCP 服务器。这将帮助您了解端到端的架构和流程。
如果您已经有现有的 Next.js 项目,请跳至步骤 2。
步骤 1:使用 TypeScript 创建 Next.js 项目
如果您没有前端,您可以使用以下命令创建一个新项目next.js
。TypeScript
Tailwind CSS
npx create-next-app@latest
您的项目结构如下所示。我们将使用最新版本的 Next.js 以及 App Router。我添加了一些文件(用于我的风格偏好),我每个项目都会这样做,所以这不是强制性的。
🧠 你可能会注意到没有tailwind.config.js
。这是因为,使用Tailwind CSS V4,我们现在可以直接在 globals.css 中自定义样式,而新的 next.js 应用程序不再需要配置文件。
第 2 步:安装 CopilotKit 包并设置提供程序。
安装必要的 CopilotKit 包。
npm install @copilotkit/react-core @copilotkit/react-ui
-
@copilotkit/react-core
提供将您的 React 应用程序与 CopilotKit 后端和 MCP 服务器连接的核心上下文和逻辑。 -
@copilotkit/react-ui
提供现成的 UI 组件,例如<CopilotChat />
快速构建 AI 聊天或助手界面。
该<CopilotKit>
组件必须包裹应用中支持 Copilot 的部分。大多数情况下,最好将其放置在整个应用的周围,例如app/layout.tsx
。
import type { Metadata } from 'next'
import './globals.css'
import '@copilotkit/react-ui/styles.css'
import './globals.css'
import { CopilotKit } from '@copilotkit/react-core'
export const metadata: Metadata = {
title: 'CopilotKit MCP Demo',
description: 'CopilotKit MCP Demo',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body
className={
'relative flex flex-col overflow-x-hidden font-sans antialiased'
}
suppressHydrationWarning
>
<CopilotKit publicApiKey="<replace_with_your_own>">
{children}
</CopilotKit>
</body>
</html>
)
}
将其替换为cloud.copilotkit.ai<replace_with_your_own>
中的 API 密钥。它是免费的,如果你正在构建用于生产环境的代码,建议使用。
如果您有兴趣使用 MCP 服务器配置自托管运行时,请阅读文档。
只需单击“开始”,您就会找到一个公共 API 密钥。
步骤 3:创建组件来配置 MCP 服务器连接
现在我们将创建一个辅助组件,用于将您的应用连接到 MCP 服务器。在 处创建一个新文件src\components\McpServerManager.tsx
。
'use client'
import { useCopilotChat } from '@copilotkit/react-core'
import { useEffect } from 'react'
function McpServerManager() {
const { setMcpServers } = useCopilotChat()
useEffect(() => {
setMcpServers([
{
// Try a sample MCP server at https://mcp.composio.dev/
endpoint: 'your_mcp_sse_url',
},
])
}, [setMcpServers])
return null
}
export default McpServerManager
此McpServerManager
组件将您的应用连接到 MCP 服务器。
-
当组件加载(
useEffect
运行)时,它会通过提供服务器 URL 来告诉 CopilotKit 连接到哪个 MCP 服务器。 -
组件本身不渲染任何内容(
return null
),它只是在后台建立连接。
它会将您的应用配置为在页面加载时自动与 MCP 服务器通信。您只需在属性中设置your_mcp_sse_url
用于工具访问的特定 MCP 端点 ( ) endpoint
。
第四步:添加聊天界面。
该ChatInterface
组件会创建实际的聊天 UI,并确保聊天功能知道您要连接的 MCP 服务器。在 处创建一个新文件src\components\ChatInterface.tsx
。
'use client'
import { CopilotChat } from '@copilotkit/react-ui'
import McpServerManager from './McpServerManager'
export default function ChatInterface() {
return (
<div className="flex h-screen p-4">
<McpServerManager />
<CopilotChat
instructions="You are a helpful assistant with access to MCP servers."
className="w-full flex-grow rounded-lg"
/>
</div>
)
}
以下是对正在发生的事情的简单解释。
-
McpServerManager
在页面加载时运行并告诉 CopilotKit 使用哪个 MCP 服务器。 -
CopilotChat
显示用户可以与 AI 交谈的聊天框。 -
告诉
instructions
人工智能它应该成为哪种助手。
步骤 5:可视化 MCP 工具调用(可选)。
要监控助手触发的工具调用,请添加一个ToolRenderer
组件。这完全是可选的,但在开发过程中很有用。
在 处创建一个新文件src\components\ToolRenderer.tsx
。
'use client'
import {
useCopilotAction,
CatchAllActionRenderProps,
} from '@copilotkit/react-core'
import McpToolCall from './McpToolCall'
export function ToolRenderer() {
useCopilotAction({
/**
* The asterisk (*) matches all tool calls
*/
name: '*',
render: ({ name, status, args, result }: CatchAllActionRenderProps<[]>) => (
<McpToolCall status={status} name={name} args={args} result={result} />
),
})
return null
}
然后创建McpToolCall.tsx
(在同一components
目录下)。这将在可折叠的 UI 中显示工具名称、状态、参数和结果。
它是一个可视化调试组件,显示工具调用的详细信息,例如助手尝试执行的操作以及返回的结果。
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import * as React from 'react'
interface ToolCallProps {
status: 'complete' | 'inProgress' | 'executing'
name?: string
args?: any
result?: any
}
export default function McpToolCall({
status,
name = '',
args,
result,
}: ToolCallProps) {
const [isOpen, setIsOpen] = React.useState(false)
const classes = {
container:
'bg-white rounded-xl overflow-hidden w-full border-2 border-gray-200 shadow-md transition-all duration-200 hover:shadow-xl my-1',
header:
'p-4 flex items-center cursor-pointer group bg-gray-50 border-b border-gray-200',
title: 'text-gray-900 font-semibold overflow-hidden text-ellipsis',
statusContainer: 'ml-auto flex items-center gap-2',
statusText: 'text-xs text-gray-700 font-medium mr-1',
content: 'px-5 pb-5 pt-3 text-gray-800 font-mono text-xs',
section: 'mb-4',
sectionTitle:
'text-gray-700 text-xs uppercase tracking-wider mb-2 font-sans font-bold',
codeBlock:
'whitespace-pre-wrap max-h-[200px] overflow-auto text-gray-900 bg-gray-50 p-3 rounded border border-gray-200',
chevron: {
base: 'text-gray-700 mr-2 transition-transform duration-200',
open: 'rotate-90',
hover: 'group-hover:text-gray-900',
},
contentWrapper: {
base: 'overflow-hidden transition-all duration-300 ease-in-out',
open: 'max-h-[600px] opacity-100',
closed: 'max-h-0 opacity-0',
},
}
// Status indicator colors
const statusColors = {
complete: 'bg-emerald-500 shadow-emerald-500/40',
inProgress: 'bg-amber-500 shadow-amber-500/40',
executing: 'bg-blue-500 shadow-blue-500/40',
}
// Simplified format function
const format = (content: any): React.ReactNode => {
if (!content) return null
return typeof content === 'object' ? (
<span>{JSON.stringify(content, null, 2)}</span>
) : (
<span>{String(content)}</span>
)
}
const getStatusColor = () => {
const baseColor = statusColors[status].split(' ')[0]
const shadowColor = statusColors[status].split(' ')[1]
return `${baseColor} ${status === 'inProgress' || status === 'executing' ? 'animate-pulse' : ''} shadow-[0_0_10px] ${shadowColor}`
}
return (
<div className={classes.container}>
<div className={classes.header} onClick={() => setIsOpen(!isOpen)}>
<ChevronRight isOpen={isOpen} chevronClasses={classes.chevron} />
<span className={classes.title}>{name || 'MCP Tool Call'}</span>
<div className={classes.statusContainer}>
<span className={classes.statusText}>
{status === 'complete'
? 'Completed'
: status === 'inProgress'
? 'In Progress'
: 'Executing'}
</span>
<div className={`h-3 w-3 rounded-full ${getStatusColor()}`} />
</div>
</div>
<div
className={`${classes.contentWrapper.base} ${isOpen ? classes.contentWrapper.open : classes.contentWrapper.closed}`}
>
<div className={classes.content}>
<div className={classes.section}>
<div className={classes.sectionTitle}>Name</div>
<pre className={classes.codeBlock}>{name}</pre>
</div>
{args && (
<div className={classes.section}>
<div className={classes.sectionTitle}>Parameters</div>
<pre className={classes.codeBlock}>{format(args)}</pre>
</div>
)}
{status === 'complete' && result && (
<div className={classes.section}>
<div className={classes.sectionTitle}>Result</div>
<pre className={classes.codeBlock}>{format(result)}</pre>
</div>
)}
</div>
</div>
</div>
)
}
const ChevronRight = ({
isOpen,
chevronClasses,
}: {
isOpen: boolean
chevronClasses: any
}) => {
return (
<svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={`${chevronClasses.base} ${isOpen ? chevronClasses.open : ''} ${chevronClasses.hover}`}
stroke="currentColor"
strokeWidth="2.5"
strokeLinecap="round"
strokeLinejoin="round"
>
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
)
}
步骤6:组合所有组件。
创建所有单独的组件后,就该将它们全部组合起来了src/app/page.tsx
。
'use client'
import { CopilotChat } from '@copilotkit/react-ui'
import McpServerManager from '../components/McpServerManager'
import { ToolRenderer } from '../components/ToolRenderer'
export default function Page() {
return (
<div className="flex h-screen p-4">
<McpServerManager />
<CopilotChat
instructions="You are a helpful assistant with access to MCP servers."
className="w-full flex-grow rounded-lg"
/>
<ToolRenderer />
</div>
)
}
恭喜!🎉 您的 CopilotKit 和 MCP 服务器设置已完成!
步骤 7:添加 MCP 服务器端点
现在我们只需要添加端点 URL 来连接到外部 MCP 服务器。这可以在组件内部通过像这样的属性McpServerManager
传递 URL来实现。endpoint
setMcpServers([
{
// Try a sample MCP server at https://mcp.composio.dev/
endpoint: 'your_mcp_sse_url',
},
])
有两种更简单的方法可以立即连接到 100 多个 MCP 服务器:
1) Composio - Composio 拥有完全托管的服务器,无需复杂的设置,并内置 Auth 功能。它支持 250 多种工具,并提供 20,000 多个预构建的 API 操作,无需编码即可集成。
它还可以在本地或远程操作。并提供更好的工具调用准确性,使AI代理能够与集成应用程序顺畅交互。
这也意味着更少的停机时间和维护问题。您可以在status.composio.dev/查看状态。
通过每个选项,您将找到活跃用户总数、当前版本、最近更新的时间以及所有可用的操作。
TypeScript
您将找到使用、安装它的说明Python
,并且它支持 Claude (MacOS)、Windsurf (MacOS) 和 Cursor 作为 MCP 主机。
2)Zapier - Zapier 支持超过8,000 个应用程序,但每小时只能进行 80 次工具调用,这可能是一个限制。
如果出现服务器问题,只需使用其他选项。
🔧 MCP 服务器故障排除
最简单的方法是使用 Cursor 或 Claude 等客户端(您只需要在 Cursor 中运行 npx 命令),然后您可以通过打开聊天来测试工具调用。
如果您不确定您的 MCP 服务器是否正常工作:
⚡ 直接在浏览器中打开 MCP 服务器 URL。如果它返回数据流(通常是 JSON 行),则表示服务器正常运行。⚡
检查浏览器的 DevTools 是否存在网络或控制台错误。⚡
有时,过时的连接可能会导致静默故障,重启开发服务器可以解决此问题。
步骤 8:添加 MCP 端点并运行服务器。
您可以使用 在 next.js 应用中运行服务器npm run dev
。现在您应该可以看到聊天界面。
这个流程与上一个非常相似。我再次使用 Gmail 服务器https://mcp.composio.dev/gmail来帮助您理解从头设置和通过 CLI 设置之间的结果差异。
添加端点后,只需提供提示,您将能够看到我们使用该ToolRenderer
组件以来的工具调用。
和以前一样,它会请求批准并相应地发送电子邮件。我已确认邮件已成功发送到我的收件箱。
在下一节中,我们将举一个复杂的例子。
4. 构建工作记忆项目来管理来自 Linear 等工具的任务和项目。
让我们研究一个工作记忆项目,它将教我们如何构建交互式、人工智能聊天应用程序,并使用 MCP 和 CopilotKit 与 Linear 和 Slack 等外部工具连接。
涉及的技术栈:
- Next.js(应用路由器)+ TypeScript
- CopilotKit React 核心(状态管理)
- CopilotKit React UI(AI聊天)
- Tailwind CSS(样式)
- React Query(数据获取)
- Framer Motion(动画)
- Radix UI(可访问组件)
- React Flow(可视化流程图)
在继续之前,请确保您有Node.js(推荐使用 LTS 版本)。
步骤 1:克隆并设置存储库。
为了简单起见,我们将在 GitHub 上克隆copilotkit mcp 存储库。
git clone https://github.com/CopilotKit/copilotkit-mcp-demo.git
请使用安装依赖项npm install
。
之后,我们需要.env
在该目录下创建一个文件root
。然后将你的OpenAI API 密钥添加到该.env
文件中。我已附上文档链接,方便查阅。
这将是命名约定。
OPENAI_API_KEY= YOUR_API_KEY
您还需要将cloud.copilotkit.ai中的 API 密钥放入文件中.env
。如果您要构建用于生产环境的代码,则建议您使用这个密钥。
这将是命名约定。
NEXT_PUBLIC_COPILOT_CLOUD_API_KEY= YOUR_API_KEY
只需单击“开始”,您就会找到一个公共 API 密钥。
第 2 步:让我们看一下项目结构。
项目结构如下。
-
/src/app
:包含 Next.js 页面、布局和全局样式。 -
/src/components
:包括可重复使用的 UI 组件和代理界面,如旅行、研究、聊天、地图和侧边栏。 -
/src/providers
:包装用于管理代理状态的全局状态提供程序。 -
/src/lib
:包含实用函数和配置文件。 -
/src/hooks
:用于可重复使用逻辑的自定义 React 钩子。 -
/src/contexts
:提供用于管理全局状态的 React 上下文。
步骤 3:让我们了解代码库。
我不会逐一介绍每个组件的代码,否则这篇博客会太长,所以我会尽量涵盖所涉及的概念。请查看代码库并继续学习,了解所有组件是如何协同工作的。
⚡ 1. Entry 是src/app/layout.tsx
,它导入全局样式,加载 Google 字体,然后将所有内容包装在您的顶级中<Providers>
。
⚡ 2. Providers(src/providers/Providers.tsx
)是设置应用程序的状态、API 访问和服务器配置的全局提供程序的组件。
"use client";
import { CoAgentsProvider } from "@/components/coagents-provider";
import McpServerManager from "@/components/McpServerManager";
import { ToolRenderer } from "@/components/ToolRenderer";
import { useLocalStorage } from "@/hooks/use-local-storage";
import { CopilotKit } from "@copilotkit/react-core";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import React from "react";
export interface Config {
endpoint: string;
serverName: string;
}
export interface ConfigContextType {
config: Config[];
setConfig: (config: Config[]) => void;
}
const queryClient = new QueryClient();
export const ServerConfigsContext = React.createContext<
ConfigContextType | undefined
>(undefined);
export default function Providers({ children }: { children: React.ReactNode }) {
const [mcpConfig] = useLocalStorage("mcpConfig", []);
const [config, setConfig] = React.useState<Config[]>(mcpConfig || []);
return (
<ServerConfigsContext.Provider value={{ config, setConfig }}>
<QueryClientProvider client={queryClient}>
<CopilotKit
publicApiKey={process.env.NEXT_PUBLIC_COPILOT_CLOUD_API_KEY}
>
<McpServerManager configs={config} />
<ToolRenderer />
{/* <MCPToolCall /> */}
<CoAgentsProvider>{children}</CoAgentsProvider>
</CopilotKit>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</ServerConfigsContext.Provider>
);
}
ServerConfigsContext
:保存已配置的“MCP”服务器列表QueryClientProvider
:连接 React Query<CopilotKit>
:初始化 CopilotKit 运行时(使用您的公共 API 密钥)<McpServerManager>
:从上下文读取配置并告诉 CopilotKit 使用哪些服务器<ToolRenderer>
:捕获所有 CopilotKit“工具调用”并将其呈现为 MCPToolCall 卡<CoAgentsProvider>
:整理代理状态的占位符(目前仅通过子级传递)
⚡ 3. MCP 服务器配置
- MCPConfigModal(
src/components/mcp-config-modal.tsx
):一种模式,可让您添加/删除 SSE 或 stdio 服务器,持久保存到 localStorage,更新上下文和 CopilotKit。 - use-local-storage (
src\hooks\use-local-storage.tsx
) :用于保存这些设置的钩子
由于代码太长,因此我没有将其包括在内。
⚡ 4. 聊天用户界面
- ChatWindow(
src/components/chat-window.tsx
)只是一个样式包装器@copilotkit/react-ui’s <CopilotChat>
- 你通过了:
- “指示”(告诉 AI 始终通过 MCP 服务器并提供当前的待办事项状态)
- 标签、图标、旋转/停止按钮
"use client";
import { useTodo } from "@/contexts/TodoContext";
import { CopilotChat } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";
import { Loader2, RotateCw, SendIcon, Square } from "lucide-react";
import { FC } from "react";
import { Loader } from "./Loader";
export const ChatWindow: FC = () => {
const { todos } = useTodo();
return (
<CopilotChat
className="h-full flex flex-col"
instructions={`Always use the MCP server to complete the task. You will be provided with a list of MCP servers. Use the appropriate MCP server to complete the task.
To perform any actions over the todo task use the following data for manipulation ${JSON.stringify(
todos
)}`}
labels={{
title: "To-do Assistant",
initial:
"Hi! I'm your AI task assistant, powered by MCP servers that you can configure to help manage and break down your tasks. \n\nHow can I help you today?",
placeholder: "Type your message here...",
regenerateResponse: "Try another response",
}}
icons={{
sendIcon: (
<SendIcon className="w-4 h-4 hover:scale-110 transition-transform" />
),
activityIcon: (
<Loader
texts={[
"Thinking...",
"Analyzing Your Query...",
"Taking Action...",
]}
/>
),
spinnerIcon: <Loader2 className="w-4 h-4 animate-spin" />,
stopIcon: (
<Square className="w-4 h-4 hover:text-red-500 transition-colors" />
),
regenerateIcon: (
<RotateCw className="w-4 h-4 hover:rotate-180 transition-transform duration-300" />
),
}}
/>
);
};
⚡ 5. 待办事项状态和操作
- TodoContext(
src/contexts/TodoContext.tsx
)保存内存中的待办事项和子任务列表以及所有 CRUD/切换功能 - TodoApp(
src/components/Todo.tsx
)渲染用于添加/切换/删除任务和子任务的 UI - 在 TodoApp 内部,您还注册了一套 useCopilotAction 钩子(ADD_TASK、ADD_SUBTASK、COMPLETE_TASK 等)和一个用于 JSON 编码列表的 useCopilotReadable。
当 AI 决定调用其中一个操作时,CopilotKit 将调用您的处理程序,以更新相同的 React 上下文。
⚡ 6. 视觉表现
- 视觉呈现 (
src/components/VisualRepresentation.tsx
)- 订阅相同的待办事项上下文
- 每当您的待办事项发生变化时,构建一组“节点”和“边”
- 使用自定义 ParentNode/ChildNode 组件在 React Flow 中呈现树视图(
src/components/Nodes.tsx
) - 点击节点可切换相应的任务/子任务
⚡ 7. 工具调用
- ToolRenderer(
src/components/ToolRenderer.tsx
) 安装一个通配符 useCopilotAction 监听器 - 每次 CopilotKit 发出“工具调用”(即访问 MCP 服务器)时,您都会呈现一个 MCPToolCall 卡(
src/components/MCPToolCall.tsx
)来显示状态、错误/结果等。
⚡ 8. 画布布局
- Canvas(
src/components/canvas.tsx
) 将所有内容缝合在一起:- 左窗格:聊天窗口
- 主区域:两张卡片并排(VisualRepresentation + TodoApp)
- 切换 MCPConfigModal 的“MCP 服务器”按钮
- 在底层,它还会调用 useCopilotChatSuggestions 来呈现 AI 驱动的建议
⚡ 9. UI 基元和实用程序
- src/components/ui/… – 基于基数的按钮、卡片、对话框等,均使用 Tailwind 设置样式
- src/lib/utils.ts – 用于组合 Tailwind 类的小型“cn”助手
- src/hooks – useLocalStorage、useIsMobile
🧠 流程摘要:
这是所有组件的流程。
1) 您通过模态框配置一个或多个 MCP 服务器 → 它们被保存在localStorage
→ 然后通过 传递到 CopilotKit McpServerManager
。
2) 您在聊天中输入一条消息 → CopilotKit 将其路由到 AI → AI 可以ADD_TASK
通过 MCP 服务器“调用”您注册的操作(例如)。
3) 然后ToolRenderer
可视化每个工具调用 → 您的动作处理程序在 React 上下文中更新状态 → TodoApp 和 VisualRepresentation 都使用新状态重新渲染 → 您的聊天流继续。
我相信,如果你打开代码库并了解流程,一切都会变得有意义。
步骤 4:最终演示
您可以在本地运行服务器,并使用copilotkit-mcp-demo.vercel.appnpm run dev
检查实时演示应用程序。
5. 一些具有用例的真实示例。
掌握基础知识后,您可以通过以下一些先进且富有创意的方法将 CopilotKit 与 MCP 结合使用,以构建无代理的强大工作流程。
我们可以使用 MCP 的可组合服务器端点进行链工具交互。
✅ 跨 API 的多步骤工作流自动化。
让我们假设一个示例任务:Fetch unresolved Linear issues, summarize them and send a report to the team via Slack.
技术流程可能是:
MCP Server 1 (Linear)
:使用操作获取线性问题Linear_get_linear_issue
。
-
Local LLM (such as OpenAI)
:使用任何 API 总结问题标题和描述。 -
MCP Server 2 (Slack)
:使用slack_message
操作在定义的频道中发布摘要。
您可以通过提示、工具和 MCP 服务器定义多步骤工作流程。
✅ 语义代码审查助手。
我们可以用自定义逻辑构建一个简单的代码审查助手。
让我们假设一个示例任务:Review this PR using our frontend checklist and comment inline on unoptimized code.
技术流程可能是:
-
GitHub MCP Server
:获取 PR 差异或文件列表。 -
Prompt Templates
:将清单规则加载为结构化提示。 -
LLM (such as OpenAI)
:运行语义分析并生成内联反馈。 -
GitHub MCP
:使用适当的行动,例如post_comment_on_pull_request
留言。
✅ 情境 CRM 助手
我们可以构建根据过去的线索和对话历史做出回应的助手。
让我们假设一个示例任务:Find all unanswered emails from investors and suggest follow-ups based on the last threads.
技术流程可能是:
-
Gmail MCP
:使用 从 Gmail 获取线程列表gmail_list_threads
。 -
LLM + Context Chunking
:使用 OpenAI 函数调用总结最近的线程。 -
Draft Reply
:通过 LLM 生成响应。 -
Gmail MCP
:用于gmail_send_email
发送草稿。
您可以使用 Notion 或 Airtable MCP 进行扩展,以记录交互或添加提醒,例如:Remind me next week if no reply.
这些只是起点。MCP 允许您完全通过提示(逻辑上)自动化几乎任何多工具工作流程。
许多开发者认为集成 MCP 为时过早或过于复杂。但愿 CopilotKit 的内置支持能够证明这一点。
所以,去创造一些疯狂的东西吧。让它变得有用。让世界见证当工作流程与环境相遇时所能创造的一切。
祝你今天过得愉快!下次再见 :)
你可以在anmolbaranwal.com 查看 我的作品。 感谢阅读!🥰 |
![]() ![]() ![]() |
---|
在Twitter上关注 CopilotKit 并打招呼,如果您想构建一些很酷的东西,请加入 Discord 社区。
文章来源:https://dev.to/copilotkit/add-an-mcp-client-to-any-react-app-in-under-30-minutes-55gm