Transport-level routing for MCP/ACP protocols
MCP Echo Server
TypeScript MCP server example for testing Model Context Protocol integration with stdio Bus.
Overview
The MCP Echo Server is a reference implementation of an MCP (Model Context Protocol) server that provides simple tools for testing MCP integration. It demonstrates how to build MCP servers that can be used with the ACP Worker or MCP-to-ACP Proxy.
Key Features:
- Full MCP protocol implementation using @modelcontextprotocol/sdk
- Five example tools for testing different scenarios
- TypeScript with complete type definitions
- Error handling and cancellation support
- Reference code for custom MCP servers
Purpose
The MCP Echo Server serves multiple purposes:
- Testing: Verify MCP integration with stdio Bus and ACP Worker
- Reference Implementation: Demonstrate MCP server development patterns
- Development: Quick testing of MCP client implementations
- Learning: Understand MCP protocol and tool execution
Available Tools
The MCP Echo Server provides five tools for testing different scenarios:
echo
Echoes back the input text.
Parameters:
text(string, required) - Text to echo back
Example:
{"method": "tools/call","params": {"name": "echo","arguments": {"text": "Hello, world!"}}}
Response:
{"content": [{"type": "text","text": "Echo: Hello, world!"}]}
reverse
Reverses the input text.
Parameters:
text(string, required) - Text to reverse
Example:
{"method": "tools/call","params": {"name": "reverse","arguments": {"text": "Hello"}}}
Response:
{"content": [{"type": "text","text": "olleH"}]}
uppercase
Converts input text to uppercase.
Parameters:
text(string, required) - Text to convert
Example:
{"method": "tools/call","params": {"name": "uppercase","arguments": {"text": "hello world"}}}
Response:
{"content": [{"type": "text","text": "HELLO WORLD"}]}
delay
Echoes text after a specified delay (useful for testing cancellation).
Parameters:
text(string, required) - Text to echoms(number, required) - Delay in milliseconds
Example:
{"method": "tools/call","params": {"name": "delay","arguments": {"text": "Delayed message","ms": 5000}}}
Response (after 5 seconds):
{"content": [{"type": "text","text": "Delayed: Delayed message"}]}
error
Always returns an error (useful for testing error handling).
Parameters:
message(string, optional) - Custom error message
Example:
{"method": "tools/call","params": {"name": "error","arguments": {"message": "Test error"}}}
Response:
{"error": {"code": -32000,"message": "Test error"}}
Usage
Standalone Testing
Run the MCP Echo Server directly:
node node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js
The server will start and listen on stdin for MCP protocol messages.
With ACP Worker
The MCP Echo Server can be used with the ACP Worker to test MCP server integration:
ACP Worker configuration:
{"pools": [{"id": "acp-registry","command": "npx","args": ["@stdiobus/workers-registry","acp-worker"],"instances": 1,"env": {"MCP_SERVERS": "echo-server"}}]}
MCP server configuration (mcp-servers.json):
{"echo-server": {"command": "node","args": ["./node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js"]}}
With MCP-to-ACP Proxy
Use the MCP Echo Server through the MCP-to-ACP Proxy for IDE integration:
IDE MCP configuration:
{"mcpServers": {"echo-server": {"command": "node","args": ["./node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js"]}}}
Configuration
Basic Configuration
Minimal configuration for running the MCP Echo Server:
{"command": "node","args": ["./node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js"]}
With Environment Variables
Configure logging and behavior:
{"command": "node","args": ["./node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js"],"env": {"LOG_LEVEL": "debug","NODE_ENV": "development"}}
Development
Building from Source
cd node_modules/@stdiobus/workers-registry/workers/mcp-echo-servernpm installnpm run build
Project Structure
mcp-echo-server/├── src/│ ├── index.ts # Main entry point│ ├── server.ts # MCP server implementation│ └── tools/ # Tool implementations│ ├── echo.ts│ ├── reverse.ts│ ├── uppercase.ts│ ├── delay.ts│ └── error.ts├── dist/ # Compiled JavaScript├── package.json└── tsconfig.json
Creating Custom Tools
Add new tools by implementing the MCP tool interface:
import { Tool } from '@modelcontextprotocol/sdk/types.js';export const myTool: Tool = {name: 'my-tool',description: 'Description of my tool',inputSchema: {type: 'object',properties: {param1: {type: 'string',description: 'Parameter description'}},required: ['param1']}};export async function handleMyTool(args: any) {// Tool implementationreturn {content: [{type: 'text',text: `Result: ${args.param1}`}]};}
Testing Use Cases
Tool Execution
Test that tools execute correctly:
# Start MCP Echo Servernode node_modules/@stdiobus/workers-registry/workers/mcp-echo-server/dist/index.js# Send tool call (via stdin)echo '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"echo","arguments":{"text":"test"}}}' | node ...
Error Handling
Test error handling with the error tool:
# Call error toolecho '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"error","arguments":{"message":"Test error"}}}' | node ...# Verify error response format
Cancellation
Test cancellation with the delay tool:
# Start long-running operationecho '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"delay","arguments":{"text":"test","ms":10000}}}' | node ...# Send cancellation requestecho '{"jsonrpc":"2.0","method":"$/cancelRequest","params":{"id":"1"}}' | node ...
Tool Discovery
Test tool listing:
# List available toolsecho '{"jsonrpc":"2.0","id":"1","method":"tools/list"}' | node ...# Verify all 5 tools are listed
Protocol Implementation
The MCP Echo Server demonstrates key MCP protocol patterns:
Server Initialization
import { Server } from '@modelcontextprotocol/sdk/server/index.js';import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';const server = new Server({name: 'mcp-echo-server',version: '1.0.0'},{capabilities: {tools: {}}});
Tool Registration
server.setRequestHandler('tools/list', async () => {return {tools: [{name: 'echo',description: 'Echoes back the input text',inputSchema: {type: 'object',properties: {text: {type: 'string',description: 'Text to echo'}},required: ['text']}}// ... other tools]};});
Tool Execution
server.setRequestHandler('tools/call', async (request) => {const { name, arguments: args } = request.params;switch (name) {case 'echo':return {content: [{type: 'text',text: `Echo: ${args.text}`}]};// ... other toolsdefault:throw new Error(`Unknown tool: ${name}`);}});
Transport Setup
const transport = new StdioServerTransport();await server.connect(transport);
Best Practices
When using the MCP Echo Server as a reference:
- Use TypeScript - Type safety prevents many common errors
- Validate input - Check tool arguments before processing
- Handle errors gracefully - Return proper error responses
- Support cancellation - Implement cancellation for long-running operations
- Document tools - Provide clear descriptions and input schemas
- Log to stderr - Never write non-protocol messages to stdout
- Test thoroughly - Test all tools, error cases, and edge conditions
Troubleshooting
Server Not Starting
Symptom: MCP Echo Server fails to start
Solutions:
- Check Node.js version:
node --version(must be ≥20.0.0) - Verify build output exists
Tool Calls Failing
Symptom: Tool calls return errors
Solutions:
- Verify tool name is correct (case-sensitive)
- Check that required arguments are provided
- Validate argument types match input schema
Integration with ACP Worker
Symptom: MCP Echo Server not working with ACP Worker
Solutions:
- Verify MCP server configuration in mcp-servers.json
- Check server command and args are valid
- Ensure server path is correct
Next Steps
- ACP Worker - MCP server integration
- MCP-to-ACP Proxy - IDE integration