@topolo/mcp 0.7.0 → 0.7.2

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 CHANGED
@@ -201,10 +201,33 @@ npx @modelcontextprotocol/inspector node dist/index.js
201
201
 
202
202
  ## Release Flow
203
203
 
204
- Preferred flow: push a `v<x.y.z>` tag to `main`; GitHub Actions typechecks,
205
- tests, builds, verifies the tag matches `package.json`, and publishes to npm via
206
- the `NPM_TOKEN` secret. Operators may publish directly with an npm token only
207
- after running the same package checks and `npm pack --dry-run`.
204
+ Agent packages are released locally from the `staging` branch after its package
205
+ gates pass. Publish in dependency order (`@topolo/sdk`, `@topolo/cli`, then
206
+ `@topolo/mcp`) so every public dependency already exists in the registry.
207
+
208
+ For each package, run its tests, typecheck, build, and tarball verification:
209
+
210
+ ```bash
211
+ pnpm --dir packages/topolo-mcp test
212
+ pnpm --dir packages/topolo-mcp typecheck
213
+ pnpm --dir packages/topolo-mcp build
214
+ node tooling/verify-npm-package.mjs packages/topolo-mcp
215
+ ```
216
+
217
+ The npm token is stored in the macOS Keychain under `registry.npmjs.org`. Use a
218
+ temporary npm config so the token is never written into the repository or
219
+ printed:
220
+
221
+ ```bash
222
+ printf '//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}\n' > /tmp/topolo-release.npmrc
223
+ NODE_AUTH_TOKEN="$(security find-generic-password -s registry.npmjs.org -w)" \
224
+ NPM_CONFIG_USERCONFIG=/tmp/topolo-release.npmrc \
225
+ sh -c 'cd packages/topolo-mcp && npm publish --access public'
226
+ ```
227
+
228
+ After publishing, install exact versions into an empty temporary directory and
229
+ exercise the SDK exports, CLI version command, MCP exports, and `topolo-mcp`
230
+ executable before updating `topoloPublishedVersion`.
208
231
 
209
232
  ## Phase 2 (planned)
210
233
 
