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.listChangedstays at the library-defaulttrueso the advertised capability matches reality once that path lands; never mutate it tofalsehere, that would fightToolsSupport'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.dartbehaviour we replaced). -
Stdio transport: production wiring goes through
dart_mcp'sstdioChannelhelper, leaving stderr free for diagnostic logging.
Constructors
- McpServer.stdio({required ArtisanRegistry registry, required McpFilterConfig filter})
-
Production factory: wires stdin / stdout through
stdioChanneland 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
shutdownis 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.capabilitiesas 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
nameon this server.inherited -
registerRequestHandler<
T extends Request?, R extends Result?> (String name, FutureOr< R> impl(T)) → void -
Registers a handler for the method
nameon this server.inherited -
registerTool(
Tool tool, FutureOr< CallToolResult> impl(CallToolRequest), {bool validateArguments = true}) → void -
Register
toolto callimplwhen 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
requestto the peer, and handles coercing the response to the typeT.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
Toolbyname.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).