chore: initial release v0.1.0
forge-toolkit: хелперы для разработки MCP-серверов на Go. - toolkit: args/schema/result/env/probe/server - toolkit/validate: валидаторы синтаксиса - configreload: live-reload конфига по контент-хэшу - docs: ARCHITECTURE, quickstart, mcp-contract - template/ и examples/hello-tool/ - CI (Gitea Actions), лицензия Apache-2.0
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package toolkit
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
// Ключи forge-специфичных метаданных в стандартном поле `_meta` (SEP-2575).
|
||||
// MCP-хост forge, вызвав инструмент с флагом probe, ожидает, что сервер НЕ
|
||||
// выполнит действие, а вернёт эмитированные permission-паттерны. Константы
|
||||
// дублируются на стороне хоста: хост не импортирует этот пакет.
|
||||
const (
|
||||
metaProbeKey = "forge.permission_patterns"
|
||||
metaPatternsKey = "forge.patterns"
|
||||
metaAlwaysKey = "forge.always"
|
||||
// metaCapabilityKey — флаг в Tool.Meta: сервер объявляет поддержку
|
||||
// forge-протокола эмитированных паттернов. Хост проверяет его перед
|
||||
// probe, чтобы не слать probe серверам без поддержки.
|
||||
metaCapabilityKey = "forge.supports_permission_patterns"
|
||||
)
|
||||
|
||||
// PatternsFn вычисляет эмитированные permission-паттерны и безопасные
|
||||
// префиксы "always" по аргументам инструмента. nil — инструмент паттернов
|
||||
// не эмитирует (хост применит политику по умолчанию).
|
||||
type PatternsFn func(args map[string]any) (patterns, always []string)
|
||||
|
||||
// WrapProbe оборачивает handler, перехватывая probe-запрос хоста: вместо
|
||||
// выполнения действия возвращает `_meta` с паттернами.
|
||||
func WrapProbe(h mcp.ToolHandler, fn PatternsFn) mcp.ToolHandler {
|
||||
return func(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
if IsProbe(req) {
|
||||
var patterns, always []string
|
||||
if fn != nil {
|
||||
patterns, always = fn(RequestArgs(req))
|
||||
}
|
||||
return &mcp.CallToolResult{
|
||||
Meta: mcp.Meta{metaPatternsKey: patterns, metaAlwaysKey: always},
|
||||
}, nil
|
||||
}
|
||||
return h(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterPatternTool регистрирует инструмент с поддержкой forge-probe:
|
||||
// помечает Tool.Meta флагом поддержки и оборачивает handler. Без флага хост
|
||||
// не стал бы слать probe-вызов.
|
||||
func RegisterPatternTool(s *mcp.Server, tool *mcp.Tool, fn PatternsFn, h mcp.ToolHandler) {
|
||||
if tool.Meta == nil {
|
||||
tool.Meta = mcp.Meta{}
|
||||
}
|
||||
tool.Meta[metaCapabilityKey] = true
|
||||
s.AddTool(tool, WrapProbe(h, fn))
|
||||
}
|
||||
|
||||
// IsProbe сообщает, является ли вызов probe-запросом паттернов.
|
||||
func IsProbe(req *mcp.CallToolRequest) bool {
|
||||
if req == nil || req.Params == nil {
|
||||
return false
|
||||
}
|
||||
v, ok := req.Params.GetMeta()[metaProbeKey]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
b, _ := v.(bool)
|
||||
return b
|
||||
}
|
||||
Reference in New Issue
Block a user