@qodalis/mcp-cli 0.0.0-stage → 0.1.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +273 -2
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +92 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +56 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +130 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/env-file.d.ts +9 -0
- package/dist/src/env-file.d.ts.map +1 -0
- package/dist/src/env-file.js +54 -0
- package/dist/src/env-file.js.map +1 -0
- package/dist/src/errors.d.ts +22 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +115 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/filters.d.ts +13 -0
- package/dist/src/filters.d.ts.map +1 -0
- package/dist/src/filters.js +16 -0
- package/dist/src/filters.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/remote.d.ts +62 -0
- package/dist/src/remote.d.ts.map +1 -0
- package/dist/src/remote.js +235 -0
- package/dist/src/remote.js.map +1 -0
- package/dist/src/server.d.ts +13 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +86 -0
- package/dist/src/server.js.map +1 -0
- package/package.json +67 -5
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { ProtocolError, Server } from '@modelcontextprotocol/server';
|
|
3
|
+
import { RemoteError } from './errors.js';
|
|
4
|
+
import { isToolAllowed } from './filters.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
/** package.json sits one level up from src/ and two levels up from dist/src/. */
|
|
7
|
+
const readPackageJson = () => {
|
|
8
|
+
for (const candidate of ['../package.json', '../../package.json']) {
|
|
9
|
+
try {
|
|
10
|
+
return require(candidate);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// try the next location
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return { name: '@qodalis/mcp-cli', version: '0.0.0' };
|
|
17
|
+
};
|
|
18
|
+
const packageJson = readPackageJson();
|
|
19
|
+
export const SERVER_NAME = packageJson.name;
|
|
20
|
+
export const SERVER_VERSION = packageJson.version;
|
|
21
|
+
export const WEBSITE_URL = 'https://github.com/qodalis-solutions/mcp-cli';
|
|
22
|
+
const INVALID_PARAMS = -32602;
|
|
23
|
+
const INTERNAL_ERROR = -32603;
|
|
24
|
+
export const buildInstructions = (config) => [
|
|
25
|
+
`Proxy to the Qodalis CLI server at ${config.url}.`,
|
|
26
|
+
"The tools are the server's CLI commands and features (files, data explorer, jobs, plugins), limited by the permissions of the configured account.",
|
|
27
|
+
'Call server_info first to see the server version and which features are enabled.',
|
|
28
|
+
config.readOnly
|
|
29
|
+
? 'Read-only mode: only tools the server marks as read-only are available.'
|
|
30
|
+
: 'Tools that change data are available; check a tool’s description before calling it.',
|
|
31
|
+
'After a network or VPN interruption simply retry the call: the proxy reconnects automatically.',
|
|
32
|
+
].join('\n');
|
|
33
|
+
const errorResult = (message) => ({
|
|
34
|
+
content: [{ text: message, type: 'text' }],
|
|
35
|
+
isError: true,
|
|
36
|
+
});
|
|
37
|
+
/** Why a tool the server knows is hidden by the client-side settings. */
|
|
38
|
+
const hiddenReason = (tool, config) => config.readOnly && tool.annotations?.readOnlyHint !== true
|
|
39
|
+
? `Tool ${tool.name} is not available: QCLI_READ_ONLY allows only read-only tools.`
|
|
40
|
+
: `Tool ${tool.name} is not available: excluded by QCLI_TOOLS / QCLI_EXCLUDE.`;
|
|
41
|
+
/**
|
|
42
|
+
* The local MCP server Claude Code talks to over stdio: `tools/list` returns the
|
|
43
|
+
* remote tools (unchanged) that pass the client-side filters, `tools/call` is forwarded.
|
|
44
|
+
*/
|
|
45
|
+
export const createProxyServer = (remote, config) => {
|
|
46
|
+
const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION, websiteUrl: WEBSITE_URL }, {
|
|
47
|
+
capabilities: { tools: { listChanged: false } },
|
|
48
|
+
instructions: buildInstructions(config),
|
|
49
|
+
});
|
|
50
|
+
server.setRequestHandler('tools/list', async () => {
|
|
51
|
+
try {
|
|
52
|
+
const tools = await remote.listTools();
|
|
53
|
+
return { tools: tools.filter((tool) => isToolAllowed(tool, config)) };
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error instanceof ProtocolError) {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
throw new ProtocolError(INTERNAL_ERROR, error.message);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
server.setRequestHandler('tools/call', async (request, ctx) => {
|
|
63
|
+
const params = request.params;
|
|
64
|
+
try {
|
|
65
|
+
const tool = await remote.findTool(params.name);
|
|
66
|
+
if (!tool) {
|
|
67
|
+
throw new ProtocolError(INVALID_PARAMS, `Unknown tool: ${params.name}`);
|
|
68
|
+
}
|
|
69
|
+
if (!isToolAllowed(tool, config)) {
|
|
70
|
+
throw new ProtocolError(INVALID_PARAMS, hiddenReason(tool, config));
|
|
71
|
+
}
|
|
72
|
+
return await remote.callTool({ arguments: params.arguments ?? {}, name: params.name }, ctx.mcpReq?.signal);
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
if (error instanceof ProtocolError) {
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
if (error instanceof RemoteError) {
|
|
79
|
+
return errorResult(error.message);
|
|
80
|
+
}
|
|
81
|
+
return errorResult(error?.message ?? String(error));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return server;
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@qodalis/mcp-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Model Context Protocol (MCP) server for Qodalis CLI servers: gives Claude Code the server's commands, files, data explorer and jobs through a resilient stdio proxy to the server's MCP endpoint.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/src/index.js",
|
|
7
|
+
"types": "dist/src/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp-cli": "dist/src/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/src",
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20.18.1"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.build.json",
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"dev": "tsx src/cli.ts",
|
|
24
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"*.md\" \"vitest.config.ts\"",
|
|
29
|
+
"check-format": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"vitest.config.ts\"",
|
|
30
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"mcp",
|
|
34
|
+
"model-context-protocol",
|
|
35
|
+
"qodalis",
|
|
36
|
+
"cli",
|
|
37
|
+
"claude",
|
|
38
|
+
"claude-code",
|
|
39
|
+
"ai",
|
|
40
|
+
"proxy"
|
|
41
|
+
],
|
|
42
|
+
"author": "Nicolae Lupei <nicolae.lupei@qodalis.com>",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/qodalis-solutions/mcp-cli.git"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/qodalis-solutions/mcp-cli#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/qodalis-solutions/mcp-cli/issues"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@modelcontextprotocol/client": "^2.3.1",
|
|
57
|
+
"@modelcontextprotocol/server": "^2.3.1",
|
|
58
|
+
"undici": "^7.30.1"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.20.5",
|
|
62
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
63
|
+
"prettier": "^3.9.10",
|
|
64
|
+
"tsx": "^4.23.15",
|
|
65
|
+
"typescript": "~5.9",
|
|
66
|
+
"vitest": "^5.0.5"
|
|
67
|
+
}
|
|
68
|
+
}
|