Foxy Contexts 是一个用 Golang 编写的库,用于构建支持模型上下文协议(Model Context Protocol)的上下文服务器。该库专注于服务器端,允许开发者通过声明式方法构建上下文服务器,通过定义工具(tools)、资源(resources)和提示(prompts),然后将其注册到应用程序中。
核心功能
- 声明式构建:通过定义工具、资源和提示,然后注册到应用程序中,实现上下文服务器的构建。
- 工具:支持定义工具输入模式并验证输入。
- 资源:支持静态资源、动态资源通过资源提供者以及动态资源通过资源模板。
- 提示:支持提示完成功能。
- 功能测试:提供 foxytest 包进行功能测试。
- 依赖注入:支持依赖注入,方便复用共享部分,如客户端、数据库连接等。
- 日志记录:支持通过 MCP 进行日志记录。
- 采样:支持采样功能。
- 根目录:支持根目录功能。
- 分页:支持分页功能。
- 通知:支持 list_changed 通知。
安装步骤
- 克隆仓库:
git clone https://github.com/strowk/foxy-contexts
- 进入目录:
cd foxy-contexts
- 运行示例:
npx @modelcontextprotocol/inspector go run main.go
- 在浏览器中打开:
http://localhost:5173
- 连接服务器
- 列出工具
- 选择 list-current-dir-files 工具
示例代码
以下是一个简单的示例,演示如何创建一个列出当前目录文件的工具:
package main
import (
"fmt"
"os"
"github.com/strowk/foxy-contexts/pkg/app"
"github.com/strowk/foxy-contexts/pkg/fxctx"
"github.com/strowk/foxy-contexts/pkg/mcp"
"github.com/strowk/foxy-contexts/pkg/stdio"
"go.uber.org/fx"
"go.uber.org/fx/fxevent"
"go.uber.org/zap"
)
func NewListCurrentDirFilesTool() fxctx.Tool {
return fxctx.NewTool(
&mcp.Tool{
Name: "list-current-dir-files",
Description: Ptr("Lists files in the current directory"),
InputSchema: mcp.ToolInputSchema{
Type: "object",
Properties: map[string]map[string]interface{}{},
Required: []string{},
},
},
func(args map[string]interface{}) *mcp.CallToolResult {
files, err := os.ReadDir(".")
if err != nil {
return &mcp.CallToolResult{
IsError: Ptr(true),
Meta: map[string]interface{}{},
Content: []interface{}{
mcp.TextContent{
Type: "text",
Text: fmt.Sprintf("failed to read dir: %v", err),
},
},
}
}
var contents []interface{} = make([]interface{}, len(files))
for i, f := range files {
contents[i] = mcp.TextContent{
Type: "text",
Text: f.Name(),
}
}
return &mcp.CallToolResult{
Meta: map[string]interface{}{},
Content: contents,
IsError: Ptr(false),
}
},
)
}
func main() {
app.NewBuilder().
WithTool(NewListCurrentDirFilesTool).
WithName("list-current-dir-files").
WithVersion("0.0.1").
WithTransport(stdio.NewTransport()).
WithFxOptions(
fx.Provide(func() *zap.Logger {
cfg := zap.NewDevelopmentConfig()
cfg.Level.SetLevel(zap.ErrorLevel)
logger, _ := cfg.Build()
return logger
}),
fx.Option(fx.WithLogger(
func(logger *zap.Logger) fxevent.Logger {
return &fxevent.ZapLogger{Logger: logger}
},
)),
).
Run()
}
func Ptr[T any](v T) *T {
return &v
}
评论