@topolo/mcp 0.9.0 → 0.9.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/dist/http.js +172 -172
- package/dist/index.js +63 -6
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// ../topolo-sdk/dist/index.js
|
|
7
7
|
function applyAuthHeaders(headers, credential) {
|
|
8
8
|
if (credential.kind === "api_key") {
|
|
9
9
|
headers.set("X-Api-Key", credential.apiKey);
|
|
@@ -69,6 +69,7 @@ var APP_API_URLS = {
|
|
|
69
69
|
auth: "https://auth.topolo.app",
|
|
70
70
|
backup: "https://backup.topolo.app",
|
|
71
71
|
books: "https://books.topolo.app",
|
|
72
|
+
brand: "https://brand.topolo.app",
|
|
72
73
|
bugfix: "https://bugfix.topolo.app",
|
|
73
74
|
bytes: "https://bytes.topolo.app",
|
|
74
75
|
calendar: "https://calendar.topolo.app",
|
|
@@ -249,6 +250,38 @@ var APPLICATIONS = {
|
|
|
249
250
|
}
|
|
250
251
|
]
|
|
251
252
|
},
|
|
253
|
+
"brand": {
|
|
254
|
+
"id": "brand",
|
|
255
|
+
"appDir": "TopoloBrand",
|
|
256
|
+
"name": "topolo-brand",
|
|
257
|
+
"packageName": "@topolo/topolo-brand",
|
|
258
|
+
"productionUrl": "https://brand.topolo.app",
|
|
259
|
+
"services": [
|
|
260
|
+
"brand"
|
|
261
|
+
],
|
|
262
|
+
"deployTargets": [
|
|
263
|
+
{
|
|
264
|
+
"name": "topolo-brand",
|
|
265
|
+
"kind": "worker",
|
|
266
|
+
"apiUrl": "https://brand.topolo.app",
|
|
267
|
+
"domains": [
|
|
268
|
+
"brand.topolo.app"
|
|
269
|
+
],
|
|
270
|
+
"routes": [
|
|
271
|
+
"brand.topolo.app"
|
|
272
|
+
],
|
|
273
|
+
"appId": "brand"
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"name": "topolo-brand-api",
|
|
277
|
+
"kind": "worker",
|
|
278
|
+
"apiUrl": null,
|
|
279
|
+
"domains": [],
|
|
280
|
+
"routes": [],
|
|
281
|
+
"appId": null
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
},
|
|
252
285
|
"bugfix": {
|
|
253
286
|
"id": "bugfix",
|
|
254
287
|
"appDir": "TopoloBugFix",
|
|
@@ -2363,6 +2396,8 @@ var TopoloClient = class _TopoloClient {
|
|
|
2363
2396
|
requireConfirmForWrites;
|
|
2364
2397
|
timeoutMs;
|
|
2365
2398
|
fetchImpl;
|
|
2399
|
+
credentialProvider;
|
|
2400
|
+
credentialLoadInFlight = null;
|
|
2366
2401
|
refreshCredential;
|
|
2367
2402
|
refreshInFlight = null;
|
|
2368
2403
|
debug;
|
|
@@ -2390,6 +2425,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2390
2425
|
this.requireConfirmForWrites = options.requireConfirmForWrites !== false;
|
|
2391
2426
|
this.timeoutMs = options.timeoutMs ?? 3e4;
|
|
2392
2427
|
this.fetchImpl = options.fetch ?? fetch;
|
|
2428
|
+
this.credentialProvider = options.credentialProvider;
|
|
2393
2429
|
this.refreshCredential = options.refreshCredential;
|
|
2394
2430
|
this.debug = options.debug;
|
|
2395
2431
|
}
|
|
@@ -2412,6 +2448,7 @@ var TopoloClient = class _TopoloClient {
|
|
|
2412
2448
|
`Mutating ${method} requests require { confirm: true }. This guardrail prevents agents from issuing writes without an explicit human-in-the-loop acknowledgement.`
|
|
2413
2449
|
);
|
|
2414
2450
|
}
|
|
2451
|
+
await this.loadCurrentCredential();
|
|
2415
2452
|
const resolvedService = opts.baseUrl ? { serviceKey: normalizeLookupKey(opts.service), baseUrl: requireHttpOrigin(opts.baseUrl) } : await this.resolveRequestService(opts.service);
|
|
2416
2453
|
const baseUrl = resolvedService.baseUrl;
|
|
2417
2454
|
const url = new URL(opts.path, baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`);
|
|
@@ -2523,6 +2560,19 @@ var TopoloClient = class _TopoloClient {
|
|
|
2523
2560
|
});
|
|
2524
2561
|
return parsed;
|
|
2525
2562
|
}
|
|
2563
|
+
async loadCurrentCredential() {
|
|
2564
|
+
if (!this.credentialProvider) return;
|
|
2565
|
+
this.credentialLoadInFlight ??= this.credentialProvider().then((credential) => {
|
|
2566
|
+
if (!credential) {
|
|
2567
|
+
throw new TopoloAuthError("The configured Topolo credential is no longer available.");
|
|
2568
|
+
}
|
|
2569
|
+
this.credential = credential;
|
|
2570
|
+
return credential;
|
|
2571
|
+
}).finally(() => {
|
|
2572
|
+
this.credentialLoadInFlight = null;
|
|
2573
|
+
});
|
|
2574
|
+
await this.credentialLoadInFlight;
|
|
2575
|
+
}
|
|
2526
2576
|
async refreshRejectedAccessToken(attemptedAccessToken) {
|
|
2527
2577
|
if (this.credential.kind === "access_token" && this.credential.accessToken !== attemptedAccessToken) {
|
|
2528
2578
|
return this.credential;
|
|
@@ -3369,7 +3419,7 @@ function createTopolo(options) {
|
|
|
3369
3419
|
};
|
|
3370
3420
|
}
|
|
3371
3421
|
|
|
3372
|
-
//
|
|
3422
|
+
// ../topolo-sdk/dist/node/credential-store.js
|
|
3373
3423
|
import { mkdir, readFile, writeFile, chmod } from "fs/promises";
|
|
3374
3424
|
import { existsSync } from "fs";
|
|
3375
3425
|
import { homedir, platform } from "os";
|
|
@@ -3407,6 +3457,7 @@ var APP_API_URLS2 = {
|
|
|
3407
3457
|
auth: "https://auth.topolo.app",
|
|
3408
3458
|
backup: "https://backup.topolo.app",
|
|
3409
3459
|
books: "https://books.topolo.app",
|
|
3460
|
+
brand: "https://brand.topolo.app",
|
|
3410
3461
|
bugfix: "https://bugfix.topolo.app",
|
|
3411
3462
|
bytes: "https://bytes.topolo.app",
|
|
3412
3463
|
calendar: "https://calendar.topolo.app",
|
|
@@ -3663,9 +3714,9 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
|
|
|
3663
3714
|
const profile = profileForEnvironment(config, environment);
|
|
3664
3715
|
const cred = profile.credential;
|
|
3665
3716
|
if (!cred || cred.kind !== "access_token") return cred ?? null;
|
|
3666
|
-
if (!cred.refreshToken || !
|
|
3717
|
+
if (!cred.refreshToken || !profile.oauthClientId) return cred;
|
|
3667
3718
|
const now = Math.floor(Date.now() / 1e3);
|
|
3668
|
-
if (!options.force && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
|
|
3719
|
+
if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
|
|
3669
3720
|
try {
|
|
3670
3721
|
const oauth = new TopoloOAuth({
|
|
3671
3722
|
serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
|
|
@@ -3706,9 +3757,9 @@ async function refreshContextCredentialIfNeeded(environment, key, options = {})
|
|
|
3706
3757
|
const credential = context?.credential;
|
|
3707
3758
|
if (!credential || credential.kind !== "access_token") return credential ?? null;
|
|
3708
3759
|
const oauthClientId = context.oauthClientId ?? profile.oauthClientId;
|
|
3709
|
-
if (!credential.refreshToken || !
|
|
3760
|
+
if (!credential.refreshToken || !oauthClientId) return credential;
|
|
3710
3761
|
const now = Math.floor(Date.now() / 1e3);
|
|
3711
|
-
if (!options.force && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
|
|
3762
|
+
if (!options.force && credential.expiresAt && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
|
|
3712
3763
|
try {
|
|
3713
3764
|
const oauth = new TopoloOAuth({
|
|
3714
3765
|
serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
|
|
@@ -4529,6 +4580,10 @@ async function resolveMcpCredential(environment, selector = process.env.TOPOLO_C
|
|
|
4529
4580
|
return {
|
|
4530
4581
|
credential,
|
|
4531
4582
|
contextKey,
|
|
4583
|
+
credentialProvider: () => dependencies.refreshContextCredentialIfNeeded(
|
|
4584
|
+
environment,
|
|
4585
|
+
contextKey
|
|
4586
|
+
),
|
|
4532
4587
|
refreshCredential: () => dependencies.refreshContextCredentialIfNeeded(
|
|
4533
4588
|
environment,
|
|
4534
4589
|
contextKey,
|
|
@@ -4539,6 +4594,7 @@ async function resolveMcpCredential(environment, selector = process.env.TOPOLO_C
|
|
|
4539
4594
|
return {
|
|
4540
4595
|
credential: await dependencies.refreshCredentialIfNeeded(environment),
|
|
4541
4596
|
contextKey: null,
|
|
4597
|
+
credentialProvider: () => dependencies.refreshCredentialIfNeeded(environment),
|
|
4542
4598
|
refreshCredential: () => dependencies.refreshCredentialIfNeeded(environment, { force: true })
|
|
4543
4599
|
};
|
|
4544
4600
|
}
|
|
@@ -4567,6 +4623,7 @@ async function main() {
|
|
|
4567
4623
|
},
|
|
4568
4624
|
serviceUrls,
|
|
4569
4625
|
requireConfirmForWrites: true,
|
|
4626
|
+
...resolvedCredential.credentialProvider ? { credentialProvider: resolvedCredential.credentialProvider } : {},
|
|
4570
4627
|
...resolvedCredential.refreshCredential ? { refreshCredential: resolvedCredential.refreshCredential } : {}
|
|
4571
4628
|
});
|
|
4572
4629
|
const scopes = await loadScopes(topolo);
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/mcp",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.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": {
|
|
7
|
-
"topolo-mcp": "
|
|
7
|
+
"topolo-mcp": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
"./dispatch": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@topolo/sdk": "^0.9.
|
|
39
|
+
"@topolo/sdk": "^0.9.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@topolo/sdk": "file:../topolo-sdk",
|