Cortex
一个声明式平台,用于在 Golang 中构建模型上下文协议 (MCP) 服务器——以清晰、结构化的方式公开工具、资源和提示。
FreePeak
README
<h1 align="center"> <img alt="main logo" src="logo.svg" width="150"/> <br/> Cortex </h1> <h4 align="center">在 Golang 中声明式地构建 MCP 服务器</h4>
<p align="center"> <a href="https://pkg.go.dev/github.com/FreePeak/cortex"><img src="https://pkg.go.dev/badge/github.com/FreePeak/cortex.svg" alt="Go Reference"></a> <a href="https://goreportcard.com/report/github.com/FreePeak/cortex"><img src="https://goreportcard.com/badge/github.com/FreePeak/cortex" alt="Go Report Card"></a> <a href="https://github.com/FreePeak/cortex/actions/workflows/go.yml"><img src="https://github.com/FreePeak/cortex/actions/workflows/go.yml/badge.svg" alt="Go Workflow"></a> <a href="https://opensource.org/licenses/Apache-2.0"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache 2.0"></a> <a href="https://github.com/FreePeak/cortex/graphs/contributors"><img src="https://img.shields.io/github/contributors/FreePeak/cortex" alt="Contributors"></a> </p>
目录
概述
模型上下文协议允许应用程序以标准化的方式为 LLM 提供上下文,将提供上下文的关注点与实际的 LLM 交互分离。Cortex 实现了完整的 MCP 规范,使其易于:
- 构建暴露资源和工具的 MCP 服务器
- 使用标准传输方式,如 stdio 和服务器发送事件 (SSE)
- 处理所有 MCP 协议消息和生命周期事件
- 遵循 Go 最佳实践和干净的架构原则
注意: Cortex 始终更新以与 spec.modelcontextprotocol.io/latest 的最新 MCP 规范保持一致
安装
go get github.com/FreePeak/cortex
快速开始
让我们创建一个简单的 MCP 服务器,它暴露一个 echo 工具:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/FreePeak/cortex/pkg/server"
"github.com/FreePeak/cortex/pkg/tools"
)
func main() {
// 创建一个将日志写入 stderr 而不是 stdout 的 logger
// 这对于 STDIO 服务器至关重要,因为 stdout 必须只包含 JSON-RPC 消息
logger := log.New(os.Stderr, "[cortex] ", log.LstdFlags)
// 创建服务器
mcpServer := server.NewMCPServer("Echo Server Example", "1.0.0", logger)
// 创建一个 echo 工具
echoTool := tools.NewTool("echo",
tools.WithDescription("回显输入消息"),
tools.WithString("message",
tools.Description("要回显的消息"),
tools.Required(),
),
)
// 带有数组参数的工具示例
arrayExampleTool := tools.NewTool("array_example",
tools.WithDescription("带有数组参数的示例工具"),
tools.WithArray("values",
tools.Description("字符串值的数组"),
tools.Required(),
tools.Items(map[string]interface{}{
"type": "string",
}),
),
)
// 将工具添加到服务器并添加处理程序
ctx := context.Background()
err := mcpServer.AddTool(ctx, echoTool, handleEcho)
if err != nil {
logger.Fatalf("添加工具时出错: %v", err)
}
err = mcpServer.AddTool(ctx, arrayExampleTool, handleArrayExample)
if err != nil {
logger.Fatalf("添加数组示例工具时出错: %v", err)
}
// 将服务器状态写入 stderr 而不是 stdout,以保持干净的 JSON 协议
fmt.Fprintf(os.Stderr, "启动 Echo Server...\n")
fmt.Fprintf(os.Stderr, "通过 stdin 发送 JSON-RPC 消息与服务器交互。\n")
fmt.Fprintf(os.Stderr, `尝试: {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"echo","parameters":{"message":"Hello, World!"}}}\n`)
// 通过 stdio 提供服务
if err := mcpServer.ServeStdio(); err != nil {
fmt.Fprintf(os.Stderr, "错误: %v\n", err)
os.Exit(1)
}
}
// Echo 工具处理程序
func handleEcho(ctx context.Context, request server.ToolCallRequest) (interface{}, error) {
// 提取 message 参数
message, ok := request.Parameters["message"].(string)
if !ok {
return nil, fmt.Errorf("缺少或无效的 'message' 参数")
}
// 以 MCP 协议期望的格式返回 echo 响应
return map[string]interface{}{
"content": []map[string]interface{}{
{
"type": "text",
"text": message,
},
},
}, nil
}
// 数组示例工具处理程序
func handleArrayExample(ctx context.Context, request server.ToolCallRequest) (interface{}, error) {
// 提取 values 参数
values, ok := request.Parameters["values"].([]interface{})
if !ok {
return nil, fmt.Errorf("缺少或无效的 'values' 参数")
}
// 将 values 转换为字符串数组
stringValues := make([]string, len(values))
for i, v := range values {
stringValues[i] = v.(string)
}
// 以 MCP 协议期望的格式返回数组响应
return map[string]interface{}{
"content": stringValues,
}, nil
}
什么是 MCP?
模型上下文协议 (MCP) 是一种标准化协议,允许应用程序以安全有效的方式为 LLM 提供上下文。它将提供上下文和工具的关注点与实际的 LLM 交互分离。MCP 服务器可以:
- 通过 资源 暴露数据(只读数据端点)
- 通过 工具 提供功能(可执行函数)
- 通过 提示词 定义交互模式(可重用模板)
- 支持各种传输方法(stdio、HTTP/SSE)
核心概念
服务器
MCP 服务器是您与 MCP 协议的核心接口。它处理连接管理、协议合规性和消息路由:
// 创建一个带有 logger 的新 MCP 服务器
mcpServer := server.NewMCPServer("My App", "1.0.0", logger)
工具
工具允许 LLM 通过您的服务器执行操作。与资源不同,工具需要执行计算并具有副作用:
// 定义一个计算器工具
calculatorTool := tools.NewTool("calculator",
tools.WithDescription("执行基本数学运算"),
tools.WithString("operation",
tools.Description("要执行的操作(加、减、乘、除)"),
tools.Required(),
),
tools.WithNumber("a",
tools.Description("第一个操作数"),
tools.Required(),
),
tools.WithNumber("b",
tools.Description("第二个操作数"),
tools.Required(),
),
)
// 将工具添加到服务器并添加处理程序
mcpServer.AddTool(ctx, calculatorTool, handleCalculator)
提供者
提供者允许您将相关的工具和资源分组到一个包中,该包可以轻松地注册到服务器:
// 创建一个天气提供者
weatherProvider, err := weather.NewWeatherProvider(logger)
if err != nil {
logger.Fatalf("创建天气提供者失败: %v", err)
}
// 将提供者注册到服务器
err = mcpServer.RegisterProvider(ctx, weatherProvider)
if err != nil {
logger.Fatalf("注册天气提供者失败: %v", err)
}
资源
资源是您如何向 LLM 暴露数据。它们类似于 REST API 中的 GET 端点 - 它们提供数据,但不应执行重要的计算或具有副作用:
// 创建一个资源(当前使用内部 API)
resource := &domain.Resource{
URI: "sample://hello-world",
Name: "Hello World Resource",
Description: "一个用于演示目的的示例资源",
MIMEType: "text/plain",
}
提示词
提示词是可重用的模板,可帮助 LLM 有效地与您的服务器交互:
// 创建一个提示词(当前使用内部 API)
codeReviewPrompt := &domain.Prompt{
Name: "review-code",
Description: "用于代码审查的提示词",
Template: "请审查此代码:\n\n{{.code}}",
Parameters: []domain.PromptParameter{
{
Name: "code",
Description: "要审查的代码",
Type: "string",
Required: true,
},
},
}
// 注意:提示词支持正在公共 API 中更新
运行你的服务器
Go 中的 MCP 服务器可以根据您的用例连接到不同的传输方式:
STDIO
对于命令行工具和直接集成:
// 启动一个 stdio 服务器
if err := mcpServer.ServeStdio(); err != nil {
fmt.Fprintf(os.Stderr, "错误: %v\n", err)
os.Exit(1)
}
重要提示:使用 STDIO 时,所有日志必须定向到 stderr,以保持 stdout 上干净的 JSON-RPC 协议:
// 创建一个将日志写入 stderr 的 logger
logger := log.New(os.Stderr, "[cortex] ", log.LstdFlags)
// 所有调试/状态消息都应使用 stderr
fmt.Fprintf(os.Stderr, "服务器启动中...\n")
带有 SSE 的 HTTP
对于 Web 应用程序,您可以使用服务器发送事件 (SSE) 进行实时通信:
// 配置 HTTP 地址
mcpServer.SetAddress(":8080")
// 启动一个带有 SSE 支持的 HTTP 服务器
if err := mcpServer.ServeHTTP(); err != nil {
log.Fatalf("HTTP 服务器错误: %v", err)
}
// 为了优雅关闭
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := mcpServer.Shutdown(ctx); err != nil {
log.Fatalf("服务器关闭错误: %v", err)
}
多协议
您还可以通过使用 goroutine 同时运行多个协议服务器:
// 启动一个 HTTP 服务器
go func() {
if err := mcpServer.ServeHTTP(); err != nil {
log.Fatalf("HTTP 服务器错误: %v", err)
}
}()
// 启动一个 STDIO 服务器
go func() {
if err := mcpServer.ServeStdio(); err != nil {
log.Fatalf("STDIO 服务器错误: %v", err)
}
}()
// 等待关闭信号
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
<-stop
测试和调试
对于测试和调试,Cortex 框架提供了几个实用程序:
// 您可以使用 test-call.sh 脚本将测试请求发送到您的 STDIO 服务器
// 例如:
// ./test-call.sh echo '{"message":"Hello, World!"}'
示例
基本示例
该存储库在 examples 目录中包含几个基本示例:
- STDIO 服务器:一个通过 STDIO 通信的简单 MCP 服务器 (
examples/stdio-server) - SSE 服务器:一个使用带有服务器发送事件的 HTTP 进行通信的服务器 (
examples/sse-server) - 多协议:一个可以同时在多个协议上运行的服务器 (
examples/multi-protocol)
高级示例
examples 目录还包含更高级的用例:
- 提供者:如何创建和使用提供者来组织相关工具的示例 (
examples/providers)- 天气提供者:演示如何为与天气相关的工具创建提供者
- 数据库提供者:展示如何为数据库操作创建提供者
插件系统
Cortex 包含一个用于扩展服务器功能的插件系统:
// 基于 BaseProvider 创建一个新的提供者
type MyProvider struct {
*plugin.BaseProvider
}
// 创建一个新的提供者实例
func NewMyProvider(logger *log.Logger) (*MyProvider, error) {
info := plugin.ProviderInfo{
ID: "my-provider",
Name: "My Provider",
Version: "1.0.0",
Description: "一个用于我的工具的自定义提供者",
Author: "您的姓名",
URL: "https://github.com/yourusername/myrepo",
}
baseProvider := plugin.NewBaseProvider(info, logger)
provider := &MyProvider{
BaseProvider: baseProvider,
}
// 将工具注册到提供者
// ...
return provider, nil
}
包结构
Cortex 代码库被组织成几个包:
pkg/server: 核心服务器实现pkg/tools: 工具创建和管理pkg/plugin: 用于扩展服务器功能的插件系统pkg/types: 通用类型和接口pkg/builder: 用于创建复杂对象的构建器
贡献
欢迎贡献!请随时提交 Pull Request。
- Fork 存储库
- 创建您的功能分支 (
git checkout -b feature/amazing-feature) - 提交您的更改 (
git commit -m 'Add some amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 打开一个 Pull Request
许可
该项目根据 Apache License 2.0 获得许可 - 有关详细信息,请参阅 LICENSE 文件。
支持 & 联系
- 如有问题,请发送电子邮件至 mnhatlinh.doan@gmail.com
- 直接打开一个 issue:Issue Tracker
- 如果 Cortex 对您的工作有帮助,请考虑支持:
<p align=""> <a href="https://www.buymeacoffee.com/linhdmn"> <img src="https://img.buymeacoffee.com/button-api/?text=Support Cortex&emoji=☕&slug=linhdmn&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" alt="Buy Me A Coffee"/> </a> </p>
推荐服务器
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
MCP Package Docs Server
促进大型语言模型高效访问和获取 Go、Python 和 NPM 包的结构化文档,通过多语言支持和性能优化来增强软件开发。
Claude Code MCP
一个实现了 Claude Code 作为模型上下文协议(Model Context Protocol, MCP)服务器的方案,它可以通过标准化的 MCP 接口来使用 Claude 的软件工程能力(代码生成、编辑、审查和文件操作)。
@kazuph/mcp-taskmanager
用于任务管理的模型上下文协议服务器。它允许 Claude Desktop(或任何 MCP 客户端)在基于队列的系统中管理和执行任务。
Sequential Thinking MCP Server
这个服务器通过将复杂问题分解为顺序步骤来促进结构化的问题解决,支持修订,并通过完整的 MCP 集成来实现多条解决方案路径。
mermaid-mcp-server
一个模型上下文协议 (MCP) 服务器,用于将 Mermaid 图表转换为 PNG 图像。
Jira-Context-MCP
MCP 服务器向 AI 编码助手(如 Cursor)提供 Jira 工单信息。
Linear MCP Server
一个模型上下文协议(Model Context Protocol)服务器,它与 Linear 的问题跟踪系统集成,允许大型语言模型(LLM)通过自然语言交互来创建、更新、搜索和评论 Linear 问题。
JSON Resume MCP Server
一个服务器,它通过分析你的代码项目来增强 AI 助手的能力,使其能够更新你的 JSON 简历,自动提取技能并生成专业的描述。