McpServer class final

MCP server that exposes ArtisanRegistry.mcpTools to a connected MCP client (Claude Code, Cursor, etc.) over a StreamChannel of newline- delimited JSON-RPC.

Architectural choices:

  • Static tool set: tools are filtered + registered ONCE inside initialize. No sendToolListChanged() calls in V1 (per Oracle C1 revise; the SIGHUP reload path is V1.1 BACKLOG). capabilities.tools.listChanged stays at the library-default true so the advertised capability matches reality once that path lands; never mutate it to false here, that would fight ToolsSupport's own initialize.

  • Filter at registration, not at dispatch: a denied tool never reaches registerTool, so dart_mcp's built-in "no tool registered with the name X" error covers the denied case automatically.

  • VM Service connection owned by serve: the connection lifetime is the server's lifetime. No cross-server caching (single-server-per-process model; matches the prior fluttersdk_mcp/lib/src/mcp_server.dart behaviour we replaced).

  • Stdio transport: production wiring goes through dart_mcp's stdioChannel helper, leaving stderr free for diagnostic logging.

Constructors

McpServer.stdio({required ArtisanRegistry registry, required McpFilterConfig filter})
Production factory: wires stdin / stdout through stdioChannel and uses the real VmServiceClient + StateFile.read for discovery.
factory
McpServer.test({required StreamChannel<String> channel, required ArtisanRegistry registry, required McpFilterConfig filter, required VmServiceClientFactory vmClientFactory, required StateReader stateReader})
Test factory: caller supplies the channel + every external seam.
factory

Properties

clientCapabilities ↔ ClientCapabilities
The capabilities of the client.
getter/setter pairinherited
clientInfo ↔ Implementation
The client implementation information provided during initialization.
getter/setter pairinherited
done Future<void>
Completes after shutdown is called.
no setterinherited
filter McpFilterConfig
Effective allow/deny axes applied once at initialize time.
final
hashCode int
The hash code for this object.
no setterinherited
implementation → Implementation
The name, current version, and other info to give to the client.
finalinherited
initialized Future<InitializedNotification?>
Completes when this server has finished initialization and gotten the final ack from the client.
no setterinherited
instructions String?
Instructions for how to use this server, which are given to the client.
finalinherited
isActive bool
Whether the connection with the peer is active.
no setterinherited
name String
The name of the associated server.
no setterinherited
protocolVersion ↔ ProtocolVersion
The negotiated protocol version.
getter/setter pairinherited
ready bool
Whether this server is still active and has completed initialization.
no setterinherited
registry ArtisanRegistry
Source of the tool catalog and provider attribution.
final
rootsListChanged Stream<RootsListChangedNotification?>?
Emits an event any time the client notifies us of a change to the list of roots it supports.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

callTool(CallToolRequest request) Future<CallToolResult>
Invoked when one of the registered tools is called.
inherited
createMessage(CreateMessageRequest request) Future<CreateMessageResult>
A request to prompt the LLM owned by the client with a message.
inherited
handleInitialized([InitializedNotification? notification]) → void
Called by the client after accepting our InitializeResult.
inherited
initialize(InitializeRequest request) FutureOr<InitializeResult>
Mixins should register their methods in this method, as well as editing the InitializeResult.capabilities as needed.
listRoots([ListRootsRequest? request]) Future<ListRootsResult>
Lists all the root URIs from the client.
inherited
listTools([ListToolsRequest? request]) FutureOr<ListToolsResult>
Returns the list of supported tools for this server.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
notifyProgress(ProgressNotification notification) → void
Notifies the peer of progress towards completing some request.
inherited
onProgress(Request request) Stream<ProgressNotification>
A stream of progress notifications for a given request.
inherited
ping({Duration timeout = const Duration(seconds: 1), PingRequest? request}) Future<bool>
Pings the peer, and returns whether or not it responded within timeout.
inherited
registerNotificationHandler<T extends Notification?>(String name, void impl(T)) → void
Registers a notification handler named name on this server.
inherited
registerRequestHandler<T extends Request?, R extends Result?>(String name, FutureOr<R> impl(T)) → void
Registers a handler for the method name on this server.
inherited
registerTool(Tool tool, FutureOr<CallToolResult> impl(CallToolRequest), {bool validateArguments = true}) → void
Register tool to call impl when invoked.
inherited
sendNotification(String method, [Notification? notification]) → void
Sends a notification to the peer.
inherited
sendRequest<T extends Result?>(String methodName, [Request? request]) Future<T>
Sends request to the peer, and handles coercing the response to the type T.
inherited
shutdown() Future<void>
Handles cleanup of all streams and other resources on shutdown.
toString() String
A string representation of this object.
inherited
unregisterTool(String name) → void
Un-registers a Tool by name.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Methods

serve({required ArtisanRegistry registry, required McpFilterConfig filter}) Future<void>
Convenience entry: build a stdio-wired server and block until the peer closes the channel. Intended for bin/mcp.dart (Step 22).