package/dist/dispatch.js CHANGED
@@ -79,7 +79,7 @@ var TOOLS = [
79
79
  {
80
80
  name: "topolo_search_applications",
81
81
  title: "Search Topolo applications the agent can reach",
82
- description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns granted permissions, API URL, and launch URL without loading the global platform catalog.",
82
+ description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns actionService as the canonical selector for topolo_search_actions, plus granted permissions, API URL, and launch URL without loading the global platform catalog.",
83
83
  requiredScopes: [],
84
84
  destructive: false,
85
85
  inputSchema: {
@@ -102,6 +102,7 @@ var TOOLS = [
102
102
  return {
103
103
  id,
104
104
  appId: entry.appId,
105
+ actionService: entry.appId,
105
106
  slug: entry.slug,
106
107
  name: entry.name,
107
108
  apiBaseUrl: entry.apiBaseUrl,
@@ -128,7 +129,7 @@ var TOOLS = [
128
129
  properties: {
129
130
  service: {
130
131
  type: "string",
131
- description: "Required app id, slug, or name."
132
+ description: "Required application selector. Prefer actionService from topolo_search_applications; canonical app id, slug, and name are also accepted."
132
133
  },
133
134
  query: { type: "string" },
134
135
  cursor: { type: "string" },
@@ -215,13 +216,8 @@ var TOOLS = [
215
216
  if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
216
217
  throw new Error("input must be an object.");
217
218
  }
218
- const action = await topolo.client.getAction(actionId);
219
- const agentAccess = action.agentAccess ?? (action.destructive ? "off" : action.readOnly && !action.requiresConfirmation ? "auto" : "confirm");
220
- if (action.method !== "GET" || !action.readOnly || action.destructive || action.requiresConfirmation || agentAccess !== "auto") {
221
- throw new Error(`Action "${actionId}" is not an automatic read-only action. Use topolo_call_action with confirmation.`);
222
- }
223
219
  const resource = optionalResourceContext(args);
224
- return topolo.client.callAction(
220
+ return topolo.client.readAction(
225
221
  actionId,
226
222
  input ?? {},
227
223
  resource ? { resource } : {}
package/dist/http.js CHANGED
@@ -15887,7 +15887,7 @@ var TOOLS = [
15887
15887
  {
15888
15888
  name: "topolo_search_applications",
15889
15889
  title: "Search Topolo applications the agent can reach",
15890
- description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns granted permissions, API URL, and launch URL without loading the global platform catalog.",
15890
+ description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns actionService as the canonical selector for topolo_search_actions, plus granted permissions, API URL, and launch URL without loading the global platform catalog.",
15891
15891
  requiredScopes: [],
15892
15892
  destructive: false,
15893
15893
  inputSchema: {
@@ -15910,6 +15910,7 @@ var TOOLS = [
15910
15910
  return {
15911
15911
  id,
15912
15912
  appId: entry.appId,
15913
+ actionService: entry.appId,
15913
15914
  slug: entry.slug,
15914
15915
  name: entry.name,
15915
15916
  apiBaseUrl: entry.apiBaseUrl,
@@ -15936,7 +15937,7 @@ var TOOLS = [
15936
15937
  properties: {
15937
15938
  service: {
15938
15939
  type: "string",
15939
- description: "Required app id, slug, or name."
15940
+ description: "Required application selector. Prefer actionService from topolo_search_applications; canonical app id, slug, and name are also accepted."
15940
15941
  },
15941
15942
  query: { type: "string" },
15942
15943
  cursor: { type: "string" },
@@ -16023,13 +16024,8 @@ var TOOLS = [
16023
16024
  if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
16024
16025
  throw new Error("input must be an object.");
16025
16026
  }
16026
- const action = await topolo.client.getAction(actionId);
16027
- const agentAccess = action.agentAccess ?? (action.destructive ? "off" : action.readOnly && !action.requiresConfirmation ? "auto" : "confirm");
16028
- if (action.method !== "GET" || !action.readOnly || action.destructive || action.requiresConfirmation || agentAccess !== "auto") {
16029
- throw new Error(`Action "${actionId}" is not an automatic read-only action. Use topolo_call_action with confirmation.`);
16030
- }
16031
16027
  const resource = optionalResourceContext(args);
16032
- return topolo.client.callAction(
16028
+ return topolo.client.readAction(
16033
16029
  actionId,
16034
16030
  input ?? {},
16035
16031
  resource ? { resource } : {}
package/dist/index.js CHANGED
@@ -72,6 +72,7 @@ var APP_API_URLS = {
72
72
  bugfix: "https://bugfix.topolo.app",
73
73
  bytes: "https://bytes.topolo.app",
74
74
  calendar: "https://calendar.topolo.app",
75
+ campaigns: "https://campaigns.topolo.app",
75
76
  capacity: "https://capacity.topolo.app",
76
77
  chat: "https://chat.topolo.app",
77
78
  commerce: "https://commerce.topolo.app",
@@ -330,6 +331,38 @@ var APPLICATIONS = {
330
331
  }
331
332
  ]
332
333
  },
334
+ "campaigns": {
335
+ "id": "campaigns",
336
+ "appDir": "TopoloCampaigns",
337
+ "name": "topolo-campaigns",
338
+ "packageName": "topolo-campaigns",
339
+ "productionUrl": "https://campaigns.topolo.app",
340
+ "services": [
341
+ "campaigns"
342
+ ],
343
+ "deployTargets": [
344
+ {
345
+ "name": "topolo-campaigns",
346
+ "kind": "worker",
347
+ "apiUrl": "https://campaigns.topolo.app",
348
+ "domains": [
349
+ "campaigns.topolo.app"
350
+ ],
351
+ "routes": [
352
+ "campaigns.topolo.app"
353
+ ],
354
+ "appId": "campaigns"
355
+ },
356
+ {
357
+ "name": "topolo-campaigns-api",
358
+ "kind": "worker",
359
+ "apiUrl": null,
360
+ "domains": [],
361
+ "routes": [],
362
+ "appId": null
363
+ }
364
+ ]
365
+ },
333
366
  "capacity": {
334
367
  "id": "capacity",
335
368
  "appDir": "TopoloCapacity",
@@ -2504,7 +2537,21 @@ var TopoloClient = class _TopoloClient {
2504
2537
  return match;
2505
2538
  }
2506
2539
  async callAction(action, input = {}, options = {}) {
2540
+ const entry = await this.getAction(action);
2541
+ return this.executeResolvedAction(entry, input, options);
2542
+ }
2543
+ async readAction(action, input = {}, options = {}) {
2507
2544
  const entry = await this.getAction(action);
2545
+ const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2546
+ if (entry.method !== "GET" || !entry.readOnly || entry.destructive || entry.requiresConfirmation || agentAccess !== "auto") {
2547
+ throw new TopoloPermissionError(
2548
+ `Topolo action "${entry.actionId}" is not an automatic read-only action.`,
2549
+ entry.requiredPermission ? [entry.requiredPermission] : []
2550
+ );
2551
+ }
2552
+ return this.executeResolvedAction(entry, input, options);
2553
+ }
2554
+ async executeResolvedAction(entry, input, options) {
2508
2555
  const agentAccess = entry.agentAccess ?? (entry.destructive ? "off" : entry.readOnly && !entry.requiresConfirmation ? "auto" : "confirm");
2509
2556
  if (agentAccess === "off") {
2510
2557
  throw new TopoloPermissionError(
@@ -2576,6 +2623,7 @@ var TopoloClient = class _TopoloClient {
2576
2623
  const kind = payload.credentialType === "api_key" ? "api_key" : "access_token";
2577
2624
  return {
2578
2625
  kind,
2626
+ authorizationMode: normalizeCredentialAuthorizationMode(payload.authorizationMode, kind),
2579
2627
  user: {
2580
2628
  id: user.id,
2581
2629
  email: user.email,
@@ -2838,6 +2886,11 @@ function objectToQuery(value) {
2838
2886
  }
2839
2887
  return Object.keys(query).length > 0 ? query : void 0;
2840
2888
  }
2889
+ function normalizeCredentialAuthorizationMode(value, kind) {
2890
+ if (kind === "api_key") return "api_key";
2891
+ if (value === "context_rbac" || value === "oauth_scopes" || value === "session_rbac") return value;
2892
+ return "unknown";
2893
+ }
2841
2894
  function describeError(body, fallback) {
2842
2895
  if (body && typeof body === "object") {
2843
2896
  const maybe = body;
@@ -2980,6 +3033,7 @@ var APP_API_URLS2 = {
2980
3033
  bugfix: "https://bugfix.topolo.app",
2981
3034
  bytes: "https://bytes.topolo.app",
2982
3035
  calendar: "https://calendar.topolo.app",
3036
+ campaigns: "https://campaigns.topolo.app",
2983
3037
  capacity: "https://capacity.topolo.app",
2984
3038
  chat: "https://chat.topolo.app",
2985
3039
  commerce: "https://commerce.topolo.app",
@@ -3372,7 +3426,7 @@ var TOOLS = [
3372
3426
  {
3373
3427
  name: "topolo_search_applications",
3374
3428
  title: "Search Topolo applications the agent can reach",
3375
- description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns granted permissions, API URL, and launch URL without loading the global platform catalog.",
3429
+ description: "Searches the credential-scoped application registry with a bounded page and continuation cursor. Returns actionService as the canonical selector for topolo_search_actions, plus granted permissions, API URL, and launch URL without loading the global platform catalog.",
3376
3430
  requiredScopes: [],
3377
3431
  destructive: false,
3378
3432
  inputSchema: {
@@ -3395,6 +3449,7 @@ var TOOLS = [
3395
3449
  return {
3396
3450
  id,
3397
3451
  appId: entry.appId,
3452
+ actionService: entry.appId,
3398
3453
  slug: entry.slug,
3399
3454
  name: entry.name,
3400
3455
  apiBaseUrl: entry.apiBaseUrl,
@@ -3421,7 +3476,7 @@ var TOOLS = [
3421
3476
  properties: {
3422
3477
  service: {
3423
3478
  type: "string",
3424
- description: "Required app id, slug, or name."
3479
+ description: "Required application selector. Prefer actionService from topolo_search_applications; canonical app id, slug, and name are also accepted."
3425
3480
  },
3426
3481
  query: { type: "string" },
3427
3482
  cursor: { type: "string" },
@@ -3508,13 +3563,8 @@ var TOOLS = [
3508
3563
  if (input !== void 0 && (!input || typeof input !== "object" || Array.isArray(input))) {
3509
3564
  throw new Error("input must be an object.");
3510
3565
  }
3511
- const action = await topolo.client.getAction(actionId);
3512
- const agentAccess = action.agentAccess ?? (action.destructive ? "off" : action.readOnly && !action.requiresConfirmation ? "auto" : "confirm");
3513
- if (action.method !== "GET" || !action.readOnly || action.destructive || action.requiresConfirmation || agentAccess !== "auto") {
3514
- throw new Error(`Action "${actionId}" is not an automatic read-only action. Use topolo_call_action with confirmation.`);
3515
- }
3516
3566
  const resource = optionalResourceContext(args);
3517
- return topolo.client.callAction(
3567
+ return topolo.client.readAction(
3518
3568
  actionId,
3519
3569
  input ?? {},
3520
3570
  resource ? { resource } : {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topolo/mcp",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Model Context Protocol server for the Topolo platform. Exposes scope-gated tools that third-party agents (Claude, Codex, etc.) can call natively.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "@modelcontextprotocol/sdk": "^1.0.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "@topolo/sdk": "^0.8.1"
39
+ "@topolo/sdk": "^0.8.3"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@topolo/sdk": "file:../topolo-sdk",