zero-config-cli-bridge 1.2.0 → 1.3.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/dist/index.js +57 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,42 +3,55 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import { executeCommand } from './executor.js';
|
|
6
|
+
import { validateSubcommand, validateArgs } from './security.js';
|
|
7
|
+
import { buildToolDefinitions, buildGhArgs } from './schema.js';
|
|
6
8
|
const MAX_JSON_ITEMS = 30;
|
|
7
|
-
const JSON_TRUNCATION_MSG = `\n...[Output truncated at ${MAX_JSON_ITEMS} items. Use --limit or filters to narrow results.]`;
|
|
8
9
|
const MAX_TEXT_CHARS = 2000;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
* JSON path : caps array at MAX_JSON_ITEMS — always returns valid JSON.
|
|
14
|
-
* Text path : caps at MAX_TEXT_CHARS — prevents context exhaustion on
|
|
15
|
-
* error messages and plain-text fallback output.
|
|
16
|
-
*
|
|
17
|
-
* The executor's MAX_RAW_CHARS (4096) is an independent backstop that fires
|
|
18
|
-
* only if this function is somehow bypassed (e.g. future code paths).
|
|
19
|
-
*/
|
|
20
|
-
function toSafeOutput(raw) {
|
|
10
|
+
function toEnvelope(raw) {
|
|
11
|
+
// --- JSON path ---
|
|
12
|
+
let parsed;
|
|
21
13
|
try {
|
|
22
|
-
|
|
23
|
-
if (Array.isArray(parsed)) {
|
|
24
|
-
if (parsed.length > MAX_JSON_ITEMS) {
|
|
25
|
-
return JSON.stringify(parsed.slice(0, MAX_JSON_ITEMS), null, 2) + JSON_TRUNCATION_MSG;
|
|
26
|
-
}
|
|
27
|
-
return JSON.stringify(parsed, null, 2);
|
|
28
|
-
}
|
|
29
|
-
return JSON.stringify(parsed, null, 2);
|
|
14
|
+
parsed = JSON.parse(raw);
|
|
30
15
|
}
|
|
31
16
|
catch {
|
|
32
|
-
// Non-JSON
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return
|
|
17
|
+
// Non-JSON (error messages, plain text)
|
|
18
|
+
const text = raw.length > MAX_TEXT_CHARS
|
|
19
|
+
? raw.slice(0, MAX_TEXT_CHARS) + '...[truncated]'
|
|
20
|
+
: raw;
|
|
21
|
+
return {
|
|
22
|
+
data: null,
|
|
23
|
+
meta: { truncated: raw.length > MAX_TEXT_CHARS, error: text },
|
|
24
|
+
};
|
|
37
25
|
}
|
|
26
|
+
// Array response: truncate at item level
|
|
27
|
+
if (Array.isArray(parsed)) {
|
|
28
|
+
const truncated = parsed.length > MAX_JSON_ITEMS;
|
|
29
|
+
const data = truncated ? parsed.slice(0, MAX_JSON_ITEMS) : parsed;
|
|
30
|
+
return {
|
|
31
|
+
data,
|
|
32
|
+
meta: {
|
|
33
|
+
truncated,
|
|
34
|
+
returnedItems: data.length,
|
|
35
|
+
...(truncated
|
|
36
|
+
? { note: `Showing first ${MAX_JSON_ITEMS} items. Use --limit or filters to narrow results.` }
|
|
37
|
+
: {}),
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// Non-array JSON object: cap by serialised size
|
|
42
|
+
const serialised = JSON.stringify(parsed);
|
|
43
|
+
if (serialised.length > MAX_TEXT_CHARS) {
|
|
44
|
+
return {
|
|
45
|
+
data: null,
|
|
46
|
+
meta: {
|
|
47
|
+
truncated: true,
|
|
48
|
+
error: `Response object too large (${serialised.length} chars). Use filters to narrow results.`,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { data: parsed, meta: { truncated: false } };
|
|
38
53
|
}
|
|
39
|
-
|
|
40
|
-
import { buildToolDefinitions, buildGhArgs } from './schema.js';
|
|
41
|
-
const server = new Server({ name: 'zero-config-cli-bridge', version: '1.1.0' }, { capabilities: { tools: {} } });
|
|
54
|
+
const server = new Server({ name: 'zero-config-cli-bridge', version: '1.3.0' }, { capabilities: { tools: {} } });
|
|
42
55
|
let toolRegistry = new Map();
|
|
43
56
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
44
57
|
tools: Array.from(toolRegistry.values()).map(({ name, description, inputSchema }) => ({
|
|
@@ -52,10 +65,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
52
65
|
const args = (rawArgs ?? {});
|
|
53
66
|
const tool = toolRegistry.get(toolName);
|
|
54
67
|
if (!tool) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
const envelope = {
|
|
69
|
+
data: null,
|
|
70
|
+
meta: { truncated: false, error: `Unknown tool "${toolName}".` },
|
|
58
71
|
};
|
|
72
|
+
return { content: [{ type: 'text', text: JSON.stringify(envelope, null, 2) }], isError: true };
|
|
59
73
|
}
|
|
60
74
|
// Security: whitelist subcommand + validate arg values
|
|
61
75
|
try {
|
|
@@ -63,10 +77,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
63
77
|
validateArgs(args);
|
|
64
78
|
}
|
|
65
79
|
catch (err) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
80
|
+
const envelope = {
|
|
81
|
+
data: null,
|
|
82
|
+
meta: { truncated: false, error: err instanceof Error ? err.message : String(err) },
|
|
69
83
|
};
|
|
84
|
+
return { content: [{ type: 'text', text: JSON.stringify(envelope, null, 2) }], isError: true };
|
|
70
85
|
}
|
|
71
86
|
// Direct spawn — no shell, no injection surface
|
|
72
87
|
const ghArgs = buildGhArgs(tool, args);
|
|
@@ -75,20 +90,20 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
75
90
|
result = await executeCommand('gh', ghArgs);
|
|
76
91
|
}
|
|
77
92
|
catch (err) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
const envelope = {
|
|
94
|
+
data: null,
|
|
95
|
+
meta: { truncated: false, error: `Execution error: ${err instanceof Error ? err.message : String(err)}` },
|
|
81
96
|
};
|
|
97
|
+
return { content: [{ type: 'text', text: JSON.stringify(envelope, null, 2) }], isError: true };
|
|
82
98
|
}
|
|
83
|
-
const raw = result.stdout || result.stderr ||
|
|
84
|
-
const
|
|
99
|
+
const raw = result.stdout || result.stderr || '';
|
|
100
|
+
const envelope = toEnvelope(raw);
|
|
85
101
|
return {
|
|
86
|
-
content: [{ type: 'text', text:
|
|
102
|
+
content: [{ type: 'text', text: JSON.stringify(envelope, null, 2) }],
|
|
87
103
|
isError: result.exitCode !== 0,
|
|
88
104
|
};
|
|
89
105
|
});
|
|
90
106
|
async function main() {
|
|
91
|
-
// Probe local gh binary for available capabilities before accepting requests
|
|
92
107
|
const tools = await buildToolDefinitions();
|
|
93
108
|
toolRegistry = new Map(tools.map((t) => [t.name, t]));
|
|
94
109
|
const transport = new StdioServerTransport();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|