server.tsā¢6.41 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { DatabaseManager } from './lib/database.js';
import { SessionManager } from './lib/session-manager.js';
import { FileHandler } from './lib/file-handler.js';
import { ClipboardManager } from './lib/clipboard-manager.js';
import { OperationLogger } from './lib/operation-logger.js';
import { PathAccessControl } from './lib/path-access-control.js';
import { ClipboardTools } from './tools/clipboard-tools.js';
import { TOOL_DEFINITIONS, ToolDefinition } from './config/tools.js';
/**
* MCP Cut-Copy-Paste Clipboard Server
* Provides cut, copy, paste, and undo operations via MCP protocol
*/
export class ClipboardServer {
private server: Server;
private sessionManager: SessionManager;
private pathAccessControl: PathAccessControl;
private fileHandler: FileHandler;
private clipboardManager: ClipboardManager;
private operationLogger: OperationLogger;
private clipboardTools: ClipboardTools;
private sessionId: string;
private tools: ToolDefinition[];
constructor(dbManager: DatabaseManager) {
// Initialize server
this.server = new Server(
{
name: 'cut-copy-paste-mcp',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
// Initialize core components
this.sessionManager = new SessionManager(dbManager);
this.pathAccessControl = new PathAccessControl();
this.fileHandler = new FileHandler(this.pathAccessControl);
this.clipboardManager = new ClipboardManager(dbManager);
this.operationLogger = new OperationLogger(dbManager);
// Initialize clipboard tools
this.clipboardTools = new ClipboardTools(
this.fileHandler,
this.clipboardManager,
this.operationLogger,
this.sessionManager,
this.pathAccessControl
);
// Create session for this server instance
this.sessionId = this.sessionManager.createSession();
// Cleanup expired sessions on startup
this.sessionManager.cleanupExpiredSessions();
// Load tool definitions from config
this.tools = TOOL_DEFINITIONS;
// Register request handlers
this.setupRequestHandlers();
}
/**
* Setup MCP request handlers
*/
private setupRequestHandlers(): void {
// Handle list tools request
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: this.tools,
};
});
// Handle call tool request
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
if (!args) {
throw new Error('Missing arguments');
}
switch (name) {
case 'copy_lines': {
const result = await this.clipboardTools.copyLines(
this.sessionId,
args.file_path as string,
args.start_line as number,
args.end_line as number
);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
case 'cut_lines': {
const result = await this.clipboardTools.cutLines(
this.sessionId,
args.file_path as string,
args.start_line as number,
args.end_line as number
);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
case 'paste_lines': {
const result = await this.clipboardTools.pasteLines(
this.sessionId,
args.targets as Array<{ file_path: string; target_line: number }>
);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
case 'show_clipboard': {
const result = await this.clipboardTools.showClipboard(this.sessionId);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
case 'undo_last_paste': {
const result = await this.clipboardTools.undoLastPaste(this.sessionId);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
case 'get_operation_history': {
const result = await this.clipboardTools.getOperationHistory(
this.sessionId,
args.limit as number | undefined
);
return {
content: [
{
type: 'text',
text: JSON.stringify(result, null, 2),
},
],
};
}
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text',
text: JSON.stringify({
error: error instanceof Error ? error.message : String(error),
}),
},
],
isError: true,
};
}
});
}
/**
* Get server info (for testing)
*/
getServerInfo(): { name: string; version: string } {
return {
name: 'cut-copy-paste-mcp',
version: '1.0.0',
};
}
/**
* Get registered tools (for testing)
*/
getRegisteredTools(): ToolDefinition[] {
return this.tools;
}
/**
* Get session ID (for testing)
*/
getSessionId(): string {
return this.sessionId;
}
/**
* Cleanup expired sessions (for testing)
*/
cleanupExpiredSessions(): void {
this.sessionManager.cleanupExpiredSessions();
}
/**
* Get the underlying MCP server (for running)
*/
getMCPServer(): Server {
return this.server;
}
}