[FEATURE] reflective mcp client server functionality in go-sdk.

Resolved 💬 2 comments Opened May 8, 2026 by owensk Closed May 11, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

---
Request: expose generic request/notification sending + handler registration in go-sdk's Client and Server

Context: Building a CLI coding agent (Loom) in Go on top of github.com/modelcontextprotocol/go-sdk v1.6.0. Excellent typed-handler surface via AddTool[In, Out] +
jsonschema-go inference — that part is a real upgrade over the community alternatives.

Gap: The SDK's Client / ClientSession only exposes spec-named methods (CallTool, ListTools, Ping, etc.) and the Server only accepts spec-named handlers (AddTool, AddPrompt,
AddResource, AddNotificationHandler). There's no equivalent of mcp-go's transport.Interface.SendRequest(ctx, JSONRPCRequest) — and no server-side AddRequestHandler(method
string, h MethodHandler) — so applications can't introduce vendor-prefixed extension methods over an otherwise standard MCP session. AddSendingMiddleware /
AddReceivingMiddleware wrap existing methods but can't originate or serve new ones.

Use case: we want a loom/derive_lane request so each tool can answer "what's my dispatcher-lane URI for these args?" at dispatch time (e.g. git's rev-parse
--show-toplevel). We end up registering a hidden companion tool (__loom_derive_lane_v1) and routing through CallTool, which works but pollutes the tool registry, requires a
visibility filter on every LLM-facing list path, and conceptually mis-models "this is an extension method" as "this is a tool."

Asks (in rough priority):

  1. Server.AddRequestHandler(method string, h MethodHandler) and AddNotificationHandler equivalent that already accepts arbitrary method names. Validate the method has a

vendor prefix (^[a-z]+/[a-z_]+$ or similar) so standard names can't be shadowed.

  1. ClientSession.Send(ctx, method, params, result any) error — generic typed round-trip, mirroring the server-side MethodHandler shape.
  2. Optional: expose the underlying transport via ClientSession.Transport() as an escape hatch. Less preferred than (1)/(2) because consumers then have to deal with JSON-RPC

envelopes themselves, but it's a safety valve if the typed API isn't feasible.

Clean vendor-method extension is the main thing many MCP-native apps will want past the spec surface (observability, per-session telemetry, app-specific coordination like
ours). Happy to contribute a PR if the shape gets agreed on; wanted to flag the shape of the hole first.

---

Proposed Solution

---
Request: expose generic request/notification sending + handler registration in go-sdk's Client and Server

Context: Building a CLI coding agent (Loom) in Go on top of github.com/modelcontextprotocol/go-sdk v1.6.0. Excellent typed-handler surface via AddTool[In, Out] +
jsonschema-go inference — that part is a real upgrade over the community alternatives.

Gap: The SDK's Client / ClientSession only exposes spec-named methods (CallTool, ListTools, Ping, etc.) and the Server only accepts spec-named handlers (AddTool, AddPrompt,
AddResource, AddNotificationHandler). There's no equivalent of mcp-go's transport.Interface.SendRequest(ctx, JSONRPCRequest) — and no server-side AddRequestHandler(method
string, h MethodHandler) — so applications can't introduce vendor-prefixed extension methods over an otherwise standard MCP session. AddSendingMiddleware /
AddReceivingMiddleware wrap existing methods but can't originate or serve new ones.

Use case: we want a loom/derive_lane request so each tool can answer "what's my dispatcher-lane URI for these args?" at dispatch time (e.g. git's rev-parse
--show-toplevel). We end up registering a hidden companion tool (__loom_derive_lane_v1) and routing through CallTool, which works but pollutes the tool registry, requires a
visibility filter on every LLM-facing list path, and conceptually mis-models "this is an extension method" as "this is a tool."

Asks (in rough priority):

  1. Server.AddRequestHandler(method string, h MethodHandler) and AddNotificationHandler equivalent that already accepts arbitrary method names. Validate the method has a

vendor prefix (^[a-z]+/[a-z_]+$ or similar) so standard names can't be shadowed.

  1. ClientSession.Send(ctx, method, params, result any) error — generic typed round-trip, mirroring the server-side MethodHandler shape.
  2. Optional: expose the underlying transport via ClientSession.Transport() as an escape hatch. Less preferred than (1)/(2) because consumers then have to deal with JSON-RPC

envelopes themselves, but it's a safety valve if the typed API isn't feasible.

Clean vendor-method extension is the main thing many MCP-native apps will want past the spec surface (observability, per-session telemetry, app-specific coordination like
ours). Happy to contribute a PR if the shape gets agreed on; wanted to flag the shape of the hole first.

---

Alternative Solutions

---
Request: expose generic request/notification sending + handler registration in go-sdk's Client and Server

Context: Building a CLI coding agent (Loom) in Go on top of github.com/modelcontextprotocol/go-sdk v1.6.0. Excellent typed-handler surface via AddTool[In, Out] +
jsonschema-go inference — that part is a real upgrade over the community alternatives.

Gap: The SDK's Client / ClientSession only exposes spec-named methods (CallTool, ListTools, Ping, etc.) and the Server only accepts spec-named handlers (AddTool, AddPrompt,
AddResource, AddNotificationHandler). There's no equivalent of mcp-go's transport.Interface.SendRequest(ctx, JSONRPCRequest) — and no server-side AddRequestHandler(method
string, h MethodHandler) — so applications can't introduce vendor-prefixed extension methods over an otherwise standard MCP session. AddSendingMiddleware /
AddReceivingMiddleware wrap existing methods but can't originate or serve new ones.

Use case: we want a loom/derive_lane request so each tool can answer "what's my dispatcher-lane URI for these args?" at dispatch time (e.g. git's rev-parse
--show-toplevel). We end up registering a hidden companion tool (__loom_derive_lane_v1) and routing through CallTool, which works but pollutes the tool registry, requires a
visibility filter on every LLM-facing list path, and conceptually mis-models "this is an extension method" as "this is a tool."

Asks (in rough priority):

  1. Server.AddRequestHandler(method string, h MethodHandler) and AddNotificationHandler equivalent that already accepts arbitrary method names. Validate the method has a

vendor prefix (^[a-z]+/[a-z_]+$ or similar) so standard names can't be shadowed.

  1. ClientSession.Send(ctx, method, params, result any) error — generic typed round-trip, mirroring the server-side MethodHandler shape.
  2. Optional: expose the underlying transport via ClientSession.Transport() as an escape hatch. Less preferred than (1)/(2) because consumers then have to deal with JSON-RPC

envelopes themselves, but it's a safety valve if the typed API isn't feasible.

Clean vendor-method extension is the main thing many MCP-native apps will want past the spec surface (observability, per-session telemetry, app-specific coordination like
ours). Happy to contribute a PR if the shape gets agreed on; wanted to flag the shape of the hole first.

---

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

---
Request: expose generic request/notification sending + handler registration in go-sdk's Client and Server

Context: Building a CLI coding agent (Loom) in Go on top of github.com/modelcontextprotocol/go-sdk v1.6.0. Excellent typed-handler surface via AddTool[In, Out] +
jsonschema-go inference — that part is a real upgrade over the community alternatives.

Gap: The SDK's Client / ClientSession only exposes spec-named methods (CallTool, ListTools, Ping, etc.) and the Server only accepts spec-named handlers (AddTool, AddPrompt,
AddResource, AddNotificationHandler). There's no equivalent of mcp-go's transport.Interface.SendRequest(ctx, JSONRPCRequest) — and no server-side AddRequestHandler(method
string, h MethodHandler) — so applications can't introduce vendor-prefixed extension methods over an otherwise standard MCP session. AddSendingMiddleware /
AddReceivingMiddleware wrap existing methods but can't originate or serve new ones.

Use case: we want a loom/derive_lane request so each tool can answer "what's my dispatcher-lane URI for these args?" at dispatch time (e.g. git's rev-parse
--show-toplevel). We end up registering a hidden companion tool (__loom_derive_lane_v1) and routing through CallTool, which works but pollutes the tool registry, requires a
visibility filter on every LLM-facing list path, and conceptually mis-models "this is an extension method" as "this is a tool."

Asks (in rough priority):

  1. Server.AddRequestHandler(method string, h MethodHandler) and AddNotificationHandler equivalent that already accepts arbitrary method names. Validate the method has a

vendor prefix (^[a-z]+/[a-z_]+$ or similar) so standard names can't be shadowed.

  1. ClientSession.Send(ctx, method, params, result any) error — generic typed round-trip, mirroring the server-side MethodHandler shape.
  2. Optional: expose the underlying transport via ClientSession.Transport() as an escape hatch. Less preferred than (1)/(2) because consumers then have to deal with JSON-RPC

envelopes themselves, but it's a safety valve if the typed API isn't feasible.

Clean vendor-method extension is the main thing many MCP-native apps will want past the spec surface (observability, per-session telemetry, app-specific coordination like
ours). Happy to contribute a PR if the shape gets agreed on; wanted to flag the shape of the hole first.

---

Additional Context

---
Request: expose generic request/notification sending + handler registration in go-sdk's Client and Server

Context: Building a CLI coding agent (Loom) in Go on top of github.com/modelcontextprotocol/go-sdk v1.6.0. Excellent typed-handler surface via AddTool[In, Out] +
jsonschema-go inference — that part is a real upgrade over the community alternatives.

Gap: The SDK's Client / ClientSession only exposes spec-named methods (CallTool, ListTools, Ping, etc.) and the Server only accepts spec-named handlers (AddTool, AddPrompt,
AddResource, AddNotificationHandler). There's no equivalent of mcp-go's transport.Interface.SendRequest(ctx, JSONRPCRequest) — and no server-side AddRequestHandler(method
string, h MethodHandler) — so applications can't introduce vendor-prefixed extension methods over an otherwise standard MCP session. AddSendingMiddleware /
AddReceivingMiddleware wrap existing methods but can't originate or serve new ones.

Use case: we want a loom/derive_lane request so each tool can answer "what's my dispatcher-lane URI for these args?" at dispatch time (e.g. git's rev-parse
--show-toplevel). We end up registering a hidden companion tool (__loom_derive_lane_v1) and routing through CallTool, which works but pollutes the tool registry, requires a
visibility filter on every LLM-facing list path, and conceptually mis-models "this is an extension method" as "this is a tool."

Asks (in rough priority):

  1. Server.AddRequestHandler(method string, h MethodHandler) and AddNotificationHandler equivalent that already accepts arbitrary method names. Validate the method has a

vendor prefix (^[a-z]+/[a-z_]+$ or similar) so standard names can't be shadowed.

  1. ClientSession.Send(ctx, method, params, result any) error — generic typed round-trip, mirroring the server-side MethodHandler shape.
  2. Optional: expose the underlying transport via ClientSession.Transport() as an escape hatch. Less preferred than (1)/(2) because consumers then have to deal with JSON-RPC

envelopes themselves, but it's a safety valve if the typed API isn't feasible.

Clean vendor-method extension is the main thing many MCP-native apps will want past the spec surface (observability, per-session telemetry, app-specific coordination like
ours). Happy to contribute a PR if the shape gets agreed on; wanted to flag the shape of the hole first.

---

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