import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
// Research how MCP server setup works
async function researchMCPServer() {
console.log('=== MCP Server Research ===\n');
// 1. Basic server creation
console.log('1. Server Creation:');
try {
// Look at the constructor signature from the types
const serverInfo = {
name: 'test-server',
version: '1.0.0',
};
const options = {
capabilities: {
tools: {},
},
};
new Server(serverInfo, options);
console.log('✓ Server created successfully');
console.log(` - Implementation info provided to constructor`);
console.log(` - Options include capabilities`);
} catch (error) {
console.log('✗ Server creation failed:', error);
}
// 2. Tool registration pattern
console.log('\n2. Tool Registration:');
const testServer = new Server(
{
name: 'test-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
},
);
// Research tool list handler
testServer.setRequestHandler(ListToolsRequestSchema, async () => {
console.log(' - tools/list handler called');
return {
tools: [
{
name: 'test_tool',
description: 'A test tool',
inputSchema: {
type: 'object',
properties: {
message: { type: 'string' },
},
required: ['message'],
},
},
],
};
});
// Research tool call handler
testServer.setRequestHandler(CallToolRequestSchema, async (request) => {
console.log(' - tools/call handler called');
console.log(` - Tool name: ${request.params.name}`);
console.log(` - Tool arguments:`, request.params.arguments);
if (request.params.name === 'test_tool') {
return {
content: [
{
type: 'text',
text: `Received: ${JSON.stringify(request.params.arguments)}`,
},
],
};
}
throw new Error(`Unknown tool: ${request.params.name}`);
});
console.log('✓ Request handlers set');
// 3. Transport setup
console.log('\n3. Transport Setup:');
try {
new StdioServerTransport();
console.log('✓ StdioServerTransport created');
console.log(' - Uses process.stdin and process.stdout for communication');
// Note: Don't actually run the transport in research
// await testServer.connect(transport);
console.log(' - Server would connect to transport with server.connect(transport)');
console.log(' - This starts the JSON-RPC message loop');
} catch (error) {
console.log('✗ Transport setup failed:', error);
}
// 4. Error handling patterns
console.log('\n4. Error Handling:');
console.log(' - MCP errors should use McpError class');
console.log(' - Tool errors should return error in response');
console.log(' - Example error response:');
console.log(' { error: { code: "INVALID_PARAMS", message: "...", details: {...} } }');
// 5. Schema validation
console.log('\n5. Schema Validation:');
console.log(' - SDK uses request schemas for validation');
console.log(' - ListToolsRequestSchema validates tools/list requests');
console.log(' - CallToolRequestSchema validates tools/call requests');
console.log(' - Input validation happens automatically');
// 6. Tool response format
console.log('\n6. Tool Response Format:');
console.log(' - Tools must return { content: [...] }');
console.log(' - Content items have type: "text" or "image"');
console.log(' - Text content: { type: "text", text: "..." }');
console.log(' - Errors: throw or return error object');
// 7. Multiple tools pattern
console.log('\n7. Multiple Tools Pattern:');
console.log(' - All tools handled in single CallToolRequestSchema handler');
console.log(' - Switch on request.params.name');
console.log(' - Import tool functions and call based on name');
console.log(' - Map tool names to functions for cleaner code');
// 8. Environment and configuration
console.log('\n8. Environment Configuration:');
console.log(' - Can read from process.env for configuration');
console.log(' - Common env vars: NODE_ENV, CACHE_SIZE, RATE_LIMIT');
console.log(' - Server info (name, version) typically from package.json');
// 9. Async patterns
console.log('\n9. Async Patterns:');
console.log(' - All handlers are async');
console.log(' - Tool functions can be async');
console.log(' - Errors in async functions are caught by SDK');
// 10. Testing considerations
console.log('\n10. Testing Considerations:');
console.log(' - Can test handlers directly without transport');
console.log(' - Mock request objects for handler testing');
console.log(' - Test tool registration separately from execution');
console.log(' - Verify error handling for unknown tools');
// 11. Tool input schemas
console.log('\n11. Tool Input Schemas:');
console.log(' - Input schemas use JSON Schema format');
console.log(' - Common properties: type, properties, required');
console.log(' - Support for various types: string, number, boolean, object, array');
console.log(' - Can include descriptions for each property');
// 12. Method names from schemas
console.log('\n12. Request Methods:');
console.log(` - ListToolsRequestSchema method: ${ListToolsRequestSchema.shape.method.value}`);
console.log(` - CallToolRequestSchema method: ${CallToolRequestSchema.shape.method.value}`);
}
// Run research
researchMCPServer().catch(console.error);