@thalovant/mcp-server 0.1.8 → 0.1.9
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/.env.example +3 -0
- package/CHANGELOG.md +7 -0
- package/README.md +41 -3
- package/dist/index.js +15 -3
- package/examples/claude_desktop_config.json +1 -0
- package/package.json +1 -1
- package/server.json +3 -3
package/.env.example
CHANGED
|
@@ -3,6 +3,9 @@ THALOVANT_PROFILE=prod
|
|
|
3
3
|
THALOVANT_API_URL=https://api.thalovant.com
|
|
4
4
|
|
|
5
5
|
# Use one control-plane auth option for private/admin tools.
|
|
6
|
+
# Recommended: a scoped, revocable API token (dashboard or device flow).
|
|
7
|
+
# Minimum scopes for the full tool surface: hubs:read, clients:write, memory:read, memory:write.
|
|
8
|
+
# THALOVANT_API_TOKEN=
|
|
6
9
|
# THALOVANT_ACCESS_TOKEN=
|
|
7
10
|
# THALOVANT_EMAIL=
|
|
8
11
|
# THALOVANT_PASSWORD=
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.9
|
|
4
|
+
|
|
5
|
+
- Added first-class scoped API token auth for the control plane: set `THALOVANT_API_TOKEN` and the server authenticates with the token directly and never calls the login endpoint. Precedence is `THALOVANT_API_TOKEN`, then `THALOVANT_ACCESS_TOKEN`, then the `THALOVANT_EMAIL`/`THALOVANT_PASSWORD` login fallback.
|
|
6
|
+
- `thalovant_config_status` now reports the active control-plane auth mode (`controlPlaneAuthMode`: `api-token`, `access-token`, `email-password`, or `none`) and `hasApiToken`, without revealing token values.
|
|
7
|
+
- Documented API tokens as the recommended auth mode for AI and CI use, including the minimum token scopes for the full control-plane tool surface: `hubs:read`, `clients:write`, `memory:read`, `memory:write`.
|
|
8
|
+
- Clarified the unauthenticated-tool error to name `THALOVANT_API_TOKEN` as the recommended option.
|
|
9
|
+
|
|
3
10
|
## 0.1.8
|
|
4
11
|
|
|
5
12
|
- Tightened memory tool input validation to match the control-plane API exactly: `title` max 160, `content` max 4096, `source` max 64, `consentScope` max 128, `consentVersion` max 64, `retentionPolicy` max 64 on create/update, and list `query` max 240, so invalid values fail with a clear client-side error instead of an opaque API 422.
|
package/README.md
CHANGED
|
@@ -29,13 +29,43 @@ npm run build
|
|
|
29
29
|
|
|
30
30
|
Node.js 20 or newer is required.
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Control-Plane Auth
|
|
33
33
|
|
|
34
34
|
Public hub discovery does not need Thalovant credentials. Private control-plane tools and runtime hub tools read credentials only from the MCP server environment or server-side principal credential files. Do not pass API tokens or passwords through chat or tool arguments.
|
|
35
35
|
|
|
36
|
+
The server selects control-plane auth in this order:
|
|
37
|
+
|
|
38
|
+
1. `THALOVANT_API_TOKEN` — a scoped Thalovant API token. Recommended.
|
|
39
|
+
2. `THALOVANT_ACCESS_TOKEN` — a pre-issued session access token.
|
|
40
|
+
3. `THALOVANT_EMAIL` + `THALOVANT_PASSWORD` — interactive-account login fallback.
|
|
41
|
+
|
|
42
|
+
When a token is set, the server never calls the login endpoint. `thalovant_config_status` reports the active mode as `controlPlaneAuthMode` without revealing token values.
|
|
43
|
+
|
|
44
|
+
### API Tokens (Recommended For AI Agents And CI)
|
|
45
|
+
|
|
46
|
+
Scoped API tokens are the right credential for AI and automation use: they are minted from the Thalovant dashboard (or through the device flow), carry only the scopes you grant, can be revoked individually, and never involve your account password or MFA. Tokens start with `tvpat_`.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
export THALOVANT_API_TOKEN="tvpat_..."
|
|
50
|
+
export THALOVANT_API_URL="https://api.thalovant.com"
|
|
51
|
+
|
|
52
|
+
npm start
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Minimum scopes for the full control-plane tool surface:
|
|
56
|
+
|
|
57
|
+
| Scope | Used by |
|
|
58
|
+
|-------|---------|
|
|
59
|
+
| `hubs:read` | `thalovant_list_hubs`, `thalovant_get_hub`, `thalovant_get_analytics_overview`, and the hub lookup inside `thalovant_create_client_identity` |
|
|
60
|
+
| `clients:write` | `thalovant_create_client_identity` (`POST /v1/clients`) |
|
|
61
|
+
| `memory:read` | `thalovant_list_memory_items`, `thalovant_get_memory_summary`, `thalovant_get_memory_item` |
|
|
62
|
+
| `memory:write` | `thalovant_create_memory_item`, `thalovant_update_memory_item`, `thalovant_delete_memory_item` |
|
|
63
|
+
|
|
64
|
+
Grant fewer scopes for narrower deployments: a read-only assistant needs only `hubs:read` and `memory:read`. `thalovant_get_analytics_overview` with `admin: true` additionally requires an admin account with `admin:analytics`, which API tokens for regular use should not carry. Runtime hub tools (`thalovant_ask`, `thalovant_send_action`, and friends) use Thalovant client identities, not control-plane tokens.
|
|
65
|
+
|
|
66
|
+
### Login Fallback
|
|
67
|
+
|
|
36
68
|
```bash
|
|
37
|
-
export THALOVANT_ACCESS_TOKEN="..."
|
|
38
|
-
# or
|
|
39
69
|
export THALOVANT_EMAIL="you@example.com"
|
|
40
70
|
export THALOVANT_PASSWORD="..."
|
|
41
71
|
|
|
@@ -45,6 +75,10 @@ export THALOVANT_API_URL="https://api.thalovant.com"
|
|
|
45
75
|
npm start
|
|
46
76
|
```
|
|
47
77
|
|
|
78
|
+
If neither a token nor email/password is configured, authenticated control-plane tools fail with a clear error naming the supported options.
|
|
79
|
+
|
|
80
|
+
## Local Stdio
|
|
81
|
+
|
|
48
82
|
The server speaks MCP over stdio and does not write logs to stdout.
|
|
49
83
|
|
|
50
84
|
Runtime hub tools load local identities in this order:
|
|
@@ -208,6 +242,8 @@ MCP_HTTP_TRUST_PROXY=false
|
|
|
208
242
|
|
|
209
243
|
## Claude Desktop
|
|
210
244
|
|
|
245
|
+
Recommended: authenticate with a scoped API token so the MCP config never contains your account password.
|
|
246
|
+
|
|
211
247
|
```json
|
|
212
248
|
{
|
|
213
249
|
"mcpServers": {
|
|
@@ -215,6 +251,7 @@ MCP_HTTP_TRUST_PROXY=false
|
|
|
215
251
|
"command": "node",
|
|
216
252
|
"args": ["/home/goldyfruit/Development/Thalovant/mcp/dist/index.js"],
|
|
217
253
|
"env": {
|
|
254
|
+
"THALOVANT_API_TOKEN": "tvpat_...",
|
|
218
255
|
"THALOVANT_PROFILE": "prod"
|
|
219
256
|
}
|
|
220
257
|
}
|
|
@@ -233,6 +270,7 @@ Use the same stdio command in your MCP client config:
|
|
|
233
270
|
"command": "node",
|
|
234
271
|
"args": ["/home/goldyfruit/Development/Thalovant/mcp/dist/index.js"],
|
|
235
272
|
"env": {
|
|
273
|
+
"THALOVANT_API_TOKEN": "tvpat_...",
|
|
236
274
|
"THALOVANT_PROFILE": "prod"
|
|
237
275
|
}
|
|
238
276
|
}
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import { mkdir } from "node:fs/promises";
|
|
|
14
14
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
15
15
|
import { createRemoteJWKSet, jwtVerify } from "jose";
|
|
16
16
|
import { z } from "zod";
|
|
17
|
-
const VERSION = "0.1.
|
|
17
|
+
const VERSION = "0.1.9";
|
|
18
18
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
19
19
|
const MAX_TIMEOUT_MS = 300_000;
|
|
20
20
|
const MAX_LIMIT = 100;
|
|
@@ -423,7 +423,8 @@ async function createControlPlane(options) {
|
|
|
423
423
|
const credential = await credentialForPrincipal(principal);
|
|
424
424
|
const canUseShared = allowSharedThalovantCredentials(principal);
|
|
425
425
|
const apiUrl = options.apiUrl ?? credential?.control?.apiUrl ?? (canUseShared ? process.env.THALOVANT_API_URL : undefined) ?? DEFAULT_CONTROL_API_URL;
|
|
426
|
-
const accessToken = credential?.control?.accessToken ??
|
|
426
|
+
const accessToken = credential?.control?.accessToken ??
|
|
427
|
+
(canUseShared ? process.env.THALOVANT_API_TOKEN ?? process.env.THALOVANT_ACCESS_TOKEN : undefined);
|
|
427
428
|
const api = new ThalovantControlPlane(apiUrl, {
|
|
428
429
|
accessToken,
|
|
429
430
|
userAgent: `thalovant-mcp/${VERSION}`,
|
|
@@ -439,9 +440,18 @@ async function createControlPlane(options) {
|
|
|
439
440
|
}
|
|
440
441
|
function ensureAuthenticated(api) {
|
|
441
442
|
if (!api.accessToken) {
|
|
442
|
-
throw new Error("This tool requires Thalovant API auth. Configure THALOVANT_ACCESS_TOKEN, THALOVANT_EMAIL/THALOVANT_PASSWORD, or per-principal Thalovant credentials for this MCP principal.");
|
|
443
|
+
throw new Error("This tool requires Thalovant API auth. Configure THALOVANT_API_TOKEN (recommended: a scoped, revocable API token), THALOVANT_ACCESS_TOKEN, THALOVANT_EMAIL/THALOVANT_PASSWORD, or per-principal Thalovant credentials for this MCP principal.");
|
|
443
444
|
}
|
|
444
445
|
}
|
|
446
|
+
function controlPlaneAuthModeFromEnv() {
|
|
447
|
+
if (process.env.THALOVANT_API_TOKEN)
|
|
448
|
+
return "api-token";
|
|
449
|
+
if (process.env.THALOVANT_ACCESS_TOKEN)
|
|
450
|
+
return "access-token";
|
|
451
|
+
if (process.env.THALOVANT_EMAIL && process.env.THALOVANT_PASSWORD)
|
|
452
|
+
return "email-password";
|
|
453
|
+
return "none";
|
|
454
|
+
}
|
|
445
455
|
async function createRuntimeClient(options) {
|
|
446
456
|
const protocol = options.protocol ?? "wss";
|
|
447
457
|
const principal = currentPrincipal();
|
|
@@ -896,6 +906,8 @@ export function createServer() {
|
|
|
896
906
|
},
|
|
897
907
|
}, async () => jsonContent({
|
|
898
908
|
apiUrl: process.env.THALOVANT_API_URL ?? DEFAULT_CONTROL_API_URL,
|
|
909
|
+
controlPlaneAuthMode: controlPlaneAuthModeFromEnv(),
|
|
910
|
+
hasApiToken: Boolean(process.env.THALOVANT_API_TOKEN),
|
|
899
911
|
hasAccessToken: Boolean(process.env.THALOVANT_ACCESS_TOKEN),
|
|
900
912
|
hasEmailPassword: Boolean(process.env.THALOVANT_EMAIL && process.env.THALOVANT_PASSWORD),
|
|
901
913
|
profile: process.env.THALOVANT_PROFILE,
|
package/package.json
CHANGED
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.
|
|
10
|
+
"version": "0.1.9",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"identifier": "@thalovant/mcp-server",
|
|
15
|
-
"version": "0.1.
|
|
15
|
+
"version": "0.1.9",
|
|
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.
|
|
22
|
+
"identifier": "ghcr.io/thalovant/thalovant-mcp:0.1.9",
|
|
23
23
|
"transport": {
|
|
24
24
|
"type": "streamable-http",
|
|
25
25
|
"url": "http://127.0.0.1:3000/mcp"
|