# Thalovant MCP [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/thalovant/thalovant-mcp  
**GitHub Stars:** 0  
**npm Downloads (last month):** 1819  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/thalovant-mcp

## Description
Connect MCP clients to Thalovant control-plane and hub runtime APIs over stdio or Streamable HTTP.

## Tools
Capabilities this server exposes over MCP:

- **thalovant_config_status** — Inspect local Thalovant MCP configuration without revealing secret values.
- **thalovant_list_public_hubs** — List Thalovant public hubs. This read-only discovery call does not require authentication. Page size is capped at 48.
- **thalovant_get_public_hub** — Fetch one public Thalovant hub by id or slug.
- **thalovant_list_hubs** — List authenticated Thalovant hubs visible to the account.
- **thalovant_get_hub** — Fetch one authenticated Thalovant hub by UUID.
- **thalovant_get_operation** — Read the status of an asynchronous control-plane operation returned by provisioning.
- **thalovant_create_client_identity** — Create a Thalovant client identity (a hub connection) for a hub. The identity is secret; output is redacted unless savePath is used. Pass connectionType (for example home_assistant) for a connection of that kind: the API must answer with the same kind, or the connection it made instead is deleted and the call fails. A new connection is admitted by its hub in about ninety seconds; follow operationId with thalovant_wait_for_admission before connecting.
- **thalovant_wait_for_admission** — Wait until a hub admits a connection made with thalovant_create_client_identity: about ninety seconds after the create. Follows the operation the create returned (operationId), reading it every pollIntervalMs; a 429 is waited out for the time the API names. outcome is admitted (ready, or an operation the API no longer tracks), failed -- the platform could not admit it (errorCode says why, status is null) or the API refused the wait itself (status, code and detail say what it answered) -- or timeout: timeoutMs passed first and the connection may still be admitted, so call this tool again rather than creating another connection. A token the API refuses (401, 403) or an API out of reach is a tool error of its own, not a failed admission. Omit operationId when the create returned none. Reads only.
- **thalovant_begin_device_login** — Start a device sign-in (RFC 8628) when no API token is configured: a person approves it in a browser. Show the person verificationUri and userCode (or verificationUriComplete, which carries the code), then call thalovant_poll_device_login with loginId every `interval` seconds. The device code stays on this server. Once approved, control-plane tools for this principal use the token it minted. A Home Assistant link asks for hubs:read, clients:read and clients:write, which is also all a Free plan can approve, and signs in as the registered app thalovant-home-assistant (clientId).
- **thalovant_poll_device_login** — Ask once whether the person approved a device sign-in started with thalovant_begin_device_login. outcome is pending (poll again after `interval` seconds, already lengthened if the API asked to slow down), approved (control-plane tools for this principal now use the token; tokenId, scopes and expiresAt describe it), expired or denied (begin a new sign-in). The token itself is never returned.
- **thalovant_revoke_device_login** — Sign out: revoke the API token this principal signed in with through thalovant_poll_device_login, and stop using it. A token may always revoke itself, and one already revoked counts as revoked; signing out again answers alreadyRevoked without a request. Tokens configured on the server are never touched.
- **thalovant_identity_status** — Load a Thalovant identity and return redacted protocol and endpoint status.
- **thalovant_healthcheck** — Connect to a Thalovant hub with a saved identity and return runtime transport health.
- **thalovant_intent_inventory** — Discover a hub's registered intents, language examples and fallback skills using its runtime identity. listed_in names, per requested language, the hub language the sentences were listed in: a hub lists nothing under a language it did not load, so a language with no sentences is listed in its usual form or the closest language the hub loaded. When listed_in differs from the language asked, tell the user which language the sentences are in. Fallback skills come from ovos.skills.list in skill id order; the hub does not say in which order they are tried, so priority is null. Unknown fallback support remains distinct from a known empty list; answerability is a conservative hint.
- **thalovant_ask** — Send one text request to a Thalovant hub using a saved identity and return the normalized reply.
- **thalovant_query** — Send a routed HiveMind query using a saved identity and return the normalized reply. The hub may cascade the query according to its routing policy; a query can trigger actions.
- **thalovant_send_action** — Send one action to a Thalovant hub using a saved identity, the way a button or a shortcut would. The hub routes payload like a spoken request, so the skill that takes it can change things: switch a light, start a timer, play music. Returns once the action is sent, without waiting for the reply; use thalovant_ask to read the answer. THALOVANT_MCP_READONLY leaves this tool out.
- **thalovant_send_code** — Send one exact value to a Thalovant hub using a saved identity: something typed, scanned, a barcode, a QR code or a serial number. The hub receives it as an utterance whose input is marked exact, and a skill that recognizes the value may act on it. Returns once the value is sent, without waiting for a reply. THALOVANT_MCP_READONLY leaves this tool out.
- **thalovant_emit_event** — Emit a raw Thalovant event to a hub. Use only when a more specific runtime tool is not enough.
- **thalovant_wait_for_event** — Wait for one named hub event using a saved identity and return it: the first eventName the hub sends once the connection is made, or a timeout error after timeoutMs. sessionId, requestId and context narrow it to events carrying the same values. Listens only: it opens the connection and sends the hub no message, so it changes nothing.
- **thalovant_get_analytics_overview** — Read authenticated Thalovant analytics overview data.
- **thalovant_list_memory_items** — List authenticated Thalovant memory items.
- **thalovant_get_memory_summary** — Read authenticated Thalovant memory summary data.
- **thalovant_get_memory_item** — Read one authenticated Thalovant memory item.
- **thalovant_create_memory_item** — Create an explicit Thalovant memory item.
- **thalovant_update_memory_item** — Update an explicit Thalovant memory item.
- **thalovant_delete_memory_item** — Delete one Thalovant memory item.
- **thalovant_list_marketplace_skills** — Browse the Thalovant marketplace skill catalog. Start here when discovering what a hub could run: each entry carries the fields an install needs (skill_id, source_type, source_ref, package_name, version compatibility, config_schema, secret_schema) plus category, tags, verified, access_tier, and billing_sku. Requires the hubs:read scope and is NOT paid-gated, so a free-tier token can browse the catalog even though it cannot install from it. The response is not paginated — the whole catalog comes back at once.
- **thalovant_list_runtime_group_marketplace** — List the marketplace catalog resolved against one runtime group. This is the view to read immediately before installing: every catalog entry comes back with the group's own state folded in — whether the skill is desired (active, version_pin, source_type), whether it was observed running (observed_source, observed_at, intent counts), operator status, and the plan verdict (purchase_required, installable, access_message). Check installable and purchase_required here to avoid a 402 at install time. Requires the hubs:inspect scope; browsing needs no paid plan. Answers 404 for an unknown group and 403 when the caller does not own it.
- **thalovant_list_runtime_group_inventory** — List the skills a runtime group is actually observed running right now. Where thalovant_list_runtime_group_marketplace answers 'what could be installed here', this answers 'what is loaded'. Each entry carries skill_id, version, source, active, adapt_intents, padatious_intents, total_intents, and observed_at; the envelope reports source (ovos-runtime-operator, runtime-group-cache, or ovos-runtime-operator-pending), operator_phase, and operator_message. Unlike thalovant_get_hub_runtime_capabilities this never fails with 409 when nothing is reporting — it returns an empty list with a pending source. Requires the hubs:inspect scope; no paid plan needed.
- **thalovant_create_hub** — Create a Thalovant hub. Requires the hubs:write scope AND a paid plan: a token without the scope fails 403, and because the scope is checked before the plan, granting the scope can then surface a 402 'API access requires a paid plan'. The create is idempotent — the SDK sends an Idempotency-Key, so a retried create returns the first hub rather than making a second one; reusing a key with a DIFFERENT body fails 409.
- **thalovant_update_hub** — Partially update a Thalovant hub. Send ONLY the fields you are changing — do not round-trip a whole hub resource. name, namespace, and domain are immutable and are deliberately not accepted here; the API rejects a changed value with HTTP 400. This route uses optimistic locking and requires the hub's current etag, which lives in the hub resource BODY (there is no ETag response header), so call thalovant_get_hub first and pass the etag field from its response. A missing or stale etag fails 412 and changes nothing. Requires the hubs:write scope and a paid plan.
- **thalovant_release_hub** — Apply a release policy to a hub and return the updated hub. Every option is optional; omitted fields fall back to the workspace release policy. Passing images switches the hub to custom mode unless mode is also set; non-admins may pass only images the platform releases (see images). Requires the hubs:write scope and a paid plan. No etag is needed.
- **thalovant_set_hub_rating** — Rate a public Thalovant hub from 1 to 5 and return the updated hub. Requires the hubs:write scope; no paid plan is needed, so free-tier tokens can rate. Rating a non-public hub fails 400 "Only public hubs can be rated." and rating your own hub fails 400 "Hub owners cannot rate their own public hubs."
- **thalovant_clear_hub_rating** — Remove the caller's own rating from a public Thalovant hub and return the hub. This clears only the caller's rating, not the hub. Requires the hubs:write scope; no paid plan is needed.
- **thalovant_get_hub_runtime_capabilities** — Read the live skill and intent inventory a hub runtime exposes. Requires the hubs:inspect scope. The API answers HTTP 409 when the hub has no connected client that can report inventory — for a group-level view that returns an empty list instead of failing, use thalovant_list_runtime_group_inventory.
- **thalovant_list_runtime_groups** — List the Thalovant runtime groups visible to the authenticated account. Requires the hubs:read scope. The response is not paginated — every visible group is returned at once.
- **thalovant_get_runtime_group** — Fetch one Thalovant runtime group. Requires the hubs:read scope.
- **thalovant_create_runtime_group** — Create a Thalovant runtime group — the unit that hosts hubs and holds installed skills. Requires the hubs:write scope and a paid plan. Unlike the hub write routes this one takes no etag.
- **thalovant_update_runtime_group** — Update a Thalovant runtime group's name, description, or spec. spec patches replicas and container resources. This route does NOT use If-Match, so no etag is required. Requires the hubs:write scope and a paid plan.
- **thalovant_get_runtime_group_config** — Read a Thalovant runtime group's runtime configuration and personas. Requires the hubs:read scope. The revision returned by this call is used by safe configuration merges.
- **thalovant_update_runtime_group_config** — Merge runtime configuration into a Thalovant runtime group. The SDK reads and deep-merges config, then writes with a revision precondition. Only explicit HTTP 412 conflicts retry, at most three attempts; older APIs fail before a write. Set merge=false for explicit unconditional replacement. personas, when provided, is REPLACED wholesale rather than merged; omit it to leave stored personas untouched. Requires hubs:read and paid hubs:write for merging; replacement needs paid hubs:write.
- **thalovant_release_runtime_group** — Apply a runtime image policy to a Thalovant runtime group and return the updated group. Options behave like thalovant_release_hub: everything is optional, omitted fields fall back to the workspace release policy, and passing images switches to custom mode unless mode is also set (non-admins: only images the platform releases, see images). Requires the hubs:write scope and a paid plan.
- **thalovant_install_runtime_group_skill** — Install (or re-install) a skill in a Thalovant runtime group from the marketplace catalog. Installing a skill that is already present updates the existing entry rather than failing. Discover skillId with thalovant_list_marketplace_skills, then confirm installable/purchase_required with thalovant_list_runtime_group_marketplace before calling this. Requires the hubs:write scope and a paid plan (402 'API access requires a paid plan'); a paid marketplace skill ALSO needs marketplace access on the tenant plan, which fails with a second, distinct 402 about paid marketplace access. Only catalog sources are allowed by default: installing from a non-catalog source such as sourceType "git" runs code the marketplace never vetted and is refused unless the operator sets THALOVANT_ENABLE_GIT_SKILL_SOURCES.
- **thalovant_uninstall_runtime_group_skill** — Remove one skill from a Thalovant runtime group. This removes only the named skill; the runtime group and its other skills are untouched. Requires the hubs:write scope and a paid plan.
- **thalovant_list_hub_skill_history** — 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.
- **thalovant_list_hub_skills** — 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.
- **thalovant_install_hub_skill** — 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.
- **thalovant_update_hub_skill** — 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.
- **thalovant_remove_hub_skill** — 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.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "thalovant-mcp": {
    "command": "npx",
    "args": ["-y","@thalovant/mcp-server"],
    "env": {
      "THALOVANT_API_TOKEN": "",
      "THALOVANT_ACCESS_TOKEN": "",
      "THALOVANT_EMAIL": "",
      "THALOVANT_PASSWORD": "",
      "THALOVANT_API_URL": ""
    }
  }
}
```

**Requires environment variables:** `THALOVANT_API_TOKEN`, `THALOVANT_ACCESS_TOKEN`, `THALOVANT_EMAIL`, `THALOVANT_PASSWORD`, `THALOVANT_API_URL` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation

## What Thalovant MCP does

Thalovant MCP connects MCP hosts to Thalovant's control-plane and hub runtime APIs. Its tool surface covers public and private hub discovery, runtime-group inspection, marketplace and inventory queries, memory access, analytics, identity status, health checks, event waiting, and runtime interaction.

Runtime-facing tools include `thalovant_ask`, `thalovant_query`, `thalovant_send_action`, and `thalovant_send_code`. Control-plane tools expose operations such as listing hubs, retrieving hub details, checking operation status, examining runtime capabilities, and creating client identities. Device-login tools provide a browser-assisted sign-in flow for principals that do not have configured credentials.

## How it works

The package is implemented in Node.js with the official Thalovant SDK and the MCP TypeScript SDK. Local agents communicate through stdio. Remote agents use Streamable HTTP at `/mcp`; the server also publishes protected-resource metadata at `/.well-known/oauth-protected-resource`.

Authentication can use a scoped Thalovant API token, an existing access token, or an email and password fallback. Public hub discovery can run without Thalovant credentials. For browser-based authentication, the server begins and polls an RFC 8628 device flow, retaining the device code and resulting token for the principal during the process lifetime.

Remote deployments can use static bearer tokens, JWT/JWKS validation, or OAuth token introspection. Request handling includes host and origin validation, CORS, rate limiting, body-size limits, secure headers, and session binding. Optional event storage supports resumability, and JSONL audit logs are available.

## Setup and configuration

Run the published package with:

```bash
npx -y @thalovant/mcp-server
```

A source checkout can be built with `npm install` followed by `npm run build`. Node.js 20 or newer is required.

For token-based control-plane access, set a scoped API token and, when needed, the API origin:

```bash
export THALOVANT_API_TOKEN="tvpat_..."
export THALOVANT_API_URL="https://api.thalovant.com"
```

The server prioritizes `THALOVANT_API_TOKEN`, then `THALOVANT_ACCESS_TOKEN`, then `THALOVANT_EMAIL` with `THALOVANT_PASSWORD`. Credentials are read from the server environment or server-side principal files; tokens and passwords should not be sent through chat or tool arguments.

## Tools and capabilities

The available tools include:

- Public and authenticated hub listing and retrieval.
- Operation status checks, admission waiting, health checks, and identity status.
- Intent inventory, event waiting, analytics overview, and memory item access.
- Marketplace skill, runtime-group marketplace, runtime-group inventory, and runtime-group configuration queries.
- Hub runtime capability inspection.
- Device login beginning, polling, and revocation.
- Client identity creation.
- Runtime requests through ask, query, action, and code operations.

API-token scope controls access. A read-oriented deployment can use `hubs:read` and `memory:read`; discovery-only access can use `hubs:read`. Runtime hub tools use Thalovant client identities rather than control-plane tokens.

## Limitations and notes

Hub and runtime-group provisioning requires a paid plan in addition to the necessary scopes. Free-tier access can still discover marketplace entries and browse hubs, but installation and provisioning may be rejected. Marketplace results expose whether a skill is installable or requires purchase, allowing an agent to check access before attempting installation.

Hub updates and deletions use optimistic locking. The caller must first retrieve the hub and provide its current body-level `etag`; stale or missing values fail without applying changes. Hub name, namespace, and domain cannot be changed after creation, while runtime-group writes do not use etags.

Device-login polling is separate from beginning the login. The agent must show the returned verification URL and code to a person, then poll using the login identifier. Configured credentials are not replaced or revoked by this flow.

_Full upstream README: https://allmcps.com/mcp/thalovant-mcp/readme_

