@topolo/mcp 0.4.10 → 0.5.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/dispatch.js +17 -17
- package/dist/http.d.ts +2 -2
- package/dist/http.js +18 -18
- package/dist/index.js +148 -148
- package/package.json +1 -1
package/dist/dispatch.js
CHANGED
|
@@ -22,13 +22,13 @@ function hasScope(set, required) {
|
|
|
22
22
|
if (set.permissions.includes("*")) return true;
|
|
23
23
|
const [servicePart, actionPart] = splitPermission(required);
|
|
24
24
|
if (!servicePart) return set.permissions.includes(required);
|
|
25
|
-
const [
|
|
25
|
+
const [appId, resource] = splitService(servicePart);
|
|
26
26
|
const candidates = new Set([
|
|
27
27
|
required,
|
|
28
28
|
"*",
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
appId ? `${appId}.*` : null,
|
|
30
|
+
appId && resource && actionPart ? `${appId}.${resource}:*` : null,
|
|
31
|
+
appId && resource && actionPart ? `${appId}.${resource}.${actionPart}` : null,
|
|
32
32
|
resource && actionPart ? `${resource}:*` : null,
|
|
33
33
|
resource && actionPart ? `${resource}.${actionPart}` : null,
|
|
34
34
|
resource && actionPart ? `${resource}:${actionPart}` : null
|
|
@@ -80,10 +80,10 @@ var TOOLS = [
|
|
|
80
80
|
},
|
|
81
81
|
handler: async (topolo) => {
|
|
82
82
|
const services = (await topolo.client.listServices()).map((entry) => {
|
|
83
|
-
const id =
|
|
83
|
+
const id = displayAppId(entry);
|
|
84
84
|
return {
|
|
85
85
|
id,
|
|
86
|
-
|
|
86
|
+
appId: entry.appId,
|
|
87
87
|
slug: entry.slug,
|
|
88
88
|
name: entry.name,
|
|
89
89
|
apiBaseUrl: entry.apiBaseUrl,
|
|
@@ -110,7 +110,7 @@ var TOOLS = [
|
|
|
110
110
|
properties: {
|
|
111
111
|
service: {
|
|
112
112
|
type: "string",
|
|
113
|
-
description: "Optional
|
|
113
|
+
description: "Optional app id, slug, or name filter."
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
116
|
additionalProperties: false
|
|
@@ -139,7 +139,7 @@ var TOOLS = [
|
|
|
139
139
|
{
|
|
140
140
|
name: "topolo_get_application",
|
|
141
141
|
title: "Describe one Topolo platform application",
|
|
142
|
-
description: "Returns one live application catalog entry (
|
|
142
|
+
description: "Returns one live application catalog entry (app id, slug, name, API URL, launch URL, status). Accepts the app id, slug, or name. Resolved against the live registry so newly-registered apps work without a client rebuild.",
|
|
143
143
|
requiredScopes: [],
|
|
144
144
|
destructive: false,
|
|
145
145
|
inputSchema: {
|
|
@@ -147,7 +147,7 @@ var TOOLS = [
|
|
|
147
147
|
properties: {
|
|
148
148
|
application: {
|
|
149
149
|
type: "string",
|
|
150
|
-
description: "Application identifier:
|
|
150
|
+
description: "Application identifier: app id, slug, or name from topolo_list_applications."
|
|
151
151
|
}
|
|
152
152
|
},
|
|
153
153
|
required: ["application"],
|
|
@@ -161,10 +161,10 @@ var TOOLS = [
|
|
|
161
161
|
const needle = application.trim().toLowerCase();
|
|
162
162
|
const catalog = await topolo.client.listServices();
|
|
163
163
|
const match = catalog.find(
|
|
164
|
-
(e) => e.
|
|
164
|
+
(e) => e.appId.toLowerCase() === needle || e.slug && e.slug.toLowerCase() === needle || e.name && e.name.toLowerCase() === needle
|
|
165
165
|
);
|
|
166
166
|
if (!match) {
|
|
167
|
-
const known = catalog.map((e) => e.slug || e.
|
|
167
|
+
const known = catalog.map((e) => e.slug || e.appId).sort().filter((value) => typeof value === "string" && value.length > 0);
|
|
168
168
|
throw new Error(
|
|
169
169
|
`Unknown application "${application}". ${formatKnownValues(known, "applications")}`
|
|
170
170
|
);
|
|
@@ -370,7 +370,7 @@ function actionsToToolDefs(actions) {
|
|
|
370
370
|
}));
|
|
371
371
|
}
|
|
372
372
|
function toolNameForAction(action) {
|
|
373
|
-
const service = (action.serviceSlug || action.
|
|
373
|
+
const service = (action.serviceSlug || action.appId || "service").replace(/^topolo-/, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
374
374
|
const name = action.name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
375
375
|
return ["topolo", service, name].filter(Boolean).join("_").slice(0, 96);
|
|
376
376
|
}
|
|
@@ -431,18 +431,18 @@ function statusesAtOrWorse(threshold) {
|
|
|
431
431
|
if (threshold === "needs_review") return ["missing", "needs_review"];
|
|
432
432
|
return ["missing", "needs_review", "partial"];
|
|
433
433
|
}
|
|
434
|
-
function
|
|
435
|
-
for (const value of [entry.slug, entry.name, entry.
|
|
434
|
+
function displayAppId(entry) {
|
|
435
|
+
for (const value of [entry.slug, entry.name, entry.appId]) {
|
|
436
436
|
if (typeof value !== "string" || !value.trim()) continue;
|
|
437
|
-
for (const candidate of
|
|
437
|
+
for (const candidate of appIdCandidates(value)) {
|
|
438
438
|
if (Object.prototype.hasOwnProperty.call(DEFAULT_SERVICE_URLS, candidate)) {
|
|
439
439
|
return candidate;
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
442
|
}
|
|
443
|
-
return
|
|
443
|
+
return appIdCandidates(entry.slug || entry.appId)[0] || entry.appId;
|
|
444
444
|
}
|
|
445
|
-
function
|
|
445
|
+
function appIdCandidates(value) {
|
|
446
446
|
const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
|
|
447
447
|
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
448
448
|
return [.../* @__PURE__ */ new Set([
|
package/dist/http.d.ts
CHANGED
|
@@ -23,8 +23,8 @@ interface TopoloMcpHttpOptions {
|
|
|
23
23
|
path?: string;
|
|
24
24
|
/** Per-service URL overrides (e.g. staging). Passed through to createTopolo. */
|
|
25
25
|
serviceUrls?: Record<string, string>;
|
|
26
|
-
/** Per-service TopoloAuth
|
|
27
|
-
|
|
26
|
+
/** Per-service TopoloAuth app-id overrides. Passed through to createTopolo. */
|
|
27
|
+
appIds?: Record<string, string>;
|
|
28
28
|
/** Human-readable agent label for audit logs (forwarded to the SDK). */
|
|
29
29
|
agentName?: string;
|
|
30
30
|
/**
|
package/dist/http.js
CHANGED
|
@@ -15830,13 +15830,13 @@ function hasScope(set, required2) {
|
|
|
15830
15830
|
if (set.permissions.includes("*")) return true;
|
|
15831
15831
|
const [servicePart, actionPart] = splitPermission(required2);
|
|
15832
15832
|
if (!servicePart) return set.permissions.includes(required2);
|
|
15833
|
-
const [
|
|
15833
|
+
const [appId, resource] = splitService(servicePart);
|
|
15834
15834
|
const candidates = new Set([
|
|
15835
15835
|
required2,
|
|
15836
15836
|
"*",
|
|
15837
|
-
|
|
15838
|
-
|
|
15839
|
-
|
|
15837
|
+
appId ? `${appId}.*` : null,
|
|
15838
|
+
appId && resource && actionPart ? `${appId}.${resource}:*` : null,
|
|
15839
|
+
appId && resource && actionPart ? `${appId}.${resource}.${actionPart}` : null,
|
|
15840
15840
|
resource && actionPart ? `${resource}:*` : null,
|
|
15841
15841
|
resource && actionPart ? `${resource}.${actionPart}` : null,
|
|
15842
15842
|
resource && actionPart ? `${resource}:${actionPart}` : null
|
|
@@ -15888,10 +15888,10 @@ var TOOLS = [
|
|
|
15888
15888
|
},
|
|
15889
15889
|
handler: async (topolo) => {
|
|
15890
15890
|
const services = (await topolo.client.listServices()).map((entry) => {
|
|
15891
|
-
const id =
|
|
15891
|
+
const id = displayAppId(entry);
|
|
15892
15892
|
return {
|
|
15893
15893
|
id,
|
|
15894
|
-
|
|
15894
|
+
appId: entry.appId,
|
|
15895
15895
|
slug: entry.slug,
|
|
15896
15896
|
name: entry.name,
|
|
15897
15897
|
apiBaseUrl: entry.apiBaseUrl,
|
|
@@ -15918,7 +15918,7 @@ var TOOLS = [
|
|
|
15918
15918
|
properties: {
|
|
15919
15919
|
service: {
|
|
15920
15920
|
type: "string",
|
|
15921
|
-
description: "Optional
|
|
15921
|
+
description: "Optional app id, slug, or name filter."
|
|
15922
15922
|
}
|
|
15923
15923
|
},
|
|
15924
15924
|
additionalProperties: false
|
|
@@ -15947,7 +15947,7 @@ var TOOLS = [
|
|
|
15947
15947
|
{
|
|
15948
15948
|
name: "topolo_get_application",
|
|
15949
15949
|
title: "Describe one Topolo platform application",
|
|
15950
|
-
description: "Returns one live application catalog entry (
|
|
15950
|
+
description: "Returns one live application catalog entry (app id, slug, name, API URL, launch URL, status). Accepts the app id, slug, or name. Resolved against the live registry so newly-registered apps work without a client rebuild.",
|
|
15951
15951
|
requiredScopes: [],
|
|
15952
15952
|
destructive: false,
|
|
15953
15953
|
inputSchema: {
|
|
@@ -15955,7 +15955,7 @@ var TOOLS = [
|
|
|
15955
15955
|
properties: {
|
|
15956
15956
|
application: {
|
|
15957
15957
|
type: "string",
|
|
15958
|
-
description: "Application identifier:
|
|
15958
|
+
description: "Application identifier: app id, slug, or name from topolo_list_applications."
|
|
15959
15959
|
}
|
|
15960
15960
|
},
|
|
15961
15961
|
required: ["application"],
|
|
@@ -15969,10 +15969,10 @@ var TOOLS = [
|
|
|
15969
15969
|
const needle = application.trim().toLowerCase();
|
|
15970
15970
|
const catalog = await topolo.client.listServices();
|
|
15971
15971
|
const match = catalog.find(
|
|
15972
|
-
(e) => e.
|
|
15972
|
+
(e) => e.appId.toLowerCase() === needle || e.slug && e.slug.toLowerCase() === needle || e.name && e.name.toLowerCase() === needle
|
|
15973
15973
|
);
|
|
15974
15974
|
if (!match) {
|
|
15975
|
-
const known = catalog.map((e) => e.slug || e.
|
|
15975
|
+
const known = catalog.map((e) => e.slug || e.appId).sort().filter((value) => typeof value === "string" && value.length > 0);
|
|
15976
15976
|
throw new Error(
|
|
15977
15977
|
`Unknown application "${application}". ${formatKnownValues(known, "applications")}`
|
|
15978
15978
|
);
|
|
@@ -16178,7 +16178,7 @@ function actionsToToolDefs(actions) {
|
|
|
16178
16178
|
}));
|
|
16179
16179
|
}
|
|
16180
16180
|
function toolNameForAction(action) {
|
|
16181
|
-
const service = (action.serviceSlug || action.
|
|
16181
|
+
const service = (action.serviceSlug || action.appId || "service").replace(/^topolo-/, "").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
16182
16182
|
const name = action.name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
16183
16183
|
return ["topolo", service, name].filter(Boolean).join("_").slice(0, 96);
|
|
16184
16184
|
}
|
|
@@ -16239,18 +16239,18 @@ function statusesAtOrWorse(threshold) {
|
|
|
16239
16239
|
if (threshold === "needs_review") return ["missing", "needs_review"];
|
|
16240
16240
|
return ["missing", "needs_review", "partial"];
|
|
16241
16241
|
}
|
|
16242
|
-
function
|
|
16243
|
-
for (const value of [entry.slug, entry.name, entry.
|
|
16242
|
+
function displayAppId(entry) {
|
|
16243
|
+
for (const value of [entry.slug, entry.name, entry.appId]) {
|
|
16244
16244
|
if (typeof value !== "string" || !value.trim()) continue;
|
|
16245
|
-
for (const candidate of
|
|
16245
|
+
for (const candidate of appIdCandidates(value)) {
|
|
16246
16246
|
if (Object.prototype.hasOwnProperty.call(DEFAULT_SERVICE_URLS, candidate)) {
|
|
16247
16247
|
return candidate;
|
|
16248
16248
|
}
|
|
16249
16249
|
}
|
|
16250
16250
|
}
|
|
16251
|
-
return
|
|
16251
|
+
return appIdCandidates(entry.slug || entry.appId)[0] || entry.appId;
|
|
16252
16252
|
}
|
|
16253
|
-
function
|
|
16253
|
+
function appIdCandidates(value) {
|
|
16254
16254
|
const normalized = value.trim().toLowerCase().replace(/\s+/g, "-");
|
|
16255
16255
|
const withoutTopolo = normalized.startsWith("topolo-") ? normalized.slice("topolo-".length) : normalized;
|
|
16256
16256
|
return [.../* @__PURE__ */ new Set([
|
|
@@ -16383,7 +16383,7 @@ function createTopoloMcpHttpHandler(options = {}) {
|
|
|
16383
16383
|
...options.agentName ? { agentName: options.agentName } : {}
|
|
16384
16384
|
},
|
|
16385
16385
|
serviceUrls: options.serviceUrls,
|
|
16386
|
-
|
|
16386
|
+
appIds: options.appIds,
|
|
16387
16387
|
...options.fetch ? { fetch: options.fetch } : {},
|
|
16388
16388
|
// Hosted writes still go through the SDK's confirm gate: the tool layer
|
|
16389
16389
|
// sets { confirm } per-call based on each tool's requiresConfirmation.
|