STDIO Transport
The STDIO transport is the default transport mechanism in MCP Framework. It uses standard input/output streams for communication between the client and server.
Overview
STDIO transport is ideal for:
- CLI tools and applications
- Local process communication
- Simple integrations without network requirements
- Development and testing scenarios
How It Works
The STDIO transport:
- Uses standard input (stdin) to receive messages from the client
- Uses standard output (stdout) to send messages to the client
- Implements JSON-RPC 2.0 protocol for message formatting
- Maintains a direct, synchronous communication channel
Features
- Simplicity: No network configuration required
- Performance: Direct process communication with minimal overhead
- Reliability: Guaranteed message delivery within the same process
- Security: Inherent security through process isolation
- Debugging: Easy to debug with direct console output
Implementation
import { MCPServer } from "mcp-framework";
// STDIO is the default transport
const server = new MCPServer();
// Or explicitly specify STDIO transport
const server = new MCPServer({
transport: {
type: "stdio"
}
});
await server.start();
Use Cases
CLI Tools
STDIO transport is perfect for CLI tools where the MCP server runs as part of the command-line application:
#!/usr/bin/env node
import { MCPServer } from "mcp-framework";
async function main() {
const server = new MCPServer();
await server.start();
}
main().catch(console.error);
Local Development
During development, STDIO transport provides a simple way to test and debug your MCP tools:
import { MCPServer } from "mcp-framework";
const server = new MCPServer({
name: "dev-server",
version: "1.0.0"
});
await server.start();
Limitations
While STDIO transport is simple and efficient, it has some limitations:
- Single client connection only
- No network accessibility
- No authentication mechanism
- Process-bound lifecycle
For scenarios requiring multiple clients, network access, or authentication, consider using SSE Transport instead.
Best Practices
-
Error Handling
- Implement proper error handling for process termination
- Handle SIGINT and SIGTERM signals appropriately
-
Logging
- Use stderr for logging to avoid interfering with transport messages
- Consider implementing a proper logging strategy
-
Process Management
- Properly close the server on process exit
- Handle cleanup operations in shutdown hooks
Example Implementation
Here's a complete example showing best practices:
import { MCPServer } from "mcp-framework";
class MyMCPServer {
private server: MCPServer;
constructor() {
this.server = new MCPServer({
name: "my-mcp-server",
version: "1.0.0",
transport: { type: "stdio" }
});
// Handle process signals
process.on('SIGINT', () => this.shutdown());
process.on('SIGTERM', () => this.shutdown());
}
async start() {
try {
await this.server.start();
console.error('Server started successfully'); // Use stderr for logging
} catch (error) {
console.error('Failed to start server:', error);
process.exit(1);
}
}
private async shutdown() {
console.error('Shutting down...');
try {
await this.server.stop();
process.exit(0);
} catch (error) {
console.error('Error during shutdown:', error);
process.exit(1);
}
}
}
// Start the server
new MyMCPServer().start().catch(console.error);