lazy-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Lazy MCP Proxy
2
+
3
+ A proxy tool that converts normal MCP servers to use a lazy-loading pattern with three core tools, dramatically reducing initial context usage and enabling support for hundreds of commands.
4
+
5
+ ## Overview
6
+
7
+ Instead of exposing all tools directly (which can consume many context tokens), this proxy exposes only three meta-tools:
8
+
9
+ - `list_commands` - Returns command names and brief descriptions
10
+ - `describe_commands` - Accepts `command_names: Array[String]`, returns full schemas
11
+ - `invoke_command` - Executes commands with `command_name: String, parameters: Object`
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install -g lazy-mcp
17
+ ```
18
+
19
+ Or use with npx:
20
+
21
+ ```bash
22
+ npx lazy-mcp <server-command> [server-args...]
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ```bash
28
+ # Run a Python MCP server through the lazy proxy
29
+ lazy-mcp python my_server.py
30
+
31
+ # Run a Node.js MCP server through the lazy proxy
32
+ lazy-mcp node my_server.js
33
+
34
+ # Pass additional arguments to the original server
35
+ lazy-mcp python my_server.py --config config.json
36
+ ```
37
+
38
+ ## Example
39
+
40
+ ```bash
41
+ # Original server with many tools
42
+ python my_server.py
43
+ # Exposes: tool1, tool2, tool3, ..., tool100 (uses 100x context)
44
+
45
+ # Through lazy proxy
46
+ lazy-mcp python my_server.py
47
+ # Exposes: list_commands, describe_commands, invoke_command (uses 3x context)
48
+ ```
49
+
50
+ ## Development
51
+
52
+ ```bash
53
+ npm install
54
+ npm run build
55
+ npm run dev -- python example_server.py
56
+ ```
57
+
58
+ ## Benefits
59
+
60
+ - **Dramatic reduction** in initial context usage
61
+ - **Progressive tool discovery** - only load schemas when needed
62
+ - **Scales to hundreds** of commands without context bloat
63
+ - **Clean separation** of concerns between discovery and execution
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const child_process_1 = require("child_process");
5
+ const server_js_1 = require("./server.js");
6
+ class ExternalMCPServer {
7
+ constructor(serverCommand, serverArgs = []) {
8
+ this.serverCommand = serverCommand;
9
+ this.serverArgs = serverArgs;
10
+ }
11
+ async listTools() {
12
+ return new Promise((resolve, reject) => {
13
+ const process = (0, child_process_1.spawn)(this.serverCommand, this.serverArgs, {
14
+ stdio: ['pipe', 'pipe', 'inherit']
15
+ });
16
+ const request = {
17
+ jsonrpc: '2.0',
18
+ id: 1,
19
+ method: 'tools/list'
20
+ };
21
+ let responseData = '';
22
+ process.stdout.on('data', (data) => {
23
+ responseData += data.toString();
24
+ });
25
+ process.on('close', (code) => {
26
+ if (code !== 0) {
27
+ reject(new Error(`Server process exited with code ${code}`));
28
+ return;
29
+ }
30
+ try {
31
+ const lines = responseData.trim().split('\n');
32
+ for (const line of lines) {
33
+ if (line.trim()) {
34
+ const response = JSON.parse(line);
35
+ if (response.id === 1 && response.result) {
36
+ resolve(response.result);
37
+ return;
38
+ }
39
+ }
40
+ }
41
+ reject(new Error('No valid response received'));
42
+ }
43
+ catch (error) {
44
+ reject(new Error(`Failed to parse response: ${error}`));
45
+ }
46
+ });
47
+ process.stdin.write(JSON.stringify(request) + '\n');
48
+ process.stdin.end();
49
+ });
50
+ }
51
+ async callTool(name, arguments_) {
52
+ return new Promise((resolve, reject) => {
53
+ const process = (0, child_process_1.spawn)(this.serverCommand, this.serverArgs, {
54
+ stdio: ['pipe', 'pipe', 'inherit']
55
+ });
56
+ const request = {
57
+ jsonrpc: '2.0',
58
+ id: 2,
59
+ method: 'tools/call',
60
+ params: {
61
+ name,
62
+ arguments: arguments_
63
+ }
64
+ };
65
+ let responseData = '';
66
+ process.stdout.on('data', (data) => {
67
+ responseData += data.toString();
68
+ });
69
+ process.on('close', (code) => {
70
+ if (code !== 0) {
71
+ reject(new Error(`Server process exited with code ${code}`));
72
+ return;
73
+ }
74
+ try {
75
+ const lines = responseData.trim().split('\n');
76
+ for (const line of lines) {
77
+ if (line.trim()) {
78
+ const response = JSON.parse(line);
79
+ if (response.id === 2 && response.result) {
80
+ resolve(response.result);
81
+ return;
82
+ }
83
+ }
84
+ }
85
+ reject(new Error('No valid response received'));
86
+ }
87
+ catch (error) {
88
+ reject(new Error(`Failed to parse response: ${error}`));
89
+ }
90
+ });
91
+ process.stdin.write(JSON.stringify(request) + '\n');
92
+ process.stdin.end();
93
+ });
94
+ }
95
+ }
96
+ async function main() {
97
+ const args = process.argv.slice(2);
98
+ if (args.length === 0) {
99
+ console.error('Usage: lazy-mcp <server-command> [server-args...]');
100
+ console.error('Example: lazy-mcp python my_server.py');
101
+ process.exit(1);
102
+ }
103
+ const [serverCommand, ...serverArgs] = args;
104
+ const originalServer = new ExternalMCPServer(serverCommand, serverArgs);
105
+ const lazyServer = new server_js_1.LazyMCPServer(originalServer);
106
+ try {
107
+ await lazyServer.run();
108
+ }
109
+ catch (error) {
110
+ console.error('Error starting lazy MCP server:', error);
111
+ process.exit(1);
112
+ }
113
+ }
114
+ if (require.main === module) {
115
+ main().catch(console.error);
116
+ }
117
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,iDAAsC;AACtC,2CAA4C;AAG5C,MAAM,iBAAiB;IAKrB,YAAY,aAAqB,EAAE,aAAuB,EAAE;QAC1D,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,SAAS;QACb,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,OAAO,GAAG,IAAA,qBAAK,EAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,EAAE;gBACzD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;aACnC,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG;gBACd,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,MAAM,EAAE,YAAY;aACrB,CAAC;YAEF,IAAI,YAAY,GAAG,EAAE,CAAC;YAEtB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACzC,YAAY,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC3B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC7D,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;4BAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAClC,IAAI,QAAQ,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gCACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gCACzB,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC1D,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,UAA+B;QAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,OAAO,GAAG,IAAA,qBAAK,EAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,EAAE;gBACzD,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;aACnC,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG;gBACd,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,MAAM,EAAE,YAAY;gBACpB,MAAM,EAAE;oBACN,IAAI;oBACJ,SAAS,EAAE,UAAU;iBACtB;aACF,CAAC;YAEF,IAAI,YAAY,GAAG,EAAE,CAAC;YAEtB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACzC,YAAY,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC3B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC7D,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;wBACzB,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;4BAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAClC,IAAI,QAAQ,CAAC,EAAE,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gCACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gCACzB,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;gBAClD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC1D,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;YACpD,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC;IAC5C,MAAM,cAAc,GAAG,IAAI,iBAAiB,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,IAAI,yBAAa,CAAC,cAAc,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,GAAG,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { CommandInfo, CommandSchema, MCPServer, LazyMCPProxy } from './types.js';
2
+ export declare class LazyMCPProxyImpl implements LazyMCPProxy {
3
+ private mcpServer;
4
+ private toolsCache;
5
+ constructor(mcpServer: MCPServer);
6
+ listCommands(): Promise<CommandInfo[]>;
7
+ describeCommands(commandNames: string[]): Promise<CommandSchema[]>;
8
+ invokeCommand(commandName: string, parameters: Record<string, any>): Promise<any>;
9
+ }
10
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAW,MAAM,YAAY,CAAC;AAE1F,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAA0B;gBAEhC,SAAS,EAAE,SAAS;IAI1B,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAYtC,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAuBlE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;CAQxF"}
package/dist/proxy.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LazyMCPProxyImpl = void 0;
4
+ class LazyMCPProxyImpl {
5
+ constructor(mcpServer) {
6
+ this.toolsCache = null;
7
+ this.mcpServer = mcpServer;
8
+ }
9
+ async listCommands() {
10
+ if (!this.toolsCache) {
11
+ const result = await this.mcpServer.listTools();
12
+ this.toolsCache = result.tools;
13
+ }
14
+ return this.toolsCache.map(tool => ({
15
+ name: tool.name,
16
+ description: tool.description
17
+ }));
18
+ }
19
+ async describeCommands(commandNames) {
20
+ if (!this.toolsCache) {
21
+ const result = await this.mcpServer.listTools();
22
+ this.toolsCache = result.tools;
23
+ }
24
+ const schemas = [];
25
+ for (const commandName of commandNames) {
26
+ const tool = this.toolsCache.find(t => t.name === commandName);
27
+ if (tool) {
28
+ schemas.push({
29
+ name: tool.name,
30
+ description: tool.description,
31
+ inputSchema: tool.inputSchema
32
+ });
33
+ }
34
+ else {
35
+ throw new Error(`Command '${commandName}' not found`);
36
+ }
37
+ }
38
+ return schemas;
39
+ }
40
+ async invokeCommand(commandName, parameters) {
41
+ try {
42
+ const result = await this.mcpServer.callTool(commandName, parameters);
43
+ return result.content;
44
+ }
45
+ catch (error) {
46
+ throw new Error(`Failed to invoke command '${commandName}': ${error}`);
47
+ }
48
+ }
49
+ }
50
+ exports.LazyMCPProxyImpl = LazyMCPProxyImpl;
51
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":";;;AAEA,MAAa,gBAAgB;IAI3B,YAAY,SAAoB;QAFxB,eAAU,GAAqB,IAAI,CAAC;QAG1C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC;QACjC,CAAC;QAED,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClC,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,YAAsB;QAC3C,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YAChD,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC;QACjC,CAAC;QAED,MAAM,OAAO,GAAoB,EAAE,CAAC;QACpC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;YAC/D,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,WAAW;oBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;iBAC9B,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,YAAY,WAAW,aAAa,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,WAAmB,EAAE,UAA+B;QACtE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;YACtE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,MAAM,KAAK,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF;AAnDD,4CAmDC"}
@@ -0,0 +1,9 @@
1
+ import { MCPServer } from './types.js';
2
+ export declare class LazyMCPServer {
3
+ private server;
4
+ private proxy;
5
+ constructor(originalMcpServer: MCPServer);
6
+ private setupHandlers;
7
+ run(): Promise<void>;
8
+ }
9
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAmB;gBAEpB,iBAAiB,EAAE,SAAS;IAiBxC,OAAO,CAAC,aAAa;IA0Hf,GAAG;CAIV"}
package/dist/server.js ADDED
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LazyMCPServer = void 0;
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const proxy_js_1 = require("./proxy.js");
8
+ class LazyMCPServer {
9
+ constructor(originalMcpServer) {
10
+ this.proxy = new proxy_js_1.LazyMCPProxyImpl(originalMcpServer);
11
+ this.server = new index_js_1.Server({
12
+ name: 'lazy-mcp-proxy',
13
+ version: '1.0.0',
14
+ }, {
15
+ capabilities: {
16
+ tools: {},
17
+ },
18
+ });
19
+ this.setupHandlers();
20
+ }
21
+ setupHandlers() {
22
+ this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
23
+ return {
24
+ tools: [
25
+ {
26
+ name: 'list_commands',
27
+ description: 'List all available commands with brief descriptions',
28
+ inputSchema: {
29
+ type: 'object',
30
+ properties: {},
31
+ },
32
+ },
33
+ {
34
+ name: 'describe_commands',
35
+ description: 'Get detailed schemas for specified commands',
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ command_names: {
40
+ type: 'array',
41
+ items: { type: 'string' },
42
+ description: 'Array of command names to describe',
43
+ },
44
+ },
45
+ required: ['command_names'],
46
+ },
47
+ },
48
+ {
49
+ name: 'invoke_command',
50
+ description: 'Execute a command with given parameters',
51
+ inputSchema: {
52
+ type: 'object',
53
+ properties: {
54
+ command_name: {
55
+ type: 'string',
56
+ description: 'Name of the command to execute',
57
+ },
58
+ parameters: {
59
+ type: 'object',
60
+ description: 'Parameters to pass to the command',
61
+ },
62
+ },
63
+ required: ['command_name', 'parameters'],
64
+ },
65
+ },
66
+ ],
67
+ };
68
+ });
69
+ this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
70
+ const { name, arguments: args } = request.params;
71
+ try {
72
+ switch (name) {
73
+ case 'list_commands': {
74
+ const commands = await this.proxy.listCommands();
75
+ return {
76
+ content: [
77
+ {
78
+ type: 'text',
79
+ text: JSON.stringify(commands, null, 2),
80
+ },
81
+ ],
82
+ };
83
+ }
84
+ case 'describe_commands': {
85
+ const { command_names } = args;
86
+ if (!Array.isArray(command_names)) {
87
+ throw new Error('command_names must be an array');
88
+ }
89
+ const schemas = await this.proxy.describeCommands(command_names);
90
+ return {
91
+ content: [
92
+ {
93
+ type: 'text',
94
+ text: JSON.stringify(schemas, null, 2),
95
+ },
96
+ ],
97
+ };
98
+ }
99
+ case 'invoke_command': {
100
+ const { command_name, parameters } = args;
101
+ if (typeof command_name !== 'string') {
102
+ throw new Error('command_name must be a string');
103
+ }
104
+ if (typeof parameters !== 'object' || parameters === null) {
105
+ throw new Error('parameters must be an object');
106
+ }
107
+ const result = await this.proxy.invokeCommand(command_name, parameters);
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: JSON.stringify(result, null, 2),
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ default:
118
+ throw new Error(`Unknown tool: ${name}`);
119
+ }
120
+ }
121
+ catch (error) {
122
+ const errorMessage = error instanceof Error ? error.message : String(error);
123
+ return {
124
+ content: [
125
+ {
126
+ type: 'text',
127
+ text: `Error: ${errorMessage}`,
128
+ },
129
+ ],
130
+ isError: true,
131
+ };
132
+ }
133
+ });
134
+ }
135
+ async run() {
136
+ const transport = new stdio_js_1.StdioServerTransport();
137
+ await this.server.connect(transport);
138
+ }
139
+ }
140
+ exports.LazyMCPServer = LazyMCPServer;
141
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface CommandInfo {
2
+ name: string;
3
+ description: string;
4
+ }
5
+ export interface CommandSchema {
6
+ name: string;
7
+ description: string;
8
+ inputSchema: {
9
+ type: string;
10
+ properties: Record<string, any>;
11
+ required?: string[];
12
+ };
13
+ }
14
+ export interface MCPTool {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: string;
19
+ properties: Record<string, any>;
20
+ required?: string[];
21
+ };
22
+ }
23
+ export interface MCPServer {
24
+ listTools(): Promise<{
25
+ tools: MCPTool[];
26
+ }>;
27
+ callTool(name: string, arguments_: Record<string, any>): Promise<{
28
+ content: any[];
29
+ }>;
30
+ }
31
+ export interface LazyMCPProxy {
32
+ listCommands(): Promise<CommandInfo[]>;
33
+ describeCommands(commandNames: string[]): Promise<CommandSchema[]>;
34
+ invokeCommand(commandName: string, parameters: Record<string, any>): Promise<any>;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAC;CACtF;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACvC,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACnE,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACnF"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "lazy-mcp",
3
+ "version": "1.0.0",
4
+ "description": "A proxy tool that converts normal MCP servers to use lazy-loading pattern with three core tools",
5
+ "main": "dist/server.js",
6
+ "bin": {
7
+ "lazy-mcp": "dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist/**/*",
11
+ "README.md"
12
+ ],
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://gitlab.com/gitlab-org/search-team/experiments/lazy-mcp.git"
16
+ },
17
+ "homepage": "https://gitlab.com/gitlab-org/search-team/experiments/lazy-mcp#readme",
18
+ "bugs": {
19
+ "url": "https://gitlab.com/gitlab-org/search-team/experiments/lazy-mcp/-/issues"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "start": "node dist/cli.js",
24
+ "dev": "ts-node src/cli.ts"
25
+ },
26
+ "keywords": [
27
+ "mcp",
28
+ "model-context-protocol",
29
+ "proxy",
30
+ "lazy-loading"
31
+ ],
32
+ "author": "",
33
+ "license": "MIT",
34
+ "devDependencies": {
35
+ "@types/node": "^20.0.0",
36
+ "typescript": "^5.0.0",
37
+ "ts-node": "^10.9.0"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.0.0"
41
+ }
42
+ }