@systemdox/mcp-server 0.1.14 → 0.1.15
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/cli.js +31 -14
- package/dist/http.js +22 -14
- package/dist/index.js +22 -14
- package/dist/lib/config-links.d.ts +18 -0
- package/dist/lib/config-links.js +21 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -246,6 +246,27 @@ var init_deprecation = __esm({
|
|
|
246
246
|
}
|
|
247
247
|
});
|
|
248
248
|
|
|
249
|
+
// src/lib/config-links.ts
|
|
250
|
+
async function workspaceBase(apiClient2) {
|
|
251
|
+
try {
|
|
252
|
+
const access = await apiClient2.get(
|
|
253
|
+
"/v1/docs/portal-access"
|
|
254
|
+
);
|
|
255
|
+
const slug = (access.host ?? "").split(".")[0];
|
|
256
|
+
return slug ? `https://${slug}.systemdox.com` : null;
|
|
257
|
+
} catch {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function configLink(path, base) {
|
|
262
|
+
return base ? `${base}${path}` : `${path} in your SystemDox workspace`;
|
|
263
|
+
}
|
|
264
|
+
var init_config_links = __esm({
|
|
265
|
+
"src/lib/config-links.ts"() {
|
|
266
|
+
"use strict";
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
|
|
249
270
|
// src/tools/get-guardrails.ts
|
|
250
271
|
import { z } from "zod";
|
|
251
272
|
function registerGetGuardrails(server2, apiClient2) {
|
|
@@ -268,13 +289,9 @@ function registerGetGuardrails(server2, apiClient2) {
|
|
|
268
289
|
);
|
|
269
290
|
}
|
|
270
291
|
if (filtered.length === 0) {
|
|
292
|
+
const text2 = guardrails.length === 0 ? `No checks found. Add checks at ${configLink("/docs/guardrails", await workspaceBase(apiClient2))}` : `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`;
|
|
271
293
|
return {
|
|
272
|
-
content: [
|
|
273
|
-
{
|
|
274
|
-
type: "text",
|
|
275
|
-
text: `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`
|
|
276
|
-
}
|
|
277
|
-
]
|
|
294
|
+
content: [{ type: "text", text: text2 }]
|
|
278
295
|
};
|
|
279
296
|
}
|
|
280
297
|
const text = filtered.map(
|
|
@@ -331,6 +348,7 @@ var init_get_guardrails = __esm({
|
|
|
331
348
|
"use strict";
|
|
332
349
|
init_language();
|
|
333
350
|
init_deprecation();
|
|
351
|
+
init_config_links();
|
|
334
352
|
DESCRIPTION = "Retrieve SystemDox checks (banned patterns, required patterns, coding rules). Filter by language, category, or file path to get only relevant checks.";
|
|
335
353
|
inputSchema = () => ({
|
|
336
354
|
language: z.string().optional().describe(
|
|
@@ -559,7 +577,7 @@ function registerGetTechStack(server2, apiClient2) {
|
|
|
559
577
|
content: [
|
|
560
578
|
{
|
|
561
579
|
type: "text",
|
|
562
|
-
text:
|
|
580
|
+
text: `No tech stack entries configured. Add your stack at ${configLink("/docs/tech-stack", await workspaceBase(apiClient2))}`
|
|
563
581
|
}
|
|
564
582
|
]
|
|
565
583
|
};
|
|
@@ -593,6 +611,7 @@ ${sections}`
|
|
|
593
611
|
var init_get_tech_stack = __esm({
|
|
594
612
|
"src/tools/get-tech-stack.ts"() {
|
|
595
613
|
"use strict";
|
|
614
|
+
init_config_links();
|
|
596
615
|
}
|
|
597
616
|
});
|
|
598
617
|
|
|
@@ -1527,13 +1546,9 @@ function registerGetProjectRules(server2, apiClient2) {
|
|
|
1527
1546
|
);
|
|
1528
1547
|
}
|
|
1529
1548
|
if (filtered.length === 0) {
|
|
1549
|
+
const text2 = rules.length === 0 ? `No project rules found. Add rules at ${configLink("/docs/rules", await workspaceBase(apiClient2))}` : `No project rules found${category ? ` in category "${category}"` : ""}.`;
|
|
1530
1550
|
return {
|
|
1531
|
-
content: [
|
|
1532
|
-
{
|
|
1533
|
-
type: "text",
|
|
1534
|
-
text: `No project rules found${category ? ` in category "${category}"` : ""}.`
|
|
1535
|
-
}
|
|
1536
|
-
]
|
|
1551
|
+
content: [{ type: "text", text: text2 }]
|
|
1537
1552
|
};
|
|
1538
1553
|
}
|
|
1539
1554
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -1571,6 +1586,7 @@ var CATEGORY_LABELS;
|
|
|
1571
1586
|
var init_get_project_rules = __esm({
|
|
1572
1587
|
"src/tools/get-project-rules.ts"() {
|
|
1573
1588
|
"use strict";
|
|
1589
|
+
init_config_links();
|
|
1574
1590
|
CATEGORY_LABELS = {
|
|
1575
1591
|
deployment: "Deployment",
|
|
1576
1592
|
architecture: "Architecture",
|
|
@@ -1641,7 +1657,7 @@ function registerGetPromptTemplates(server2, apiClient2) {
|
|
|
1641
1657
|
content: [
|
|
1642
1658
|
{
|
|
1643
1659
|
type: "text",
|
|
1644
|
-
text:
|
|
1660
|
+
text: `No prompt templates found. Add templates at ${configLink("/docs/prompts", await workspaceBase(apiClient2))}`
|
|
1645
1661
|
}
|
|
1646
1662
|
]
|
|
1647
1663
|
};
|
|
@@ -1671,6 +1687,7 @@ ${text}`
|
|
|
1671
1687
|
var init_get_prompt_templates = __esm({
|
|
1672
1688
|
"src/tools/get-prompt-templates.ts"() {
|
|
1673
1689
|
"use strict";
|
|
1690
|
+
init_config_links();
|
|
1674
1691
|
}
|
|
1675
1692
|
});
|
|
1676
1693
|
|
package/dist/http.js
CHANGED
|
@@ -200,6 +200,22 @@ function legacyToolDescription(canonical, description) {
|
|
|
200
200
|
return `DEPRECATED \u2014 use \`${canonical}\` instead. This name still works and will not be removed before ${LEGACY_TOOL_REMOVAL_EARLIEST}. ${description}`;
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
+
// src/lib/config-links.ts
|
|
204
|
+
async function workspaceBase(apiClient) {
|
|
205
|
+
try {
|
|
206
|
+
const access = await apiClient.get(
|
|
207
|
+
"/v1/docs/portal-access"
|
|
208
|
+
);
|
|
209
|
+
const slug = (access.host ?? "").split(".")[0];
|
|
210
|
+
return slug ? `https://${slug}.systemdox.com` : null;
|
|
211
|
+
} catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function configLink(path, base) {
|
|
216
|
+
return base ? `${base}${path}` : `${path} in your SystemDox workspace`;
|
|
217
|
+
}
|
|
218
|
+
|
|
203
219
|
// src/tools/get-guardrails.ts
|
|
204
220
|
var DESCRIPTION = "Retrieve SystemDox checks (banned patterns, required patterns, coding rules). Filter by language, category, or file path to get only relevant checks.";
|
|
205
221
|
var inputSchema = () => ({
|
|
@@ -233,13 +249,9 @@ function registerGetGuardrails(server, apiClient) {
|
|
|
233
249
|
);
|
|
234
250
|
}
|
|
235
251
|
if (filtered.length === 0) {
|
|
252
|
+
const text2 = guardrails.length === 0 ? `No checks found. Add checks at ${configLink("/docs/guardrails", await workspaceBase(apiClient))}` : `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`;
|
|
236
253
|
return {
|
|
237
|
-
content: [
|
|
238
|
-
{
|
|
239
|
-
type: "text",
|
|
240
|
-
text: `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`
|
|
241
|
-
}
|
|
242
|
-
]
|
|
254
|
+
content: [{ type: "text", text: text2 }]
|
|
243
255
|
};
|
|
244
256
|
}
|
|
245
257
|
const text = filtered.map(
|
|
@@ -494,7 +506,7 @@ function registerGetTechStack(server, apiClient) {
|
|
|
494
506
|
content: [
|
|
495
507
|
{
|
|
496
508
|
type: "text",
|
|
497
|
-
text:
|
|
509
|
+
text: `No tech stack entries configured. Add your stack at ${configLink("/docs/tech-stack", await workspaceBase(apiClient))}`
|
|
498
510
|
}
|
|
499
511
|
]
|
|
500
512
|
};
|
|
@@ -1424,13 +1436,9 @@ function registerGetProjectRules(server, apiClient) {
|
|
|
1424
1436
|
);
|
|
1425
1437
|
}
|
|
1426
1438
|
if (filtered.length === 0) {
|
|
1439
|
+
const text2 = rules.length === 0 ? `No project rules found. Add rules at ${configLink("/docs/rules", await workspaceBase(apiClient))}` : `No project rules found${category ? ` in category "${category}"` : ""}.`;
|
|
1427
1440
|
return {
|
|
1428
|
-
content: [
|
|
1429
|
-
{
|
|
1430
|
-
type: "text",
|
|
1431
|
-
text: `No project rules found${category ? ` in category "${category}"` : ""}.`
|
|
1432
|
-
}
|
|
1433
|
-
]
|
|
1441
|
+
content: [{ type: "text", text: text2 }]
|
|
1434
1442
|
};
|
|
1435
1443
|
}
|
|
1436
1444
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -1519,7 +1527,7 @@ function registerGetPromptTemplates(server, apiClient) {
|
|
|
1519
1527
|
content: [
|
|
1520
1528
|
{
|
|
1521
1529
|
type: "text",
|
|
1522
|
-
text:
|
|
1530
|
+
text: `No prompt templates found. Add templates at ${configLink("/docs/prompts", await workspaceBase(apiClient))}`
|
|
1523
1531
|
}
|
|
1524
1532
|
]
|
|
1525
1533
|
};
|
package/dist/index.js
CHANGED
|
@@ -216,6 +216,22 @@ function legacyToolDescription(canonical, description) {
|
|
|
216
216
|
return `DEPRECATED \u2014 use \`${canonical}\` instead. This name still works and will not be removed before ${LEGACY_TOOL_REMOVAL_EARLIEST}. ${description}`;
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
// src/lib/config-links.ts
|
|
220
|
+
async function workspaceBase(apiClient2) {
|
|
221
|
+
try {
|
|
222
|
+
const access = await apiClient2.get(
|
|
223
|
+
"/v1/docs/portal-access"
|
|
224
|
+
);
|
|
225
|
+
const slug = (access.host ?? "").split(".")[0];
|
|
226
|
+
return slug ? `https://${slug}.systemdox.com` : null;
|
|
227
|
+
} catch {
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function configLink(path, base) {
|
|
232
|
+
return base ? `${base}${path}` : `${path} in your SystemDox workspace`;
|
|
233
|
+
}
|
|
234
|
+
|
|
219
235
|
// src/tools/get-guardrails.ts
|
|
220
236
|
var DESCRIPTION = "Retrieve SystemDox checks (banned patterns, required patterns, coding rules). Filter by language, category, or file path to get only relevant checks.";
|
|
221
237
|
var inputSchema = () => ({
|
|
@@ -249,13 +265,9 @@ function registerGetGuardrails(server2, apiClient2) {
|
|
|
249
265
|
);
|
|
250
266
|
}
|
|
251
267
|
if (filtered.length === 0) {
|
|
268
|
+
const text2 = guardrails.length === 0 ? `No checks found. Add checks at ${configLink("/docs/guardrails", await workspaceBase(apiClient2))}` : `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`;
|
|
252
269
|
return {
|
|
253
|
-
content: [
|
|
254
|
-
{
|
|
255
|
-
type: "text",
|
|
256
|
-
text: `No checks found${lang ? ` for language "${lang}"` : ""}${category ? ` in category "${category}"` : ""}.`
|
|
257
|
-
}
|
|
258
|
-
]
|
|
270
|
+
content: [{ type: "text", text: text2 }]
|
|
259
271
|
};
|
|
260
272
|
}
|
|
261
273
|
const text = filtered.map(
|
|
@@ -510,7 +522,7 @@ function registerGetTechStack(server2, apiClient2) {
|
|
|
510
522
|
content: [
|
|
511
523
|
{
|
|
512
524
|
type: "text",
|
|
513
|
-
text:
|
|
525
|
+
text: `No tech stack entries configured. Add your stack at ${configLink("/docs/tech-stack", await workspaceBase(apiClient2))}`
|
|
514
526
|
}
|
|
515
527
|
]
|
|
516
528
|
};
|
|
@@ -1440,13 +1452,9 @@ function registerGetProjectRules(server2, apiClient2) {
|
|
|
1440
1452
|
);
|
|
1441
1453
|
}
|
|
1442
1454
|
if (filtered.length === 0) {
|
|
1455
|
+
const text2 = rules.length === 0 ? `No project rules found. Add rules at ${configLink("/docs/rules", await workspaceBase(apiClient2))}` : `No project rules found${category ? ` in category "${category}"` : ""}.`;
|
|
1443
1456
|
return {
|
|
1444
|
-
content: [
|
|
1445
|
-
{
|
|
1446
|
-
type: "text",
|
|
1447
|
-
text: `No project rules found${category ? ` in category "${category}"` : ""}.`
|
|
1448
|
-
}
|
|
1449
|
-
]
|
|
1457
|
+
content: [{ type: "text", text: text2 }]
|
|
1450
1458
|
};
|
|
1451
1459
|
}
|
|
1452
1460
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -1535,7 +1543,7 @@ function registerGetPromptTemplates(server2, apiClient2) {
|
|
|
1535
1543
|
content: [
|
|
1536
1544
|
{
|
|
1537
1545
|
type: "text",
|
|
1538
|
-
text:
|
|
1546
|
+
text: `No prompt templates found. Add templates at ${configLink("/docs/prompts", await workspaceBase(apiClient2))}`
|
|
1539
1547
|
}
|
|
1540
1548
|
]
|
|
1541
1549
|
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { SystemDoxApiClient } from "./api-client.js";
|
|
2
|
+
/**
|
|
3
|
+
* The tenant's workspace base URL (https://{slug}.systemdox.com), or null
|
|
4
|
+
* when it can't be resolved. The slug is the first label of the portal host
|
|
5
|
+
* that GET /v1/docs/portal-access reports — the API builds that host as
|
|
6
|
+
* `{slug}.{DOCS_DOMAIN}`, so the first label is the slug whichever docs
|
|
7
|
+
* domain is live. The GET goes through the api client's response cache, so
|
|
8
|
+
* repeated empty states don't re-fetch.
|
|
9
|
+
*/
|
|
10
|
+
export declare function workspaceBase(apiClient: SystemDoxApiClient): Promise<string | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Where to add missing configuration: a full URL when the workspace base is
|
|
13
|
+
* known, the in-app path otherwise.
|
|
14
|
+
*
|
|
15
|
+
* Mirrored by apps/app/src/pages/ai/mcpPreview.ts — keep the output
|
|
16
|
+
* byte-identical when either side changes.
|
|
17
|
+
*/
|
|
18
|
+
export declare function configLink(path: string, base: string | null): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/config-links.ts
|
|
4
|
+
async function workspaceBase(apiClient) {
|
|
5
|
+
try {
|
|
6
|
+
const access = await apiClient.get(
|
|
7
|
+
"/v1/docs/portal-access"
|
|
8
|
+
);
|
|
9
|
+
const slug = (access.host ?? "").split(".")[0];
|
|
10
|
+
return slug ? `https://${slug}.systemdox.com` : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function configLink(path, base) {
|
|
16
|
+
return base ? `${base}${path}` : `${path} in your SystemDox workspace`;
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
configLink,
|
|
20
|
+
workspaceBase
|
|
21
|
+
};
|
package/package.json
CHANGED