Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 2 additions & 15 deletions backend/cmd/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,8 @@ func main() {
mcpServer := mcp.NewMCPServer(repoService, docService)
klog.V(6).Info("MCP Server 已初始化")

// 创建 SSE Server 实例并复用(避免每次请求创建新实例)
// 配置 basePath 为 /mcp,使 SSE Server 正确处理 /mcp/sse 和 /mcp/message 路径
sseServer := server.NewSSEServer(mcpServer.GetServer(), server.WithStaticBasePath("/mcp"))

// 创建 Streamable HTTP Server 实例
// Streamable HTTP 是 MCP 协议的另一种传输层实现,支持同步 HTTP 响应和流式事件
// Streamable HTTP 是 MCP 协议的传输层实现,支持同步 HTTP 响应和流式事件
streamableServer := server.NewStreamableHTTPServer(mcpServer.GetServer())

// 启动时清理卡住的任务(超过 10 分钟的运行中任务)
Expand All @@ -229,21 +225,12 @@ func main() {
// 设置路由
r := router.Setup(cfg, repoHandler, taskHandler, docHandler, apiKeyHandler, syncHandler, userRequestHandler, openAPIHandler, activityHandler, agentHandler, chatHandler)

// 添加 MCP SSE 端点
// 提供 /mcp/sse 端点,供 Cursor、Claude Code 等 AI 编程工具使用
r.GET("/mcp/sse", func(c *gin.Context) {
sseServer.ServeHTTP(c.Writer, c.Request)
})
// 添加 /mcp/message 端点,支持客户端发送 JSON-RPC 消息
r.POST("/mcp/message", func(c *gin.Context) {
sseServer.ServeHTTP(c.Writer, c.Request)
})
// 添加 MCP Streamable HTTP 端点
// Streamable HTTP 使用单个端点处理 GET(流式事件)和 POST(JSON-RPC 请求)
r.Any("/mcp/streamable", func(c *gin.Context) {
streamableServer.ServeHTTP(c.Writer, c.Request)
})
klog.V(6).Info("MCP 端点已注册: /mcp/sse, /mcp/message, /mcp/streamable")
klog.V(6).Info("MCP 端点已注册: /mcp/streamable")

//eino callbacks注册
callbacks := adkagents.NewEinoCallbacks(true, 8)
Expand Down
74 changes: 5 additions & 69 deletions frontend/src/pages/MCPPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,6 @@ const mcpTools = [
},
];

// MCP 配置文件模板 - SSE 传输
const getMCPConfigSSE = (baseUrl: string) => ({
"mcpServers": {
"openDeepWiki": {
"type": "sse",
"url": `${baseUrl}/mcp/sse`,
"timeout": 30000
}
}
});

// MCP 配置文件模板 - Streamable HTTP 传输
const getMCPConfigStreamable = (baseUrl: string) => ({
"mcpServers": {
Expand All @@ -93,9 +82,7 @@ export default function MCPPage() {
setBaseUrl(currentUrl);
}, []);

const mcpConfigSSE = getMCPConfigSSE(baseUrl || 'http://localhost:8080');
const mcpConfigStreamable = getMCPConfigStreamable(baseUrl || 'http://localhost:8080');
const configJsonSSE = JSON.stringify(mcpConfigSSE, null, 2);
const configJsonStreamable = JSON.stringify(mcpConfigStreamable, null, 2);

const handleCopy = async (config: string, type: string) => {
Expand Down Expand Up @@ -166,18 +153,6 @@ export default function MCPPage() {
<Space direction="vertical" size="small">
<Space>
<Badge status="success" text="运行中" />
<Tag color="blue">SSE</Tag>
<Text code>{baseUrl}/mcp/sse</Text>
<Text type="secondary">• GET 建立流</Text>
</Space>
<Space>
<Badge status="success" text="" />
<Tag color="blue">SSE</Tag>
<Text code>{baseUrl}/mcp/message</Text>
<Text type="secondary">• POST 发送消息</Text>
</Space>
<Space>
<Badge status="success" text="" />
<Tag color="green">Streamable HTTP</Tag>
<Text code>{baseUrl}/mcp/streamable</Text>
<Text type="secondary">• GET 流式 + POST 同步</Text>
Expand Down Expand Up @@ -205,18 +180,16 @@ export default function MCPPage() {
<List
bordered
dataSource={[
{ label: 'SSE 端点', value: `${baseUrl}/mcp/sse`, transport: 'SSE' },
{ label: '消息端点', value: `${baseUrl}/mcp/message`, transport: 'SSE' },
{ label: 'Streamable HTTP', value: `${baseUrl}/mcp/streamable`, transport: 'Streamable HTTP' },
{ label: '协议版本', value: 'MCP 2024-11-05', transport: '' },
{ label: '协议版本', value: 'MCP 2025-11-25', transport: '' },
]}
renderItem={(item) => (
<List.Item>
<Text strong style={{ width: 160, display: 'inline-block' }}>{item.label}:</Text>
<CodeOutlined />
<Text code copyable>{item.value}</Text>
{item.transport && (
<Tag color="blue" style={{ marginLeft: 8 }}>{item.transport}</Tag>
<Tag color="green" style={{ marginLeft: 8 }}>{item.transport}</Tag>
)}
</List.Item>
)}
Expand Down Expand Up @@ -277,43 +250,6 @@ export default function MCPPage() {
),
children: (
<Space direction="vertical" size="large" style={{ width: '100%' }}>
<Card
title={
<Space>
<CodeOutlined />
SSE 配置文件
</Space>
}
extra={
<Button
type="primary"
icon={copied === 'sse' ? <CheckOutlined /> : <CopyOutlined />}
onClick={() => handleCopy(configJsonSSE, 'sse')}
size="small"
>
{copied === 'sse' ? '已复制' : '复制配置'}
</Button>
}
>
<Alert
message="SSE 传输方式"
description="适用于大多数 MCP 客户端(如 Cursor、Claude Code、Windsurf)。使用 Server-Sent Events 进行双向通信。"
type="info"
showIcon
style={{ marginBottom: 16 }}
/>
<pre style={{
background: 'var(--ant-color-bg-layout)',
padding: 16,
borderRadius: 8,
overflow: 'auto',
fontSize: 13,
lineHeight: 1.6
}}>
<code>{configJsonSSE}</code>
</pre>
</Card>

<Card
title={
<Space>
Expand All @@ -334,7 +270,7 @@ export default function MCPPage() {
>
<Alert
message="Streamable HTTP 传输方式"
description="MCP 协议的另一种传输层实现,支持同步 HTTP 响应和流式事件。单端点同时处理 GET(流式)和 POST(JSON-RPC)。"
description="MCP 协议的传输层实现,支持同步 HTTP 响应和流式事件。单端点同时处理 GET(流式)和 POST(JSON-RPC)。"
type="success"
showIcon
style={{ marginBottom: 16 }}
Expand Down Expand Up @@ -364,7 +300,7 @@ export default function MCPPage() {
<Title level={5}>1. Cursor 配置</Title>
<Paragraph>
打开 Cursor Settings → MCP,点击 "Add New MCP Server",
选择 SSE 类型,填入 URL: <Text code>{baseUrl}/mcp/sse</Text>
选择 Streamable HTTP 类型,填入 URL: <Text code>{baseUrl}/mcp/streamable</Text>
</Paragraph>
</div>

Expand All @@ -384,7 +320,7 @@ export default function MCPPage() {
<Title level={5}>3. Windsurf 配置</Title>
<Paragraph>
打开 Windsurf Settings → AI → MCP,
添加新的 MCP Server,填入 SSE URL: <Text code>{baseUrl}/mcp/sse</Text>
添加新的 MCP Server,填入 URL: <Text code>{baseUrl}/mcp/streamable</Text>
</Paragraph>
</div>

Expand Down
Loading