@thalovant/mcp-server 0.1.24 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 — 2026-09-12
4
+
5
+ - Add a read-only hub skill history tool using Node SDK 0.4.0. The catalog now has 46 default tools, 23 in read-only mode, and 48 with destructive tools enabled.
6
+ - Correct shared-runtime skill scope and token requirements.
7
+
3
8
  ## 0.1.24
4
9
 
5
10
  - Require Node SDK 0.3.16 and use its public hub-skill methods instead of the temporary duplicate HTTP and polling implementation. Preserve tool schemas, accepted-operation output, API guidance and MCP cancellation checks.
package/README.md CHANGED
@@ -57,7 +57,7 @@ Minimum scopes for the full control-plane tool surface:
57
57
  | Scope | Used by |
58
58
  |-------|---------|
59
59
  | `hubs:read` | `thalovant_list_hubs`, `thalovant_get_hub`, `thalovant_get_analytics_overview`, `thalovant_list_marketplace_skills`, `thalovant_list_runtime_groups`, `thalovant_get_runtime_group`, `thalovant_get_runtime_group_config`, and the hub lookup inside `thalovant_create_client_identity` |
60
- | `hubs:inspect` | `thalovant_get_hub_runtime_capabilities`, `thalovant_list_runtime_group_marketplace`, `thalovant_list_runtime_group_inventory`, `thalovant_list_hub_skills` |
60
+ | `hubs:inspect` | `thalovant_get_hub_runtime_capabilities`, `thalovant_list_runtime_group_marketplace`, `thalovant_list_runtime_group_inventory`, `thalovant_list_hub_skills`, `thalovant_list_hub_skill_history` |
61
61
  | `hubs:write` | All hub and runtime-group provisioning: `thalovant_create_hub`, `thalovant_update_hub`, `thalovant_release_hub`, `thalovant_create_runtime_group`, `thalovant_update_runtime_group`, `thalovant_update_runtime_group_config`, `thalovant_release_runtime_group`, `thalovant_install_runtime_group_skill`, `thalovant_uninstall_runtime_group_skill`, the per-hub `thalovant_install_hub_skill`, `thalovant_update_hub_skill`, `thalovant_remove_hub_skill`, the hub rating tools, and the opt-in delete tools |
62
62
  | `clients:write` | `thalovant_create_client_identity` (`POST /v1/clients`) |
63
63
  | `memory:read` | `thalovant_list_memory_items`, `thalovant_get_memory_summary`, `thalovant_get_memory_item` |
