jujugrowth-mcp 1.0.8 → 1.0.9
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/package.json +1 -1
- package/server.mjs +36 -9
package/package.json
CHANGED
package/server.mjs
CHANGED
|
@@ -58,12 +58,18 @@ const TOOLS = [
|
|
|
58
58
|
inputSchema: {
|
|
59
59
|
type: "object",
|
|
60
60
|
properties: {
|
|
61
|
-
tenantId: {
|
|
61
|
+
tenantId: {
|
|
62
|
+
type: "string",
|
|
63
|
+
description: "the site to list (optional; required when more than one site is connected)",
|
|
64
|
+
},
|
|
62
65
|
},
|
|
63
66
|
additionalProperties: false,
|
|
64
67
|
},
|
|
65
68
|
run: async (a) =>
|
|
66
|
-
call(
|
|
69
|
+
call(
|
|
70
|
+
"GET",
|
|
71
|
+
`/recommendations${a.tenantId ? `?tenantId=${encodeURIComponent(a.tenantId)}` : ""}`,
|
|
72
|
+
),
|
|
67
73
|
},
|
|
68
74
|
{
|
|
69
75
|
name: "get_recommendation",
|
|
@@ -92,7 +98,11 @@ const TOOLS = [
|
|
|
92
98
|
additionalProperties: false,
|
|
93
99
|
},
|
|
94
100
|
run: async (a) =>
|
|
95
|
-
call(
|
|
101
|
+
call(
|
|
102
|
+
"POST",
|
|
103
|
+
`/recommendations/${a.tenantId}/${a.recId}/handled`,
|
|
104
|
+
a.note ? { note: a.note } : undefined,
|
|
105
|
+
),
|
|
96
106
|
},
|
|
97
107
|
{
|
|
98
108
|
name: "request_site_advice",
|
|
@@ -106,6 +116,13 @@ const TOOLS = [
|
|
|
106
116
|
},
|
|
107
117
|
run: async (a) => call("POST", `/site-advice/${a.tenantId}`),
|
|
108
118
|
},
|
|
119
|
+
{
|
|
120
|
+
name: "list_capability_gaps",
|
|
121
|
+
description:
|
|
122
|
+
"ADMIN/OPERATOR TOKEN ONLY. The jujugrowth system's OWN dev backlog: platform rules it has LEARNED (from docs + real platform responses) but cannot yet check because no collector observes the property the rule needs. Each item names the generic tool to build — `subject.attribute` per platform — with an example rule. Build that collector in the jujugrowth repo (make it write the property as a flat dotted attribute key on the synced entity); the gap auto-resolves once the fact is observable. The list is generated from real learned rules, never a hardcoded checklist. Returns 403 for non-admin tokens.",
|
|
123
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
124
|
+
run: async () => call("GET", "/capability-gaps"),
|
|
125
|
+
},
|
|
109
126
|
];
|
|
110
127
|
|
|
111
128
|
function send(msg) {
|
|
@@ -144,14 +161,22 @@ async function handle(msg) {
|
|
|
144
161
|
return send({
|
|
145
162
|
jsonrpc: "2.0",
|
|
146
163
|
id,
|
|
147
|
-
result: {
|
|
164
|
+
result: {
|
|
165
|
+
tools: TOOLS.map(({ name, description, inputSchema }) => ({
|
|
166
|
+
name,
|
|
167
|
+
description,
|
|
168
|
+
inputSchema,
|
|
169
|
+
})),
|
|
170
|
+
},
|
|
148
171
|
});
|
|
149
172
|
}
|
|
150
173
|
if (method === "tools/call") {
|
|
151
174
|
const tool = TOOLS.find((t) => t.name === params?.name);
|
|
152
|
-
if (!tool)
|
|
175
|
+
if (!tool)
|
|
176
|
+
return send({ jsonrpc: "2.0", id, error: { code: -32601, message: "unknown tool" } });
|
|
153
177
|
try {
|
|
154
|
-
if (!TOKEN)
|
|
178
|
+
if (!TOKEN)
|
|
179
|
+
throw new Error("JUJUGROWTH_TOKEN not set — generate one in Settings → Developer");
|
|
155
180
|
const result = await tool.run(params.arguments ?? {});
|
|
156
181
|
return send({
|
|
157
182
|
jsonrpc: "2.0",
|
|
@@ -168,17 +193,19 @@ async function handle(msg) {
|
|
|
168
193
|
});
|
|
169
194
|
}
|
|
170
195
|
}
|
|
171
|
-
if (id !== undefined)
|
|
196
|
+
if (id !== undefined)
|
|
197
|
+
send({ jsonrpc: "2.0", id, error: { code: -32601, message: "method not found" } });
|
|
172
198
|
}
|
|
173
199
|
|
|
174
200
|
let buf = "";
|
|
175
201
|
process.stdin.setEncoding("utf8");
|
|
176
202
|
process.stdin.on("data", (chunk) => {
|
|
177
203
|
buf += chunk;
|
|
178
|
-
let nl;
|
|
179
|
-
while (
|
|
204
|
+
let nl = buf.indexOf("\n");
|
|
205
|
+
while (nl >= 0) {
|
|
180
206
|
const line = buf.slice(0, nl).trim();
|
|
181
207
|
buf = buf.slice(nl + 1);
|
|
182
208
|
if (line) handle(JSON.parse(line)).catch((e) => process.stderr.write(`${e}\n`));
|
|
209
|
+
nl = buf.indexOf("\n");
|
|
183
210
|
}
|
|
184
211
|
});
|