mcpico 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/README.md +172 -0
- package/dist/config.d.ts +46 -0
- package/dist/config.js +32 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +87 -0
- package/dist/config.test.js.map +1 -0
- package/dist/discoverer.d.ts +52 -0
- package/dist/discoverer.js +84 -0
- package/dist/discoverer.js.map +1 -0
- package/dist/discoverer.test.d.ts +1 -0
- package/dist/discoverer.test.js +178 -0
- package/dist/discoverer.test.js.map +1 -0
- package/dist/grouper.d.ts +22 -0
- package/dist/grouper.js +70 -0
- package/dist/grouper.js.map +1 -0
- package/dist/grouper.test.d.ts +1 -0
- package/dist/grouper.test.js +169 -0
- package/dist/grouper.test.js.map +1 -0
- package/dist/help.d.ts +5 -0
- package/dist/help.js +115 -0
- package/dist/help.js.map +1 -0
- package/dist/help.test.d.ts +1 -0
- package/dist/help.test.js +173 -0
- package/dist/help.test.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +28 -0
- package/dist/parser.js +60 -0
- package/dist/parser.js.map +1 -0
- package/dist/parser.test.d.ts +1 -0
- package/dist/parser.test.js +142 -0
- package/dist/parser.test.js.map +1 -0
- package/dist/proxy.d.ts +6 -0
- package/dist/proxy.js +10 -0
- package/dist/proxy.js.map +1 -0
- package/dist/proxy.test.d.ts +1 -0
- package/dist/proxy.test.js +61 -0
- package/dist/proxy.test.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.js +212 -0
- package/dist/server.js.map +1 -0
- package/mcplico.example.json +18 -0
- package/package.json +36 -0
- package/src/config.test.ts +96 -0
- package/src/config.ts +76 -0
- package/src/discoverer.test.ts +222 -0
- package/src/discoverer.ts +148 -0
- package/src/grouper.test.ts +202 -0
- package/src/grouper.ts +96 -0
- package/src/help.test.ts +197 -0
- package/src/help.ts +134 -0
- package/src/index.ts +106 -0
- package/src/parser.test.ts +173 -0
- package/src/parser.ts +78 -0
- package/src/proxy.test.ts +77 -0
- package/src/proxy.ts +16 -0
- package/src/server.ts +299 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoverer.test.js","sourceRoot":"","sources":["../src/discoverer.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GroupOverrides } from "./config.js";
|
|
2
|
+
import type { UpstreamTool } from "./discoverer.js";
|
|
3
|
+
/**
|
|
4
|
+
* A group of related tools from an upstream server.
|
|
5
|
+
*/
|
|
6
|
+
export interface ToolGroup {
|
|
7
|
+
/** Group name (e.g., "filesystem") */
|
|
8
|
+
groupName: string;
|
|
9
|
+
/** Source server name */
|
|
10
|
+
serverName: string;
|
|
11
|
+
/** Tools in this group */
|
|
12
|
+
tools: UpstreamTool[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Group tools from an upstream server by prefix.
|
|
16
|
+
*
|
|
17
|
+
* Strategy:
|
|
18
|
+
* 1. If explicit group overrides exist, apply them first.
|
|
19
|
+
* 2. For remaining tools, extract prefix using separator.
|
|
20
|
+
* 3. Tools without a prefix go into the server's default group.
|
|
21
|
+
*/
|
|
22
|
+
export declare function groupTools(serverName: string, tools: UpstreamTool[], separator?: string, overrides?: GroupOverrides): ToolGroup[];
|
package/dist/grouper.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract the prefix from a tool name using the given separator.
|
|
3
|
+
* Returns null if no prefix detected.
|
|
4
|
+
*/
|
|
5
|
+
function extractPrefix(toolName, separator) {
|
|
6
|
+
const idx = toolName.indexOf(separator);
|
|
7
|
+
if (idx <= 0)
|
|
8
|
+
return null;
|
|
9
|
+
const prefix = toolName.slice(0, idx);
|
|
10
|
+
// Must have a non-empty suffix too
|
|
11
|
+
if (idx >= toolName.length - 1)
|
|
12
|
+
return null;
|
|
13
|
+
return prefix;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Group tools from an upstream server by prefix.
|
|
17
|
+
*
|
|
18
|
+
* Strategy:
|
|
19
|
+
* 1. If explicit group overrides exist, apply them first.
|
|
20
|
+
* 2. For remaining tools, extract prefix using separator.
|
|
21
|
+
* 3. Tools without a prefix go into the server's default group.
|
|
22
|
+
*/
|
|
23
|
+
export function groupTools(serverName, tools, separator = "_", overrides) {
|
|
24
|
+
const groups = new Map();
|
|
25
|
+
const ungrouped = [];
|
|
26
|
+
// Build override lookup: toolName → forcedGroupName
|
|
27
|
+
const overrideMap = new Map();
|
|
28
|
+
if (overrides) {
|
|
29
|
+
for (const [group, toolNames] of Object.entries(overrides)) {
|
|
30
|
+
for (const tn of toolNames) {
|
|
31
|
+
overrideMap.set(tn, group);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (const tool of tools) {
|
|
36
|
+
// Check explicit override
|
|
37
|
+
const forcedGroup = overrideMap.get(tool.name);
|
|
38
|
+
if (forcedGroup) {
|
|
39
|
+
const existing = groups.get(forcedGroup) || [];
|
|
40
|
+
existing.push(tool);
|
|
41
|
+
groups.set(forcedGroup, existing);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Try prefix extraction
|
|
45
|
+
const prefix = extractPrefix(tool.name, separator);
|
|
46
|
+
if (prefix) {
|
|
47
|
+
const existing = groups.get(prefix) || [];
|
|
48
|
+
existing.push(tool);
|
|
49
|
+
groups.set(prefix, existing);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
ungrouped.push(tool);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Tools without a prefix or override go into their own group per server
|
|
56
|
+
const result = [];
|
|
57
|
+
for (const [groupName, groupTools] of groups) {
|
|
58
|
+
result.push({ groupName, serverName, tools: groupTools });
|
|
59
|
+
}
|
|
60
|
+
if (ungrouped.length > 0) {
|
|
61
|
+
// Put ungrouped tools in a group named after the server
|
|
62
|
+
result.push({
|
|
63
|
+
groupName: serverName,
|
|
64
|
+
serverName,
|
|
65
|
+
tools: ungrouped,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=grouper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grouper.js","sourceRoot":"","sources":["../src/grouper.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,SAAS,aAAa,CACpB,QAAgB,EAChB,SAAiB;IAEjB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtC,mCAAmC;IACnC,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CACxB,UAAkB,EAClB,KAAqB,EACrB,YAAoB,GAAG,EACvB,SAA0B;IAE1B,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,oDAAoD;IACpD,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC9C,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3D,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC3B,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,0BAA0B;QAC1B,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAClC,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACnD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,MAAM,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,wDAAwD;QACxD,MAAM,CAAC,IAAI,CAAC;YACV,SAAS,EAAE,UAAU;YACrB,UAAU;YACV,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { groupTools } from "./grouper.js";
|
|
3
|
+
function makeTool(name, description) {
|
|
4
|
+
return { name, description, inputSchema: {} };
|
|
5
|
+
}
|
|
6
|
+
function groupNames(groups) {
|
|
7
|
+
return groups.map((g) => g.groupName);
|
|
8
|
+
}
|
|
9
|
+
function toolNames(group) {
|
|
10
|
+
return group.tools.map((t) => t.name);
|
|
11
|
+
}
|
|
12
|
+
describe("groupTools", () => {
|
|
13
|
+
describe("prefix-based grouping", () => {
|
|
14
|
+
it("groups tools by underscore prefix", () => {
|
|
15
|
+
const tools = [
|
|
16
|
+
makeTool("filesystem_read_file"),
|
|
17
|
+
makeTool("filesystem_write_file"),
|
|
18
|
+
makeTool("filesystem_list_dir"),
|
|
19
|
+
];
|
|
20
|
+
const groups = groupTools("test-server", tools);
|
|
21
|
+
expect(groups).toHaveLength(1);
|
|
22
|
+
expect(groups[0].groupName).toBe("filesystem");
|
|
23
|
+
expect(toolNames(groups[0])).toEqual([
|
|
24
|
+
"filesystem_read_file",
|
|
25
|
+
"filesystem_write_file",
|
|
26
|
+
"filesystem_list_dir",
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
it("groups tools with different prefixes into separate groups", () => {
|
|
30
|
+
const tools = [
|
|
31
|
+
makeTool("fs_read"),
|
|
32
|
+
makeTool("fs_write"),
|
|
33
|
+
makeTool("db_query"),
|
|
34
|
+
makeTool("db_insert"),
|
|
35
|
+
];
|
|
36
|
+
const groups = groupTools("test-server", tools);
|
|
37
|
+
expect(groups).toHaveLength(2);
|
|
38
|
+
expect(groupNames(groups)).toEqual(expect.arrayContaining(["fs", "db"]));
|
|
39
|
+
});
|
|
40
|
+
it("uses custom separator", () => {
|
|
41
|
+
const tools = [
|
|
42
|
+
makeTool("github.create_issue"),
|
|
43
|
+
makeTool("github.list_repos"),
|
|
44
|
+
];
|
|
45
|
+
const groups = groupTools("test-server", tools, ".");
|
|
46
|
+
expect(groups).toHaveLength(1);
|
|
47
|
+
expect(groups[0].groupName).toBe("github");
|
|
48
|
+
});
|
|
49
|
+
it("puts tools without prefix into server-named group", () => {
|
|
50
|
+
const tools = [
|
|
51
|
+
makeTool("read"),
|
|
52
|
+
makeTool("write"),
|
|
53
|
+
makeTool("filesystem_list"),
|
|
54
|
+
];
|
|
55
|
+
const groups = groupTools("my-server", tools);
|
|
56
|
+
const defaultGroup = groups.find((g) => g.groupName === "my-server");
|
|
57
|
+
expect(defaultGroup).toBeDefined();
|
|
58
|
+
expect(toolNames(defaultGroup)).toEqual(["read", "write"]);
|
|
59
|
+
});
|
|
60
|
+
it("handles mixed prefixed and unprefixed tools", () => {
|
|
61
|
+
const tools = [
|
|
62
|
+
makeTool("help"),
|
|
63
|
+
makeTool("status"),
|
|
64
|
+
makeTool("fs_read"),
|
|
65
|
+
];
|
|
66
|
+
const groups = groupTools("test-server", tools);
|
|
67
|
+
expect(groups).toHaveLength(2);
|
|
68
|
+
const fsGroup = groups.find((g) => g.groupName === "fs");
|
|
69
|
+
const defaultGroup = groups.find((g) => g.groupName === "test-server");
|
|
70
|
+
expect(fsGroup).toBeDefined();
|
|
71
|
+
expect(defaultGroup).toBeDefined();
|
|
72
|
+
expect(toolNames(defaultGroup)).toEqual(["help", "status"]);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe("explicit overrides", () => {
|
|
76
|
+
it("applies group overrides", () => {
|
|
77
|
+
const tools = [
|
|
78
|
+
makeTool("custom_tool_a"),
|
|
79
|
+
makeTool("custom_tool_b"),
|
|
80
|
+
];
|
|
81
|
+
const groups = groupTools("test-server", tools, "_", {
|
|
82
|
+
my_group: ["custom_tool_a", "custom_tool_b"],
|
|
83
|
+
});
|
|
84
|
+
expect(groups).toHaveLength(1);
|
|
85
|
+
expect(groups[0].groupName).toBe("my_group");
|
|
86
|
+
expect(toolNames(groups[0])).toEqual([
|
|
87
|
+
"custom_tool_a",
|
|
88
|
+
"custom_tool_b",
|
|
89
|
+
]);
|
|
90
|
+
});
|
|
91
|
+
it("mixes overrides with prefix-based grouping", () => {
|
|
92
|
+
const tools = [
|
|
93
|
+
makeTool("special_tool"),
|
|
94
|
+
makeTool("fs_read"),
|
|
95
|
+
makeTool("fs_write"),
|
|
96
|
+
];
|
|
97
|
+
const groups = groupTools("test-server", tools, "_", {
|
|
98
|
+
special: ["special_tool"],
|
|
99
|
+
});
|
|
100
|
+
expect(groups).toHaveLength(2);
|
|
101
|
+
const specialGroup = groups.find((g) => g.groupName === "special");
|
|
102
|
+
const fsGroup = groups.find((g) => g.groupName === "fs");
|
|
103
|
+
expect(specialGroup).toBeDefined();
|
|
104
|
+
expect(fsGroup).toBeDefined();
|
|
105
|
+
expect(toolNames(specialGroup)).toEqual(["special_tool"]);
|
|
106
|
+
});
|
|
107
|
+
it("overridden tools are removed from prefix groups", () => {
|
|
108
|
+
// "special_fs_read" would normally go in "special" prefix group,
|
|
109
|
+
// but override puts it in "custom" instead
|
|
110
|
+
const tools = [
|
|
111
|
+
makeTool("special_fs_read"),
|
|
112
|
+
makeTool("special_fs_write"),
|
|
113
|
+
];
|
|
114
|
+
const groups = groupTools("test-server", tools, "_", {
|
|
115
|
+
custom: ["special_fs_read"],
|
|
116
|
+
});
|
|
117
|
+
const customGroup = groups.find((g) => g.groupName === "custom");
|
|
118
|
+
const specialGroup = groups.find((g) => g.groupName === "special");
|
|
119
|
+
expect(customGroup).toBeDefined();
|
|
120
|
+
expect(specialGroup).toBeDefined();
|
|
121
|
+
expect(toolNames(customGroup)).toEqual(["special_fs_read"]);
|
|
122
|
+
expect(toolNames(specialGroup)).toEqual(["special_fs_write"]);
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe("edge cases", () => {
|
|
126
|
+
it("returns empty array for no tools", () => {
|
|
127
|
+
const groups = groupTools("test-server", []);
|
|
128
|
+
expect(groups).toEqual([]);
|
|
129
|
+
});
|
|
130
|
+
it("handles tools with separator at start (no prefix)", () => {
|
|
131
|
+
const tools = [makeTool("_read")];
|
|
132
|
+
const groups = groupTools("test-server", tools);
|
|
133
|
+
// Prefix index is 0, which is <= 0, so no prefix
|
|
134
|
+
expect(groups).toHaveLength(1);
|
|
135
|
+
expect(groups[0].groupName).toBe("test-server");
|
|
136
|
+
});
|
|
137
|
+
it("handles tools with separator at end (no suffix)", () => {
|
|
138
|
+
const tools = [makeTool("read_")];
|
|
139
|
+
const groups = groupTools("test-server", tools);
|
|
140
|
+
// Separator index is at last char, so no valid suffix
|
|
141
|
+
expect(groups).toHaveLength(1);
|
|
142
|
+
expect(groups[0].groupName).toBe("test-server");
|
|
143
|
+
});
|
|
144
|
+
it("sets serverName on all groups", () => {
|
|
145
|
+
const tools = [
|
|
146
|
+
makeTool("fs_read"),
|
|
147
|
+
makeTool("unprefixed"),
|
|
148
|
+
];
|
|
149
|
+
const groups = groupTools("my-server", tools);
|
|
150
|
+
for (const g of groups) {
|
|
151
|
+
expect(g.serverName).toBe("my-server");
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
it("handles multiple separators in tool name (takes first)", () => {
|
|
155
|
+
const tools = [makeTool("prefix_sub_sub")];
|
|
156
|
+
const groups = groupTools("test-server", tools);
|
|
157
|
+
expect(groups).toHaveLength(1);
|
|
158
|
+
expect(groups[0].groupName).toBe("prefix");
|
|
159
|
+
});
|
|
160
|
+
it("groups single-tool prefix correctly", () => {
|
|
161
|
+
const tools = [makeTool("solo_tool")];
|
|
162
|
+
const groups = groupTools("test-server", tools);
|
|
163
|
+
expect(groups).toHaveLength(1);
|
|
164
|
+
expect(groups[0].groupName).toBe("solo");
|
|
165
|
+
expect(groups[0].tools).toHaveLength(1);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
//# sourceMappingURL=grouper.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grouper.test.js","sourceRoot":"","sources":["../src/grouper.test.ts"],"names":[],"mappings":"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"}
|
package/dist/help.d.ts
ADDED
package/dist/help.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a human-readable property description from a JSON Schema property definition.
|
|
3
|
+
*/
|
|
4
|
+
function describeProperty(name, schema) {
|
|
5
|
+
const type = schema.type || "any";
|
|
6
|
+
const description = schema.description ? ` — ${schema.description}` : "";
|
|
7
|
+
const isRequired = schema._required ? " (required)" : " (optional)";
|
|
8
|
+
return `\`${name}\` (${type}${isRequired})${description}`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract property definitions from a JSON Schema object.
|
|
12
|
+
* Handles both flat and nested properties structures.
|
|
13
|
+
*/
|
|
14
|
+
function extractProperties(inputSchema) {
|
|
15
|
+
const properties = inputSchema.properties;
|
|
16
|
+
if (!properties)
|
|
17
|
+
return [];
|
|
18
|
+
const required = inputSchema.required || [];
|
|
19
|
+
return Object.entries(properties).map(([name, schema]) => ({
|
|
20
|
+
name,
|
|
21
|
+
schema: { ...schema, _required: required.includes(name) },
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate a human-readable type string from a JSON Schema type.
|
|
26
|
+
*/
|
|
27
|
+
function schemaType(schema) {
|
|
28
|
+
const t = schema.type;
|
|
29
|
+
if (Array.isArray(t))
|
|
30
|
+
return t.join(" | ");
|
|
31
|
+
if (typeof t === "string")
|
|
32
|
+
return t;
|
|
33
|
+
return "any";
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generate an example value for a property based on its schema type.
|
|
37
|
+
*/
|
|
38
|
+
function exampleValue(name, schema) {
|
|
39
|
+
const t = schemaType(schema);
|
|
40
|
+
if (t === "number" || t === "integer")
|
|
41
|
+
return "42";
|
|
42
|
+
if (t === "boolean")
|
|
43
|
+
return "true";
|
|
44
|
+
// For strings, use the property name as a hint
|
|
45
|
+
const lower = name.toLowerCase();
|
|
46
|
+
if (lower.includes("path"))
|
|
47
|
+
return '"/tmp/example.txt"';
|
|
48
|
+
if (lower.includes("name"))
|
|
49
|
+
return '"example-name"';
|
|
50
|
+
if (lower.includes("id"))
|
|
51
|
+
return '"abc-123"';
|
|
52
|
+
if (lower.includes("url") || lower.includes("uri"))
|
|
53
|
+
return '"https://example.com"';
|
|
54
|
+
if (lower.includes("content") || lower.includes("text"))
|
|
55
|
+
return '"Hello, world!"';
|
|
56
|
+
if (lower.includes("query") || lower.includes("search"))
|
|
57
|
+
return '"search terms"';
|
|
58
|
+
return '"value"';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate an example command string for a tool.
|
|
62
|
+
*/
|
|
63
|
+
function generateExample(tool) {
|
|
64
|
+
const props = extractProperties(tool.inputSchema);
|
|
65
|
+
if (props.length === 0)
|
|
66
|
+
return tool.name;
|
|
67
|
+
const required = props.filter((p) => p.schema._required);
|
|
68
|
+
const args = {};
|
|
69
|
+
for (const p of required.slice(0, 3)) {
|
|
70
|
+
args[p.name] = exampleValue(p.name, p.schema);
|
|
71
|
+
}
|
|
72
|
+
const argsStr = JSON.stringify(args);
|
|
73
|
+
// Keep examples compact
|
|
74
|
+
if (argsStr.length < 80) {
|
|
75
|
+
return `${tool.name} ${argsStr}`;
|
|
76
|
+
}
|
|
77
|
+
return tool.name;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Generate a complete help text for a tool group.
|
|
81
|
+
*/
|
|
82
|
+
export function generateHelpText(group) {
|
|
83
|
+
const lines = [];
|
|
84
|
+
lines.push(`⚡ MCPico — ${group.groupName}`);
|
|
85
|
+
lines.push("");
|
|
86
|
+
lines.push(`Source: ${group.serverName} (${group.tools.length} tool${group.tools.length === 1 ? "" : "s"})`);
|
|
87
|
+
lines.push("");
|
|
88
|
+
lines.push("Usage: <subcommand> {" + '"}key{"}": {"}value{"}' + "}");
|
|
89
|
+
lines.push(" Send just 'help' to see this reference again.");
|
|
90
|
+
lines.push("");
|
|
91
|
+
lines.push("─".repeat(50));
|
|
92
|
+
lines.push("");
|
|
93
|
+
for (const tool of group.tools) {
|
|
94
|
+
lines.push(` ${tool.name}`);
|
|
95
|
+
if (tool.description) {
|
|
96
|
+
lines.push(` ${tool.description}`);
|
|
97
|
+
}
|
|
98
|
+
lines.push("");
|
|
99
|
+
const props = extractProperties(tool.inputSchema);
|
|
100
|
+
if (props.length > 0) {
|
|
101
|
+
lines.push(" Parameters:");
|
|
102
|
+
for (const p of props) {
|
|
103
|
+
lines.push(` ${describeProperty(p.name, p.schema)}`);
|
|
104
|
+
}
|
|
105
|
+
lines.push("");
|
|
106
|
+
}
|
|
107
|
+
const example = generateExample(tool);
|
|
108
|
+
lines.push(` Example: ${example}`);
|
|
109
|
+
lines.push("");
|
|
110
|
+
}
|
|
111
|
+
lines.push("─".repeat(50));
|
|
112
|
+
lines.push("Generated by MCPico — auto-updates when upstream tools change.");
|
|
113
|
+
return lines.join("\n");
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=help.js.map
|
package/dist/help.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { generateHelpText } from "./help.js";
|
|
3
|
+
function makeTool(overrides = {}) {
|
|
4
|
+
return {
|
|
5
|
+
name: "test_tool",
|
|
6
|
+
description: "A test tool",
|
|
7
|
+
inputSchema: {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
param1: { type: "string", description: "First parameter" },
|
|
11
|
+
},
|
|
12
|
+
required: ["param1"],
|
|
13
|
+
},
|
|
14
|
+
...overrides,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function makeGroup(overrides = {}) {
|
|
18
|
+
return {
|
|
19
|
+
groupName: "test",
|
|
20
|
+
serverName: "test-server",
|
|
21
|
+
tools: [makeTool()],
|
|
22
|
+
...overrides,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
describe("generateHelpText", () => {
|
|
26
|
+
it("includes group name in header", () => {
|
|
27
|
+
const text = generateHelpText(makeGroup({ groupName: "filesystem" }));
|
|
28
|
+
expect(text).toContain("MCPico — filesystem");
|
|
29
|
+
});
|
|
30
|
+
it("includes server name", () => {
|
|
31
|
+
const text = generateHelpText(makeGroup({ serverName: "my-server" }));
|
|
32
|
+
expect(text).toContain("my-server");
|
|
33
|
+
});
|
|
34
|
+
it("shows correct tool count", () => {
|
|
35
|
+
const text = generateHelpText(makeGroup());
|
|
36
|
+
expect(text).toContain("1 tool");
|
|
37
|
+
});
|
|
38
|
+
it("shows plural for multiple tools", () => {
|
|
39
|
+
const group = makeGroup({
|
|
40
|
+
tools: [makeTool({ name: "tool_a" }), makeTool({ name: "tool_b" })],
|
|
41
|
+
});
|
|
42
|
+
const text = generateHelpText(group);
|
|
43
|
+
expect(text).toContain("2 tools");
|
|
44
|
+
});
|
|
45
|
+
it("includes usage instructions", () => {
|
|
46
|
+
const text = generateHelpText(makeGroup());
|
|
47
|
+
expect(text).toContain("Usage:");
|
|
48
|
+
expect(text).toContain("<subcommand>");
|
|
49
|
+
expect(text).toContain("Send just 'help'");
|
|
50
|
+
});
|
|
51
|
+
it("lists each tool by name", () => {
|
|
52
|
+
const group = makeGroup({
|
|
53
|
+
tools: [
|
|
54
|
+
makeTool({ name: "read_file", description: "Read a file" }),
|
|
55
|
+
makeTool({ name: "write_file", description: "Write a file" }),
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
const text = generateHelpText(group);
|
|
59
|
+
expect(text).toContain("read_file");
|
|
60
|
+
expect(text).toContain("Read a file");
|
|
61
|
+
expect(text).toContain("write_file");
|
|
62
|
+
expect(text).toContain("Write a file");
|
|
63
|
+
});
|
|
64
|
+
it("shows tool description", () => {
|
|
65
|
+
const text = generateHelpText(makeGroup({
|
|
66
|
+
tools: [makeTool({ description: "Does something useful" })],
|
|
67
|
+
}));
|
|
68
|
+
expect(text).toContain("Does something useful");
|
|
69
|
+
});
|
|
70
|
+
it("shows parameters section for tools with properties", () => {
|
|
71
|
+
const text = generateHelpText(makeGroup());
|
|
72
|
+
expect(text).toContain("Parameters:");
|
|
73
|
+
expect(text).toContain("param1");
|
|
74
|
+
expect(text).toContain("(string");
|
|
75
|
+
expect(text).toContain("(required)");
|
|
76
|
+
expect(text).toContain("First parameter");
|
|
77
|
+
});
|
|
78
|
+
it("marks optional parameters", () => {
|
|
79
|
+
const tool = makeTool({
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: "object",
|
|
82
|
+
properties: {
|
|
83
|
+
optional_param: { type: "string", description: "Not required" },
|
|
84
|
+
},
|
|
85
|
+
required: [],
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
89
|
+
expect(text).toContain("(optional)");
|
|
90
|
+
});
|
|
91
|
+
it("does not show Parameters section for tools without properties", () => {
|
|
92
|
+
const tool = makeTool({
|
|
93
|
+
inputSchema: { type: "object", properties: {} },
|
|
94
|
+
});
|
|
95
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
96
|
+
expect(text).not.toContain("Parameters:");
|
|
97
|
+
});
|
|
98
|
+
it("generates examples for tools with parameters", () => {
|
|
99
|
+
const tool = makeTool({
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: "object",
|
|
102
|
+
properties: {
|
|
103
|
+
path: { type: "string", description: "File path" },
|
|
104
|
+
},
|
|
105
|
+
required: ["path"],
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
109
|
+
expect(text).toContain("Example:");
|
|
110
|
+
expect(text).toContain("/tmp/example.txt");
|
|
111
|
+
});
|
|
112
|
+
it("shows bare subcommand for parameterless tools", () => {
|
|
113
|
+
const tool = makeTool({
|
|
114
|
+
inputSchema: { type: "object", properties: {} },
|
|
115
|
+
});
|
|
116
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
117
|
+
expect(text).toContain("Example:");
|
|
118
|
+
expect(text).toContain(tool.name);
|
|
119
|
+
});
|
|
120
|
+
it("includes footer", () => {
|
|
121
|
+
const text = generateHelpText(makeGroup());
|
|
122
|
+
expect(text).toContain("Generated by MCPico");
|
|
123
|
+
});
|
|
124
|
+
it("handles tools without descriptions", () => {
|
|
125
|
+
const tool = makeTool({ description: undefined });
|
|
126
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
127
|
+
expect(text).toContain(tool.name);
|
|
128
|
+
// Should not crash — tool is still listed
|
|
129
|
+
});
|
|
130
|
+
it("generates smart example values for known parameter names", () => {
|
|
131
|
+
const tool = makeTool({
|
|
132
|
+
name: "search",
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {
|
|
136
|
+
query: { type: "string", description: "Search query" },
|
|
137
|
+
limit: { type: "integer", description: "Max results" },
|
|
138
|
+
url: { type: "string", description: "Target URL" },
|
|
139
|
+
},
|
|
140
|
+
required: ["query", "limit", "url"],
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
144
|
+
expect(text).toContain("search terms");
|
|
145
|
+
expect(text).toContain("42");
|
|
146
|
+
expect(text).toContain("https://example.com");
|
|
147
|
+
});
|
|
148
|
+
it("handles tools with a mix of required and optional params in example", () => {
|
|
149
|
+
const tool = makeTool({
|
|
150
|
+
name: "write",
|
|
151
|
+
inputSchema: {
|
|
152
|
+
type: "object",
|
|
153
|
+
properties: {
|
|
154
|
+
path: { type: "string" },
|
|
155
|
+
content: { type: "string" },
|
|
156
|
+
encoding: { type: "string" },
|
|
157
|
+
},
|
|
158
|
+
required: ["path"],
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
162
|
+
// Example should show the required param
|
|
163
|
+
expect(text).toContain("path");
|
|
164
|
+
expect(text).toContain("/tmp/example.txt");
|
|
165
|
+
});
|
|
166
|
+
it("handles tools with no inputSchema", () => {
|
|
167
|
+
const tool = makeTool({ inputSchema: {} });
|
|
168
|
+
const text = generateHelpText(makeGroup({ tools: [tool] }));
|
|
169
|
+
expect(text).toContain(tool.name);
|
|
170
|
+
// Should not crash
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
//# sourceMappingURL=help.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.test.js","sourceRoot":"","sources":["../src/help.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCPico — MCP proxy that bundles flat tool lists into hierarchical subcommand groups.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* mcpico [--config <path>]
|
|
7
|
+
*
|
|
8
|
+
* Configuration is read from mcpico.json in the current directory by default.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|