mcp

package
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 19, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

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

View Source
const (
	ErrCodeParse          = -32700
	ErrCodeInvalidRequest = -32600
	ErrCodeMethodNotFound = -32601
	ErrCodeInvalidParams  = -32602
	ErrCodeInternal       = -32603
)

Standard JSON-RPC error codes

View Source
const (
	ProtocolVersion = "2024-11-05"
	ServerName      = "goatflow-mcp"
	ServerVersion   = "0.7.0"
)
View Source
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

View Source
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

func NegotiateProtocolVersion(clientVersion string) string

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

func WriteSSEEvent(w http.ResponseWriter, flusher http.Flusher, eventType string, data []byte)

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

type ContentBlock struct {
	Type string `json:"type"`
	Text string `json:"text,omitempty"`
}

ContentBlock represents content in a tool result.

func TextContent

func TextContent(text string) ContentBlock

Helper to create a text content block

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

type OpenAPIProp struct {
	Type        string
	Description string
	Enum        []string
	Default     any
	Format      string
}

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

func ErrorResponse(id any, code int, message string) Response

Helper to create an error response

func SuccessResponse

func SuccessResponse(id any, result any) Response

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.

func NewServer

func NewServer(userID int, userLogin, userRole string, bridge *APIBridge) *Server

NewServer creates a new MCP server instance.

func (*Server) HandleMessage

func (s *Server) HandleMessage(ctx context.Context, msg []byte) ([]byte, error)

HandleMessage processes a JSON-RPC message and returns a response.

type ServerCapabilities

type ServerCapabilities struct {
	Tools *ToolsCapability `json:"tools,omitempty"`
}

ServerCapabilities describes what this server supports.

type ServerInfo

type ServerInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

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.

type UserContext added in v0.8.2

type UserContext struct {
	UserID    int
	UserLogin string
	UserEmail string
	UserRole  string
}

UserContext carries the authenticated user's identity for bridge calls.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL