In-Memory MCP Server in ChatMCP: Architecture and Built-in Services
The in-memory MCP server in ChatMCP is a built-in JSON-RPC 2.0 server that runs directly in the Dart VM, providing zero-latency access to mathematical utilities and artifact instruction tools without external processes or network calls.
ChatMCP is an open-source client implementation for the Model Context Protocol (MCP) that enables AI assistants to interact with external data sources and tools. While the application supports remote MCP servers via SSE, Streamable, and STDIO transports, it also ships with a lightweight in-memory MCP server that runs entirely within the application process. This embedded server provides self-contained utilities that function without network dependencies or external binaries.
What Is the In-Memory MCP Server?
The in-memory MCP server is a specialized transport implementation that instantiates server logic directly within the Dart virtual machine. Unlike STDIO servers that spawn external processes or SSE servers that establish HTTP connections, the in-memory variant operates through direct method invocation.
In lib/mcp/mcp.dart, the initializeMcpServer function detects in-memory configurations via the "type": "inmemory" property and routes initialization through MemoryServerFactory.createMemoryServer. The factory, defined in lib/mcp/inmemory_server/factory.dart, maps command strings like "math" or "artifact_instructions" to concrete server implementations.
The resulting server instance is wrapped in an InMemoryClient (lib/mcp/inmemory/client.dart), which implements the standard McpClient interface. This design allows the UI and provider layers to interact with in-memory servers using the same API as remote transports, ensuring seamless integration.
Core Architecture and Instantiation
The McpServerProvider class (lib/provider/mcp_server_provider.dart) maintains the registry of available in-memory servers through its defaultInMemoryServers list. When the application initializes, the provider iterates through configured servers and invokes the factory pattern:
- Configuration entries specify
"type": "inmemory"and a"command"key MemoryServerFactory.createMemoryServerinstantiates the appropriate subclass ofMemoryServerInMemoryClientwraps the server and exposessendMessagemethods- The client registers with the provider's server pool for lifecycle management
Because the server runs in the same isolate as the UI, message passing occurs through direct function calls rather than serialization overhead, resulting in microsecond-level latency for tool invocations.
Built-in Services and Tools
ChatMCP ships with two default in-memory servers that provide immediate utility without external dependencies: the MathServer for computational operations and the ArtifactServer for UI rendering guidance.
MathServer: Arithmetic and Trigonometric Operations
The MathServer class (lib/mcp/inmemory_server/math.dart) exposes a comprehensive mathematical toolkit through the tools/list endpoint. The server registers twenty distinct operations:
Arithmetic and Algebraic Functions:
add,subtract,multiply,divide– Basic binary operationspower– Exponentiation (base, exponent)sqrt,cbrt– Square and cube rootsabs– Absolute valuemod– Modulo operationfactorial– Factorial calculation for positive integers
Trigonometric and Logarithmic Functions:
sin,cos,tan– Standard trigonometric functions (radian input)log– Natural logarithm
Aggregation Functions:
max,min– Binary maximum and minimumround,ceil,floor– Rounding operations
When the client invokes tools/call with a tool name and arguments, MathServer.onToolCall dispatches to the appropriate Dart math implementation and returns the computed result in the JSON-RPC response.
ArtifactServer: UI Rendering Instructions
The ArtifactServer (lib/mcp/inmemory_server/artifact_instructions.dart) provides a single tool, get_artifact_instructions, which returns a structured prompt describing how the ChatMCP interface should render artifact content.
Artifacts in ChatMCP represent distinct content blocks that the AI assistant generates—such as code snippets, SVG graphics, Mermaid diagrams, or React components. The get_artifact_instructions tool returns a comprehensive system prompt that guides the model on:
- When to create artifacts (distinct, self-contained content)
- Formatting requirements for artifact XML tags
- Supported artifact types and their specific constraints
- Update and deletion patterns for existing artifacts
This server ensures that the client UI and the AI assistant share a consistent protocol for rich content rendering without requiring external API calls.
Technical Implementation Details
The in-memory server architecture relies on a carefully designed class hierarchy that abstracts JSON-RPC handling while allowing concrete servers to define specific tool logic.
The MemoryServer Base Class
MemoryServer (lib/mcp/inmemory/memory_server.dart) extends McpServer and implements the core JSON-RPC message routing required by the MCP specification. It maintains an internal map of method handlers and provides default implementations for protocol-level operations:
Lifecycle Methods:
initialize– ReturnsInitializeResultcontaining protocol version, server name, and capabilities (prompts, resources, tools)ping– Empty response for connection keep-alive
Resource Management (Stubbed):
resources/list,resources/read,resources/subscribe,resources/unsubscribe– Return empty structures as the base class does not implement persistent resources
Prompt Management (Stubbed):
prompts/list,prompts/get– Return empty lists; concrete servers may override
Tool Execution:
tools/list– Returns the list ofToolobjects registered by the concrete server via the abstracttoolsgettertools/call– Dispatches toonToolCall, which concrete subclasses must implement to handle specific tool invocations
Logging and Completion:
logging/setLevel– No-op implementationcompletion/complete– Stubbed empty response
The class uses Dart's jsonrpc2 package for message parsing and constructs JSONRPCMessage objects for responses.
Client Interface: InMemoryClient
InMemoryClient (lib/mcp/inmemory/client.dart) implements the McpClient interface, providing a unified API for both in-memory and remote servers. It maintains a reference to a MemoryServer instance and forwards JSON-RPC requests:
sendMessage– Directly invokesMemoryServer.onmessageand returns the resultingJSONRPCMessagesendToolList– Wrapstools/listmethod callsendToolCall– Wrapstools/callwith tool name and arguments
Because there is no network serialization or process spawning, tool calls execute synchronously within the Dart event loop, providing immediate results.
Configuration and Usage
In-memory servers are configured through the same JSON schema as external servers, typically in assets/mcp_server.json or via the provider API:
{
"name": "Math",
"type": "inmemory",
"command": "math",
"env": {},
"args": []
}
The command field maps to server implementations via MemoryServerFactory. Valid values are math and artifact_instructions.
To initialize programmatically:
import 'package:chatmcp/mcp/mcp.dart';
final config = {
'name': 'Math',
'type': 'inmemory',
'command': 'math',
'env': {},
'args': [],
};
final client = await initializeMcpServer(config);
await client?.initialize();
Summary
- The in-memory MCP server is an embedded JSON-RPC 2.0 server that runs directly in the ChatMCP Dart VM, eliminating network overhead and external process dependencies.
- It is instantiated via
MemoryServerFactory.createMemoryServerinlib/mcp/inmemory_server/factory.dartand wrapped byInMemoryClientto provide a standardMcpClientinterface. - The architecture extends
MemoryServerfromlib/mcp/inmemory/memory_server.dart, which implements protocol-level MCP methods (initialize, ping, tools/list, tools/call) while leaving tool logic to concrete subclasses. - Two built-in servers ship with ChatMCP: MathServer (
lib/mcp/inmemory_server/math.dart) providing 20 mathematical tools, and ArtifactServer (lib/mcp/inmemory_server/artifact_instructions.dart) providing UI rendering guidance. - Configuration uses standard JSON with
"type": "inmemory", making in-memory servers interchangeable with remote transports from the application's perspective.
Frequently Asked Questions
How does the in-memory MCP server differ from STDIO or SSE servers?
The in-memory MCP server runs inside the ChatMCP process within the Dart VM, while STDIO servers spawn external child processes and SSE servers establish HTTP connections to remote hosts. In lib/mcp/mcp.dart, the initializeMcpServer function routes in-memory configs to MemoryServerFactory, creating an InMemoryClient that directly invokes Dart methods rather than serializing JSON over streams or sockets. This eliminates process spawning overhead and network latency, making tool calls synchronous and instantaneous.
What mathematical operations does the MathServer provide?
The MathServer class in lib/mcp/inmemory_server/math.dart exposes 20 distinct tools through the tools/list endpoint: add, subtract, multiply, divide, power, sqrt, cbrt, abs, sin, cos, tan, log, max, min, round, ceil, floor, mod, and factorial. When tools/call is invoked, the onToolCall method dispatches to the appropriate Dart math implementation and returns the computed integer result in the JSON-RPC response.
Can I add custom in-memory servers to ChatMCP?
Yes, you can extend the in-memory server system by creating a new class that inherits from MemoryServer in lib/mcp/inmemory/memory_server.dart, implementing the tools getter and onToolCall method. You must then register the server in MemoryServerFactory.createMemoryServer in lib/mcp/inmemory_server/factory.dart by mapping a command string to your class constructor. Finally, add a configuration entry with "type": "inmemory" and your custom command to assets/mcp_server.json or register it programmatically via McpServerProvider.addMcpServer.
Where is the in-memory MCP server configuration stored?
Default in-memory server configurations reside in assets/mcp_server.json, which ships with entries for the math and artifact_instructions servers. At runtime, the McpServerProvider class in lib/provider/mcp_server_provider.dart loads these configurations and maintains the defaultInMemoryServers list. Users can modify the JSON file directly or use the provider's addMcpServer method to register additional in-memory servers dynamically during application execution.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →