UNPKG

locker-mcp

Version:

MCP server for file locking and access control for AI code tools

223 lines 9.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LockerMCPServer = void 0; const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const types_js_1 = require("@modelcontextprotocol/sdk/types.js"); const locker_1 = require("./locker"); class LockerMCPServer { constructor() { this.server = new index_js_1.Server({ name: 'locker-mcp', version: '1.0.0', }, { capabilities: { tools: {}, }, }); this.locker = new locker_1.Locker(); this.setupToolHandlers(); } validateParams(args, requiredFields) { if (!args || typeof args !== 'object') { throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, 'Missing or invalid arguments'); } for (const field of requiredFields) { if (!(field in args) || args[field] === undefined || args[field] === null) { throw new types_js_1.McpError(types_js_1.ErrorCode.InvalidParams, `Missing required parameter: ${field}`); } } return args; } setupToolHandlers() { this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => { return { tools: [ { name: 'getFileState', description: 'Get the current lock state of a file', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to check', }, }, required: ['filePath'], }, }, { name: 'lockFile', description: 'Lock a file with context description', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to lock', }, context: { type: 'string', description: 'Description of the file\'s purpose or context', }, }, required: ['filePath', 'context'], }, }, { name: 'unlockFile', description: 'Unlock a file, removing its lock state', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to unlock', }, }, required: ['filePath'], }, }, { name: 'updateFile', description: 'Update a file\'s lock state and context', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to update', }, context: { type: 'string', description: 'Updated description of the file\'s purpose', }, state: { type: 'string', enum: ['unlocked', 'locked-context', 'locked'], description: 'New lock state for the file', }, }, required: ['filePath', 'context', 'state'], }, }, { name: 'finalizeFile', description: 'Mark a file as fully locked (no further edits allowed)', inputSchema: { type: 'object', properties: { filePath: { type: 'string', description: 'Path to the file to finalize', }, }, required: ['filePath'], }, }, { name: 'getAllTrackedFiles', description: 'Get all files currently tracked by the locker', inputSchema: { type: 'object', properties: {}, }, }, ], }; }); this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { case 'getFileState': { const params = this.validateParams(args, ['filePath']); const result = this.locker.getFileState(params); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } case 'lockFile': { const params = this.validateParams(args, ['filePath', 'context']); const result = this.locker.lockFile(params); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } case 'unlockFile': { const params = this.validateParams(args, ['filePath']); const result = this.locker.unlockFile(params); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } case 'updateFile': { const params = this.validateParams(args, ['filePath', 'context', 'state']); const result = this.locker.updateFile(params); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } case 'finalizeFile': { const params = this.validateParams(args, ['filePath']); const result = this.locker.finalizeFile(params.filePath); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } case 'getAllTrackedFiles': { const result = this.locker.getAllTrackedFiles(); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } default: throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Unknown tool: ${name}`); } } catch (error) { if (error instanceof types_js_1.McpError) { throw error; } throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`); } }); } async run() { const transport = new stdio_js_1.StdioServerTransport(); await this.server.connect(transport); } } exports.LockerMCPServer = LockerMCPServer; //# sourceMappingURL=server.js.map