@@ -81,7 +81,7 @@ Grant fewer scopes for narrower deployments: a read-only assistant needs only `h
81
81
 
82
82
  ### Hub Skills
83
83
 
84
- `thalovant_list_hub_skills`, `thalovant_install_hub_skill`, `thalovant_update_hub_skill`, and `thalovant_remove_hub_skill` act on **one hub**, not on a runtime group's skill set. A hub can start with no skills at all and gain them one at a time; a change applies live on the hub in about 15 seconds with no restart. `hubId` must be the hub UUID — the authenticated hub routes reject slugs.
84
+ `thalovant_list_hub_skills`, `thalovant_install_hub_skill`, `thalovant_update_hub_skill`, and `thalovant_remove_hub_skill` select a hub's attached runtime group; all hubs sharing it are affected. A hub can start with no skills at all and gain them one at a time; a change applies live on the hub in about 15 seconds with no restart. `hubId` must be the hub UUID — the authenticated hub routes reject slugs.
85
85
 
86
86
  `thalovant_list_hub_skills` returns the whole `GET /v1/hubs/{hub_id}/skills` envelope: `hub_id`, `runtime_group_id`, `observed_at`, `source`, the runtime's phase and message, and `data`, one row per skill (possibly empty) with `skill`, `title`, `marketplace_skill_id`, `package_name`, `source_type`, `install_source`, `version`, `version_pin`, `installed_version`, `observed_version`, `previous_version`, `latest_version`, `available_version`, `update_available`, `changelog`, `active`, `state`, the runtime's phase, message and last error, and `last_transition_at`. `state` is one of `pending`, `installed`, `failed`, `removing`, `drifted`, `quarantined`, or `unmanaged`; a change in progress shows as `pending`.
87
87
 
@@ -368,9 +368,10 @@ Hub and runtime-group provisioning:
368
368
  - `thalovant_install_runtime_group_skill`
369
369
  - `thalovant_uninstall_runtime_group_skill`
370
370
 
371
- Hub skills, acting on one hub (see [Hub Skills](#hub-skills); the list tool is read-only):
371
+ Hub skills, acting on the hub’s shared runtime (see [Hub Skills](#hub-skills); the list tool is read-only):
372
372
 
373
373
  - `thalovant_list_hub_skills`
374
+ - `thalovant_list_hub_skill_history`
374
375
  - `thalovant_install_hub_skill`
375
376
  - `thalovant_update_hub_skill`
376
377
  - `thalovant_remove_hub_skill`
@@ -436,7 +437,7 @@ Runtime calls sharing the same hub client identity run sequentially within one
436
437
  MCP process. Use a distinct client identity for each independently running MCP
437
438
  server so the hub can keep their sessions separate.
438
439
 
439
- Version 0.1.24 uses `@thalovant/sdk` `^0.3.16` (0.3.16 through versions below 0.4.0). This release enforces
440
+ Version 0.2.0 uses `@thalovant/sdk` `^0.4.0` (0.4.0 through versions below 0.5.0). This release enforces
440
441
  secure effective MQTT URLs and carries a single connection deadline through
441
442
  MQTT setup and HTTP failure cleanup. Runtime tools support
442
443
  HiveMind v3 Noise over WSS, HTTPS and MQTT over TLS. `thalovant_healthcheck`
@@ -510,3 +511,22 @@ options, and returns the same normalized reply shape as `thalovant_ask`. A query
510
511
  may trigger actions, so read-only mode hides it. Conversation workflows use
511
512
  `sessionId` with ask/query and the existing event-wait tool; MCP does not expose
512
513
  one tool for every SDK conversation or event-listener method.
514
+
515
+
516
+ ### Shared-runtime skill management
517
+
518
+ The catalog has 46 default tools, 23 in read-only mode, and 48 with destructive tools enabled.
519
+
520
+ Hub-addressed skill methods select the runtime group attached to the hub UUID.
521
+ Every hub sharing that group sees the same skill changes and history. The API
522
+ requires a restricted token to cover all served hubs. Reads need `hubs:inspect`
523
+ (`hubs:read` implies it); writes need `hubs:write`, an eligible paid plan and ownership.
524
+
525
+ The history response contains newest-first `event` and `operation` entries,
526
+ including nullable actor/version fields. Its limit is 1–200 (50 where omitted).
527
+ An accepted mutation is not proof the skill is ready. Optional waiting polls the
528
+ operation, with a 120-second default timeout and two-second interval. Polling
529
+ never repeats an accepted mutation and starts no new read after its deadline;
530
+ an already-running HTTP request retains its normal request timeout.
531
+
532
+ Read history with `thalovant_list_hub_skill_history` (`hubId`, optional `limit`). This tool remains available in read-only mode.
package/dist/index.js CHANGED
@@ -2152,9 +2152,20 @@ export function createServer() {
2152
2152
  await callControlPlane("write", () => api.uninstallRuntimeGroupSkill(runtimeGroupId, skillId));
2153
2153
  return textContent("Runtime group skill uninstalled.");
2154
2154
  });
2155
+ registerThalovantTool(server, "thalovant_list_hub_skill_history", {
2156
+ title: "List Hub Skill History",
2157
+ description: "Read newest-first skill events and operations for the runtime group attached to a hub. This history is shared by all hubs using that runtime. Requires hubs:inspect (hubs:read implies it); restricted tokens must cover all served hubs. Returns event/operation kind, timestamps, versions, actors and outcome fields. No changes are made.",
2158
+ inputSchema: { ...controlPlaneSchema, hubId: z.string().uuid().describe("Hub UUID (not the slug)."), limit: z.number().int().min(1).max(200).default(50) },
2159
+ annotations: { readOnlyHint: true, openWorldHint: true },
2160
+ }, async ({ hubId, limit, ...auth }) => {
2161
+ const api = await createControlPlane(auth);
2162
+ ensureAuthenticated(api);
2163
+ throwIfRuntimeCancelled(requestContext.getStore()?.signal);
2164
+ return jsonContent(redactSecrets(await callControlPlane("read", () => api.listHubSkillHistory(hubId, { limit }))));
2165
+ });
2155
2166
  registerThalovantTool(server, "thalovant_list_hub_skills", {
2156
2167
  title: "List Hub Skills",
2157
- description: "List the skills installed on ONE Thalovant hub. Returns the whole envelope: hub_id, runtime_group_id, observed_at, source, the runtime's phase and message, and data — one row per skill with version, version_pin, installed_version, observed_version, previous_version, latest_version, available_version, update_available, changelog, active, state (pending, installed, failed, removing, drifted, quarantined, unmanaged; a change in progress shows as pending), the runtime's last error and last_transition_at. This is per-hub, not the runtime group's skill set: a hub can start with an empty data array and gain skills one at a time with thalovant_install_hub_skill. hubId must be the hub UUID — the authenticated hub routes reject slugs; a hub with no runtime group attached fails 404 with code hub_without_runtime_group. Requires the hubs:inspect scope (hubs:read implies it); hub-restricted tokens only see the hubs in their allowlist.",
2168
+ description: "List the skills installed on the runtime group attached to a Thalovant hub. Returns the whole envelope: hub_id, runtime_group_id, observed_at, source, the runtime's phase and message, and data — one row per skill with version, version_pin, installed_version, observed_version, previous_version, latest_version, available_version, update_available, changelog, active, state (pending, installed, failed, removing, drifted, quarantined, unmanaged; a change in progress shows as pending), the runtime's last error and last_transition_at. The hub UUID selects its attached runtime group. Skills and changes are shared by every hub using that group; restricted tokens must cover all served hubs. hubId must be the hub UUID — the authenticated hub routes reject slugs; a hub with no runtime group attached fails 404 with code hub_without_runtime_group. Requires the hubs:inspect scope (hubs:read implies it); hub-restricted tokens only see the hubs in their allowlist.",
2158
2169
  inputSchema: {
2159
2170
  ...controlPlaneSchema,
2160
2171
  hubId: z.string().min(1).describe("Hub UUID (not the slug)."),
@@ -2168,7 +2179,7 @@ export function createServer() {
2168
2179
  });
2169
2180
  registerThalovantTool(server, "thalovant_install_hub_skill", {
2170
2181
  title: "Install Hub Skill",
2171
- description: "Install a skill on ONE Thalovant hub (not a runtime group or skill set). The change applies live on the hub in about 15 seconds, with no hub restart; a hub may start with no skills and gain them one at a time. Discover the skill name with thalovant_list_marketplace_skills. The API answers 202 with an operation_id and state \"installing\": pass wait: true to poll the operation until it converges (state \"installed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. The 202 body also carries hub_id, runtime_group_id and previous_version. Installing a skill that is already installed at ANOTHER version performs an update; the SAME version fails 409 with code skill_version_already_installed. Fails 404 with code hub_without_runtime_group when the hub has no runtime group attached yet, and 422 when \"latest\" cannot be resolved or the version string is invalid. hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. Hub-restricted tokens may only act on the hubs in their allowlist.",
2182
+ description: "Install a skill on the runtime group attached to a Thalovant hub. All hubs sharing that runtime group are affected. The change applies live on the hub in about 15 seconds, with no hub restart; a hub may start with no skills and gain them one at a time. Discover the skill name with thalovant_list_marketplace_skills. The API answers 202 with an operation_id and state \"installing\": pass wait: true to poll the operation until it converges (state \"installed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. The 202 body also carries hub_id, runtime_group_id and previous_version. Installing a skill that is already installed at ANOTHER version performs an update; the SAME version fails 409 with code skill_version_already_installed. Fails 404 with code hub_without_runtime_group when the hub has no runtime group attached yet, and 422 when \"latest\" cannot be resolved or the version string is invalid. hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. A hub-restricted token must cover every hub sharing the affected runtime group.",
2172
2183
  inputSchema: {
2173
2184
  ...controlPlaneSchema,
2174
2185
  hubId: z.string().min(1).describe("Hub UUID (not the slug)."),
@@ -2194,7 +2205,7 @@ export function createServer() {
2194
2205
  });
2195
2206
  registerThalovantTool(server, "thalovant_update_hub_skill", {
2196
2207
  title: "Update Hub Skill",
2197
- description: "Move a skill already installed on ONE Thalovant hub to a specific version (not a runtime group or skill set). The change applies live on the hub in about 15 seconds, with no hub restart. version is required — read the current version and latest_version from thalovant_list_hub_skills. The API answers 202 with an operation_id, hub_id, runtime_group_id, previous_version and state \"updating\": pass wait: true to poll the operation until it converges (state \"installed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. Fails 404 when the skill is not installed on the hub (code hub_without_runtime_group when the hub has no runtime group), 409 with code skill_version_already_installed when it is already at that version, and 422 for an invalid version. hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. Hub-restricted tokens may only act on the hubs in their allowlist.",
2208
+ description: "Move a skill already installed on the runtime group attached to a Thalovant hub to a specific version (not a runtime group or skill set). The change applies live on the hub in about 15 seconds, with no hub restart. version is required — read the current version and latest_version from thalovant_list_hub_skills. The API answers 202 with an operation_id, hub_id, runtime_group_id, previous_version and state \"updating\": pass wait: true to poll the operation until it converges (state \"installed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. Fails 404 when the skill is not installed on the hub (code hub_without_runtime_group when the hub has no runtime group), 409 with code skill_version_already_installed when it is already at that version, and 422 for an invalid version. hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. A hub-restricted token must cover every hub sharing the affected runtime group.",
2198
2209
  inputSchema: {
2199
2210
  ...controlPlaneSchema,
2200
2211
  hubId: z.string().min(1).describe("Hub UUID (not the slug)."),
@@ -2218,7 +2229,7 @@ export function createServer() {
2218
2229
  });
2219
2230
  registerThalovantTool(server, "thalovant_remove_hub_skill", {
2220
2231
  title: "Remove Hub Skill",
2221
- description: "Remove one skill from ONE Thalovant hub (not a runtime group or skill set). Only the named skill is removed; the hub and its other skills are untouched, and the change applies live on the hub in about 15 seconds with no hub restart. The API answers 202 with an operation_id, hub_id, runtime_group_id, previous_version (version is null) and state \"removing\": pass wait: true to poll the operation until it converges (state \"removed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. Fails 404 when the skill is not installed on the hub (code hub_without_runtime_group when the hub has no runtime group). hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. Hub-restricted tokens may only act on the hubs in their allowlist.",
2232
+ description: "Remove one skill from the runtime group attached to a Thalovant hub. Every hub sharing the runtime loses this skill; other skill attachments are unchanged, and the change applies live on the hub in about 15 seconds with no hub restart. The API answers 202 with an operation_id, hub_id, runtime_group_id, previous_version (version is null) and state \"removing\": pass wait: true to poll the operation until it converges (state \"removed\", or an error carrying the operation's failure message), with a 120 s default timeout; otherwise follow it with thalovant_get_operation. Fails 404 when the skill is not installed on the hub (code hub_without_runtime_group when the hub has no runtime group). hubId must be the hub UUID — the authenticated hub routes reject slugs. Requires the hubs:write scope and a paid plan; scope is checked before plan, so a free-plan token sees 403, never 402. A hub-restricted token must cover every hub sharing the affected runtime group.",
2222
2233
  inputSchema: {
2223
2234
  ...controlPlaneSchema,
2224
2235
  hubId: z.string().min(1).describe("Hub UUID (not the slug)."),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thalovant/mcp-server",
3
- "version": "0.1.24",
3
+ "version": "0.2.0",
4
4
  "description": "Stdio and Streamable HTTP MCP server for Thalovant control-plane and hub runtime APIs.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "dependencies": {
66
66
  "@modelcontextprotocol/sdk": "^1.30.0",
67
- "@thalovant/sdk": "^0.3.16",
67
+ "@thalovant/sdk": "^0.4.0",
68
68
  "jose": "^6.2.8",
69
69
  "zod": "^3.25.76"
70
70
  },
package/server.json CHANGED
@@ -7,19 +7,19 @@
7
7
  "url": "https://github.com/thalovant/thalovant-mcp",
8
8
  "source": "github"
9
9
  },
10
- "version": "0.1.24",
10
+ "version": "0.2.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@thalovant/mcp-server",
15
- "version": "0.1.24",
15
+ "version": "0.2.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
19
19
  },
20
20
  {
21
21
  "registryType": "oci",
22
- "identifier": "ghcr.io/thalovant/thalovant-mcp:0.1.24",
22
+ "identifier": "ghcr.io/thalovant/thalovant-mcp:0.2.0",
23
23
  "transport": {
24
24
  "type": "streamable-http",
25
25
  "url": "http://127.0.0.1:3000/mcp"