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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/server.mjs +36 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jujugrowth-mcp",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "MCP server connecting your AI coding assistant (Claude, Cursor, Codex) to jujugrowth — pull recommendations and apply them in your repo.",
5
5
  "type": "module",
6
6
  "bin": {
package/server.mjs CHANGED
@@ -58,12 +58,18 @@ const TOOLS = [
58
58
  inputSchema: {
59
59
  type: "object",
60
60
  properties: {
61
- tenantId: { type: "string", description: "the site to list (optional; required when more than one site is connected)" },
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("GET", `/recommendations${a.tenantId ? `?tenantId=${encodeURIComponent(a.tenantId)}` : ""}`),
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("POST", `/recommendations/${a.tenantId}/${a.recId}/handled`, a.note ? { note: a.note } : undefined),
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: { tools: TOOLS.map(({ name, description, inputSchema }) => ({ name, description, inputSchema })) },
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) return send({ jsonrpc: "2.0", id, error: { code: -32601, message: "unknown tool" } });
175
+ if (!tool)
176
+ return send({ jsonrpc: "2.0", id, error: { code: -32601, message: "unknown tool" } });
153
177
  try {
154
- if (!TOKEN) throw new Error("JUJUGROWTH_TOKEN not set — generate one in Settings → Developer");
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) send({ jsonrpc: "2.0", id, error: { code: -32601, message: "method not found" } });
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 ((nl = buf.indexOf("\n")) >= 0) {
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
  });