From b587474faef398cffa4f33b20564736a6e2225a5 Mon Sep 17 00:00:00 2001 From: Jonathan Vuillemin Date: Thu, 8 May 2025 15:23:22 +0200 Subject: [PATCH] doc(fxmcpserver): Updated documentation --- docs/modules/fxmcpserver.md | 61 ++++++++++++++++++++++++ fxmcpserver/README.md | 94 ++++++++++++++++++------------------- 2 files changed, 108 insertions(+), 47 deletions(-) diff --git a/docs/modules/fxmcpserver.md b/docs/modules/fxmcpserver.md index 8b8a78c5..31c93a61 100644 --- a/docs/modules/fxmcpserver.md +++ b/docs/modules/fxmcpserver.md @@ -23,6 +23,7 @@ It comes with: - automatic requests logging and tracing (method, target, duration, ...) - automatic requests metrics (count and duration) - possibility to register MCP resources, resource templates, prompts and tools +- possibility to register MCP SSE server context hooks - possibility to expose the MCP server via Stdio (local) and/or HTTP SSE (remote) ## Installation @@ -516,6 +517,66 @@ modules: tools: true # to expose MCP tools (disabled by default) ``` +## Hooks + +This module offers the possibility to provide context hooks with [MCPSSEServerContextHook](https://github.com/ankorstore/yokai/blob/main/fxmcpserver/server/sse/context.go) implementations, that will be applied on each MCP SSE request. + +For example, an MCP SSE server context hook that adds a config value to the context: + +```go title="internal/mcp/resource/readme.go" +package hook + +import ( + "context" + "net/http" + + "github.com/ankorstore/yokai/config" + "github.com/mark3labs/mcp-go/mcp" + "github.com/mark3labs/mcp-go/server" +) + +type ExampleHook struct { + config *config.Config +} + +func NewExampleHook(config *config.Config) *ExampleHook { + return &ExampleHook{ + config: config, + } +} + +func (h *ExampleHook) Handle() server.SSEContextFunc { + return func(ctx context.Context, r *http.Request) context.Context { + return context.WithValue(ctx, "foo", h.config.GetString("foo")) + } +} +``` + +You can register your MCP SSE server context hook: + +- with `AsMCPSSEServerContextHook()` to register a single MCP SSE server context hook +- with `AsMCPSSEServerContextHooks()` to register several MCP SSE server context hooks at once + +```go title="internal/register.go" +package internal + +import ( + "github.com/ankorstore/yokai/fxmcpserver" + "github.com/foo/bar/internal/mcp/hook" + "go.uber.org/fx" +) + +func Register() fx.Option { + return fx.Options( + // registers ReadmeResource as MCP resource + fxmcpserver.AsMCPSSEServerContextHook(hook.NewExampleHook), + // ... + ) +} +``` + +The dependencies of your MCP SSE server context hooks will be autowired. + ## Logging You can configure the MCP server requests and responses automatic logging: diff --git a/fxmcpserver/README.md b/fxmcpserver/README.md index e969c634..182a2e7d 100644 --- a/fxmcpserver/README.md +++ b/fxmcpserver/README.md @@ -12,16 +12,16 @@ * [Installation](#installation) * [Features](#features) * [Documentation](#documentation) - * [Dependencies](#dependencies) - * [Loading](#loading) - * [Configuration](#configuration) - * [Registration](#registration) - * [Resources](#resources) - * [Resource templates](#resource-templates) - * [Prompts](#prompts) - * [Tools](#tools) - * [Hooks](#hooks) - * [Testing](#testing) + * [Dependencies](#dependencies) + * [Loading](#loading) + * [Configuration](#configuration) + * [Registration](#registration) + * [Resources](#resources) + * [Resource templates](#resource-templates) + * [Prompts](#prompts) + * [Tools](#tools) + * [Hooks](#hooks) + * [Testing](#testing) ## Installation @@ -109,7 +109,7 @@ modules: prompts: true # to expose MCP prompts (disabled by default) tools: true # to expose MCP tools (disabled by default) transport: - sse: + sse: expose: true # to remotely expose the MCP server via SSE (disabled by default) address: ":8082" # exposition address (":8082" by default) base_url: "" # base url ("" by default) @@ -250,7 +250,7 @@ package main import ( "context" - + "github.com/foo/bar/internal/user" "github.com/ankorstore/yokai/config" @@ -553,59 +553,59 @@ modules: ``` ### Hooks -This module offers the possibility to provide context hooks with [MCPSSEServerContextHook](server/sse/context.go) implementations, applied on each MCP SSE request. +This module offers the possibility to provide context hooks with [MCPSSEServerContextHook](server/sse/context.go) implementations, that will be applied on each MCP SSE request. -You can use the `AsMCPSSEServerMiddleware()` function to register an MCP SSE server middleware, or `AsMCPSSEServerMiddlewares()` to register several MCP SSE server middlewares at once. +You can use the `AsMCPSSEServerContextHook()` function to register an MCP SSE server context hook, or `AsMCPSSEServerContextHooks()` to register several MCP SSE server context hooks at once. -The dependencies of your MCP SSE server middlewares will be autowired. +The dependencies of your MCP SSE server context hooks will be autowired. ```go package main import ( - "context" - "net/http" - - "github.com/ankorstore/yokai/config" - "github.com/ankorstore/yokai/fxconfig" - "github.com/ankorstore/yokai/fxgenerate" - "github.com/ankorstore/yokai/fxlog" - "github.com/ankorstore/yokai/fxmcpserver" - "github.com/ankorstore/yokai/fxmetrics" - "github.com/ankorstore/yokai/fxtrace" - "github.com/mark3labs/mcp-go/mcp" - "github.com/mark3labs/mcp-go/server" - "go.uber.org/fx" + "context" + "net/http" + + "github.com/ankorstore/yokai/config" + "github.com/ankorstore/yokai/fxconfig" + "github.com/ankorstore/yokai/fxgenerate" + "github.com/ankorstore/yokai/fxlog" + "github.com/ankorstore/yokai/fxmcpserver" + "github.com/ankorstore/yokai/fxmetrics" + "github.com/ankorstore/yokai/fxtrace" + "github.com/mark3labs/mcp-go/mcp" + "github.com/mark3labs/mcp-go/server" + "go.uber.org/fx" ) type ExampleHook struct { - config *config.Config + config *config.Config } func NewExampleHook(config *config.Config) *ExampleHook { - return &ExampleHook{ - config: config, - } + return &ExampleHook{ + config: config, + } } -func (r *ExampleHook) Handle() server.SSEContextFunc { - return func(ctx context.Context, r *http.Request) context.Context { - return context.WithValue(ctx, "foo", "bar") - } +func (h *ExampleHook) Handle() server.SSEContextFunc { + return func(ctx context.Context, r *http.Request) context.Context { + return context.WithValue(ctx, "foo", h.config.GetString("foo")) + } } func main() { - fx.New( - fxconfig.FxConfigModule, - fxlog.FxLogModule, - fxtrace.FxTraceModule, - fxmetrics.FxMetricsModule, - fxgenerate.FxGenerateModule, - fxmcpserver.FxMCPServerModule, - fx.Options( - fxmcpserver.AsMCPSSEServerContextHook(NewExampleHook), // registers the NewExampleHook as MCP SSE server context hook - ), - ).Run() + fx.New( + fxconfig.FxConfigModule, + fxlog.FxLogModule, + fxtrace.FxTraceModule, + fxmetrics.FxMetricsModule, + fxgenerate.FxGenerateModule, + fxmcpserver.FxMCPServerModule, + fx.Options( + fxmcpserver.AsMCPSSEServerContextHook(NewExampleHook), // registers the NewExampleHook as MCP SSE server context hook + ), + ).Run() } ```