import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { loadConfig, validateConfig, getConfigDir, ConfigError } from './config.js';
import { buildTools, handleToolCall, ToolError } from './tools.js';
import { Config } from './types.js';
export interface ServerOptions {
configPath?: string;
}
export function createServer(options: ServerOptions = {}) {
const configPath = options.configPath || 'instruction.yaml';
let config: Config;
try {
config = loadConfig(configPath);
} catch (err) {
if (err instanceof ConfigError) {
console.error(`Configuration error: ${err.message}`);
process.exit(1);
}
throw err;
}
const configDir = getConfigDir(configPath);
const validationErrors = validateConfig(config, configDir);
if (validationErrors.length > 0) {
console.error('Validation errors:');
for (const error of validationErrors) {
console.error(` [${error.tool}] ${error.message}`);
}
process.exit(1);
}
const tools = buildTools(config);
const server = new Server(
{ name: 'instruction-mcp', version: '0.1.0' },
{ capabilities: { tools: {} } }
);
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools,
}));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
const content = handleToolCall(config, name, args || {}, configDir);
return {
content: [{ type: 'text', text: content }],
};
} catch (err) {
const message = err instanceof ToolError ? err.message : 'Unknown error';
return {
content: [{ type: 'text', text: `Error: ${message}` }],
isError: true,
};
}
});
return { server, config, tools };
}
export async function startStdioServer(options: ServerOptions = {}) {
const { server } = createServer(options);
const transport = new StdioServerTransport();
await server.connect(transport);
console.error('Instruction server running on stdio');
}
export { loadConfig, validateConfig, ConfigError } from './config.js';
export { buildTools, handleToolCall, ToolError } from './tools.js';
export * from './types.js';