Documentation
¶
Overview ¶
Package mcp implements the Model Context Protocol server for GoatFlow. This enables AI assistants to interact with GoatFlow via API tokens.
Package mcp implements the Model Context Protocol server for GoatFlow. This enables AI assistants to interact with GoatFlow via API tokens.
All MCP tools are dynamically generated from YAML route definitions and the OpenAPI spec. Tool execution invokes the real Gin handlers via the API bridge, so RBAC is enforced by the same middleware stack as the REST API.
Index ¶
- Constants
- Variables
- func AddPluginTools(tools []*GeneratedTool)
- func GetDynamicToolsMap() map[string]*GeneratedTool
- func HandleStreamableHTTPDelete(w http.ResponseWriter, r *http.Request, sessions *SessionManager, userID int)
- func HandleStreamableHTTPGet(w http.ResponseWriter, r *http.Request, sessions *SessionManager, userID int)
- func HandleStreamableHTTPPost(w http.ResponseWriter, r *http.Request, sessions *SessionManager, ...)
- func InitDynamicTools(routes []RouteInput, openapiPath string) error
- func NegotiateProtocolVersion(clientVersion string) string
- func RefreshDynamicTools(routes []RouteInput)
- func WriteSSEEvent(w http.ResponseWriter, flusher http.Flusher, eventType string, data []byte)
- func WriteSSEHeartbeat(w http.ResponseWriter, flusher http.Flusher)
- func WriteSSEMessage(w http.ResponseWriter, flusher http.Flusher, response []byte)
- type APIBridge
- func (b *APIBridge) Execute(ctx context.Context, tool *GeneratedTool, args map[string]any, ...) (*ToolCallResult, error)
- func (b *APIBridge) ExecutePlugin(ctx context.Context, tool *GeneratedTool, args map[string]any, ...) (*ToolCallResult, error)
- func (b *APIBridge) SetPluginCaller(caller PluginCaller)
- type ContentBlock
- type Error
- type GeneratedTool
- type InitializeParams
- type InitializeResult
- type InputSchema
- type OpenAPIOperation
- type OpenAPIParam
- type OpenAPIProp
- type OpenAPISchema
- type OpenAPISpec
- type PluginCaller
- type PluginMCPToolInput
- type PluginRegistration
- type PluginRouteInput
- type Property
- type Request
- type Response
- type RouteInput
- type Server
- type ServerCapabilities
- type ServerInfo
- type Session
- type SessionManager
- type Tool
- type ToolCallParams
- type ToolCallResult
- type ToolsCapability
- type ToolsListResult
- type UserContext
Constants ¶
const ( ErrCodeParse = -32700 ErrCodeInvalidRequest = -32600 ErrCodeMethodNotFound = -32601 ErrCodeInvalidParams = -32602 ErrCodeInternal = -32603 )
Standard JSON-RPC error codes
const ( ProtocolVersion = "2024-11-05" ServerName = "goatflow-mcp" ServerVersion = "0.7.0" )
const ( // ProtocolVersion202503 is the MCP Streamable HTTP protocol version. ProtocolVersion202503 = "2025-03-26" // SessionHeader is the HTTP header for MCP session identification. SessionHeader = "Mcp-Session-Id" // SSEHeartbeatInterval is the keepalive interval for SSE connections. SSEHeartbeatInterval = 30 * time.Second )
Variables ¶
var SupportedProtocolVersions = []string{ProtocolVersion202503, ProtocolVersion}
SupportedProtocolVersions lists all MCP protocol versions this server supports.
Functions ¶
func AddPluginTools ¶ added in v0.8.2
func AddPluginTools(tools []*GeneratedTool)
AddPluginTools adds plugin-provided tools to the dynamic registry. Called after plugin loading and on plugin enable/disable.
func GetDynamicToolsMap ¶ added in v0.8.2
func GetDynamicToolsMap() map[string]*GeneratedTool
GetDynamicToolsMap returns the tool lookup map. Thread-safe.
func HandleStreamableHTTPDelete ¶ added in v0.8.2
func HandleStreamableHTTPDelete( w http.ResponseWriter, r *http.Request, sessions *SessionManager, userID int, )
HandleStreamableHTTPDelete handles DELETE requests to terminate an MCP session.
func HandleStreamableHTTPGet ¶ added in v0.8.2
func HandleStreamableHTTPGet( w http.ResponseWriter, r *http.Request, sessions *SessionManager, userID int, )
HandleStreamableHTTPGet handles GET requests for the MCP SSE notification stream. Keeps the connection open and sends server-initiated notifications.
func HandleStreamableHTTPPost ¶ added in v0.8.2
func HandleStreamableHTTPPost( w http.ResponseWriter, r *http.Request, sessions *SessionManager, bridge *APIBridge, userID int, userLogin, userRole string, )
HandleStreamableHTTPPost handles POST requests for the MCP Streamable HTTP transport. For "initialize" requests: creates a session and returns the session ID in response headers. For other requests: processes via the session's server and returns JSON or SSE.
func InitDynamicTools ¶ added in v0.8.2
func InitDynamicTools(routes []RouteInput, openapiPath string) error
InitDynamicTools generates MCP tools from pre-parsed route data and an OpenAPI spec file. The caller (in internal/api) is responsible for parsing YAML routes and converting them to RouteInput values — this avoids an import cycle between mcp and api packages. Safe to call multiple times — only executes once.
func NegotiateProtocolVersion ¶ added in v0.8.2
NegotiateProtocolVersion returns the best protocol version both client and server support.
func RefreshDynamicTools ¶ added in v0.8.2
func RefreshDynamicTools(routes []RouteInput)
RefreshDynamicTools regenerates MCP tools from updated route data. Called when plugins lazy-load and register new routes.
func WriteSSEEvent ¶ added in v0.8.2
WriteSSEEvent writes a single SSE event to the writer and flushes.
func WriteSSEHeartbeat ¶ added in v0.8.2
func WriteSSEHeartbeat(w http.ResponseWriter, flusher http.Flusher)
WriteSSEHeartbeat sends a comment line to keep the connection alive.
func WriteSSEMessage ¶ added in v0.8.2
func WriteSSEMessage(w http.ResponseWriter, flusher http.Flusher, response []byte)
WriteSSEMessage writes a JSON-RPC response as an SSE "message" event.
Types ¶
type APIBridge ¶ added in v0.8.2
type APIBridge struct {
// contains filtered or unexported fields
}
APIBridge executes generated MCP tools by invoking real Gin handlers with a synthetic request context. RBAC middleware runs as normal. For plugin tools, it delegates to the PluginCaller.
func NewAPIBridge ¶ added in v0.8.2
func NewAPIBridge() *APIBridge
NewAPIBridge creates a new API bridge.
func (*APIBridge) Execute ¶ added in v0.8.2
func (b *APIBridge) Execute(ctx context.Context, tool *GeneratedTool, args map[string]any, user UserContext) (*ToolCallResult, error)
Execute invokes the Gin handler for a generated tool, running RBAC middleware.
func (*APIBridge) ExecutePlugin ¶ added in v0.8.2
func (b *APIBridge) ExecutePlugin(ctx context.Context, tool *GeneratedTool, args map[string]any, user UserContext) (*ToolCallResult, error)
ExecutePlugin invokes a plugin handler via the plugin manager. It constructs the same args object that buildPluginArgs does in plugin_handlers.go, merging tool arguments with user context fields.
func (*APIBridge) SetPluginCaller ¶ added in v0.8.2
func (b *APIBridge) SetPluginCaller(caller PluginCaller)
SetPluginCaller sets the plugin manager for executing plugin tools.
type ContentBlock ¶
ContentBlock represents content in a tool result.
type Error ¶
type Error struct {
Code int `json:"code"`
Message string `json:"message"`
Data any `json:"data,omitempty"`
}
Error represents a JSON-RPC 2.0 error.
type GeneratedTool ¶ added in v0.8.2
type GeneratedTool struct {
Tool
HandlerName string // registered handler name, e.g. "HandleGetTicketAPI"
Method string // HTTP method: GET, POST, PUT, DELETE
Path string // full path with Gin params, e.g. "/api/v1/tickets/:id"
Middleware []string // combined group + route middleware tokens
PathParams []string // extracted from :param segments, e.g. ["id"]
IsPlugin bool // true if this is a plugin-provided tool
PluginName string // plugin name (only if IsPlugin)
}
GeneratedTool extends Tool with routing metadata needed for execution.
func GeneratePluginTools ¶ added in v0.8.2
func GeneratePluginTools(plugins []PluginRegistration) []*GeneratedTool
GeneratePluginTools creates MCP tools from plugin registrations. Route-based tools are auto-generated; MCPTools override them on name collision.
type InitializeParams ¶
type InitializeParams struct {
ProtocolVersion string `json:"protocolVersion"`
ClientInfo struct {
Name string `json:"name"`
Version string `json:"version"`
} `json:"clientInfo"`
}
InitializeParams are sent by the client during initialization.
type InitializeResult ¶
type InitializeResult struct {
ProtocolVersion string `json:"protocolVersion"`
ServerInfo ServerInfo `json:"serverInfo"`
Capabilities ServerCapabilities `json:"capabilities"`
}
InitializeResult is returned after successful initialization.
type InputSchema ¶
type InputSchema struct {
Type string `json:"type"`
Properties map[string]Property `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
}
InputSchema defines the JSON Schema for tool inputs.
type OpenAPIOperation ¶ added in v0.8.2
type OpenAPIOperation struct {
Summary string
Description string
Parameters []OpenAPIParam
BodySchema *OpenAPISchema // nil for GET/DELETE
}
OpenAPIOperation holds extracted metadata for a single API operation.
type OpenAPIParam ¶ added in v0.8.2
type OpenAPIParam struct {
Name string
In string // "query", "path", "header"
Description string
Required bool
Type string // "string", "integer", "number", "boolean"
}
OpenAPIParam represents a query or path parameter from the spec.
type OpenAPIProp ¶ added in v0.8.2
OpenAPIProp represents a single property in a schema.
type OpenAPISchema ¶ added in v0.8.2
type OpenAPISchema struct {
Properties map[string]OpenAPIProp
Required []string
}
OpenAPISchema represents properties of a request body schema.
type OpenAPISpec ¶ added in v0.8.2
type OpenAPISpec struct {
// contains filtered or unexported fields
}
OpenAPISpec holds the parsed portions of an OpenAPI 3.0 spec needed for MCP tool schema generation.
func ParseOpenAPIFile ¶ added in v0.8.2
func ParseOpenAPIFile(path string) (*OpenAPISpec, error)
ParseOpenAPIFile loads and parses an OpenAPI YAML file.
func (*OpenAPISpec) LookupOperation ¶ added in v0.8.2
func (s *OpenAPISpec) LookupOperation(method, path string) *OpenAPIOperation
LookupOperation finds the OpenAPI operation for a given method and path. The path uses OpenAPI format ({id}) not Gin format (:id).
type PluginCaller ¶ added in v0.8.2
type PluginCaller interface {
Call(ctx context.Context, pluginName, fn string, args []byte) ([]byte, error)
}
PluginCaller is the interface for calling plugin functions. Matches the signature of plugin.Manager.Call to avoid a direct import.
type PluginMCPToolInput ¶ added in v0.8.2
type PluginMCPToolInput struct {
Name string
Description string
Handler string
InputSchema map[string]any
}
PluginMCPToolInput mirrors plugin.MCPToolSpec for MCP tool generation.
type PluginRegistration ¶ added in v0.8.2
type PluginRegistration struct {
Name string
Routes []PluginRouteInput
MCPTools []PluginMCPToolInput
}
PluginRegistration holds the data needed to generate MCP tools from a plugin. Mirrors the relevant fields from pkg/plugin.GKRegistration to avoid import cycles.
type PluginRouteInput ¶ added in v0.8.2
type PluginRouteInput struct {
Method string
Path string
Handler string
Middleware []string
Description string
}
PluginRouteInput mirrors plugin.RouteSpec for MCP tool generation.
type Property ¶
type Property struct {
Type string `json:"type"`
Description string `json:"description,omitempty"`
Enum []string `json:"enum,omitempty"`
Default any `json:"default,omitempty"`
}
Property defines a single property in the input schema.
type Request ¶
type Request struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
}
Request represents a JSON-RPC 2.0 request.
type Response ¶
type Response struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Result any `json:"result,omitempty"`
Error *Error `json:"error,omitempty"`
}
Response represents a JSON-RPC 2.0 response.
func ErrorResponse ¶
Helper to create an error response
func SuccessResponse ¶
Helper to create a success response
type RouteInput ¶ added in v0.8.2
type RouteInput struct {
GroupName string
Prefix string
GroupMiddleware []string
Path string
Method string
HandlerName string
Middleware []string
Description string
MCPDescription string
MCPEnabled *bool // nil = include, false = exclude
RedirectTo string
Websocket bool
}
RouteInput is the data needed from a YAML route to generate an MCP tool. Defined here to avoid importing internal/api (which imports internal/mcp).
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server handles MCP protocol messages. Each request is authenticated by an API token, and the token owner's permissions are enforced via middleware when tools invoke API handlers.
type ServerCapabilities ¶
type ServerCapabilities struct {
Tools *ToolsCapability `json:"tools,omitempty"`
}
ServerCapabilities describes what this server supports.
type ServerInfo ¶
ServerInfo describes this MCP server.
type Session ¶ added in v0.8.2
type Session struct {
ID string
UserID int
UserLogin string
UserRole string
Server *Server
Created time.Time
LastActive time.Time
NotifyChan chan []byte // server→client notifications
}
Session holds the state for a single MCP SSE connection.
type SessionManager ¶ added in v0.8.2
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages MCP SSE sessions.
func NewSessionManager ¶ added in v0.8.2
func NewSessionManager(maxAge time.Duration) *SessionManager
NewSessionManager creates a session manager with a given inactivity timeout.
func (*SessionManager) Count ¶ added in v0.8.2
func (sm *SessionManager) Count() int
Count returns the number of active sessions.
func (*SessionManager) Create ¶ added in v0.8.2
func (sm *SessionManager) Create(userID int, userLogin, userRole string, bridge *APIBridge) *Session
Create creates a new session for the given user.
func (*SessionManager) Delete ¶ added in v0.8.2
func (sm *SessionManager) Delete(id string)
Delete removes a session.
func (*SessionManager) Get ¶ added in v0.8.2
func (sm *SessionManager) Get(id string) *Session
Get retrieves a session by ID and updates its last active time.
type Tool ¶
type Tool struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
InputSchema InputSchema `json:"inputSchema"`
}
Tool represents an MCP tool definition.
func GetDynamicTools ¶ added in v0.8.2
func GetDynamicTools() []Tool
GetDynamicTools returns the generated tool list. Thread-safe.
type ToolCallParams ¶
type ToolCallParams struct {
Name string `json:"name"`
Arguments map[string]any `json:"arguments,omitempty"`
}
ToolCallParams are the parameters for calling a tool.
type ToolCallResult ¶
type ToolCallResult struct {
Content []ContentBlock `json:"content"`
IsError bool `json:"isError,omitempty"`
}
ToolCallResult is the result of a tool call.
type ToolsCapability ¶
type ToolsCapability struct {
ListChanged bool `json:"listChanged,omitempty"`
}
ToolsCapability indicates tool support.
type ToolsListResult ¶
type ToolsListResult struct {
Tools []Tool `json:"tools"`
}
ToolsListResult contains the list of available tools.