@stackable-labs/mcp-app-extension 0.10.2 → 0.11.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/dist/{auth-37BRWM34.js → auth-5Z7FU2KG.js} +14 -53
- package/dist/{auth-7GIVRWDG.js → auth-7BRIJUR5.js} +14 -53
- package/dist/{chunk-J3MNH4OK.js → chunk-BDOVEKRM.js} +42 -2
- package/dist/{chunk-FIIWPDHX.js → chunk-HLVEV5OH.js} +42 -2
- package/dist/index.js +10 -6
- package/dist/server.js +10 -6
- package/package.json +1 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { writeAuthState, STANDALONE_CLIENT_AUTH_FILE } from './chunk-
|
|
2
|
+
import { deriveClientId, STANDALONE_CLIENT, getNonce, writeAuthState, STANDALONE_CLIENT_AUTH_FILE, getVerifier, getDigest } from './chunk-BDOVEKRM.js';
|
|
3
3
|
import { createServer } from 'http';
|
|
4
|
-
import
|
|
4
|
+
import process5 from 'process';
|
|
5
5
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
@@ -53,7 +53,7 @@ function isInsideContainer() {
|
|
|
53
53
|
|
|
54
54
|
// ../../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
55
55
|
var isWsl = () => {
|
|
56
|
-
if (
|
|
56
|
+
if (process5.platform !== "linux") {
|
|
57
57
|
return false;
|
|
58
58
|
}
|
|
59
59
|
if (os.release().toLowerCase().includes("microsoft")) {
|
|
@@ -73,7 +73,7 @@ var isWsl = () => {
|
|
|
73
73
|
}
|
|
74
74
|
return false;
|
|
75
75
|
};
|
|
76
|
-
var is_wsl_default =
|
|
76
|
+
var is_wsl_default = process5.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
77
77
|
|
|
78
78
|
// ../../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
|
|
79
79
|
var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
@@ -111,7 +111,7 @@ var powerShellPath = async () => {
|
|
|
111
111
|
if (is_wsl_default) {
|
|
112
112
|
return powerShellPathFromWsl();
|
|
113
113
|
}
|
|
114
|
-
return `${
|
|
114
|
+
return `${process5.env.SYSTEMROOT || process5.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
// ../../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
@@ -133,7 +133,7 @@ function defineLazyProperty(object, propertyName, valueGetter) {
|
|
|
133
133
|
}
|
|
134
134
|
var execFileAsync = promisify(execFile);
|
|
135
135
|
async function defaultBrowserId() {
|
|
136
|
-
if (
|
|
136
|
+
if (process5.platform !== "darwin") {
|
|
137
137
|
throw new Error("macOS only");
|
|
138
138
|
}
|
|
139
139
|
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
@@ -146,7 +146,7 @@ async function defaultBrowserId() {
|
|
|
146
146
|
}
|
|
147
147
|
var execFileAsync2 = promisify(execFile);
|
|
148
148
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
149
|
-
if (
|
|
149
|
+
if (process5.platform !== "darwin") {
|
|
150
150
|
throw new Error("macOS only");
|
|
151
151
|
}
|
|
152
152
|
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
@@ -209,18 +209,18 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
|
209
209
|
var execFileAsync4 = promisify(execFile);
|
|
210
210
|
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
211
211
|
async function defaultBrowser2() {
|
|
212
|
-
if (
|
|
212
|
+
if (process5.platform === "darwin") {
|
|
213
213
|
const id = await defaultBrowserId();
|
|
214
214
|
const name = await bundleName(id);
|
|
215
215
|
return { name, id };
|
|
216
216
|
}
|
|
217
|
-
if (
|
|
217
|
+
if (process5.platform === "linux") {
|
|
218
218
|
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
219
219
|
const id = stdout.trim();
|
|
220
220
|
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
221
221
|
return { name, id };
|
|
222
222
|
}
|
|
223
|
-
if (
|
|
223
|
+
if (process5.platform === "win32") {
|
|
224
224
|
return defaultBrowser();
|
|
225
225
|
}
|
|
226
226
|
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
@@ -230,7 +230,7 @@ async function defaultBrowser2() {
|
|
|
230
230
|
var execFile5 = promisify(childProcess.execFile);
|
|
231
231
|
var __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
|
|
232
232
|
var localXdgOpenPath = path.join(__dirname$1, "xdg-open");
|
|
233
|
-
var { platform, arch } =
|
|
233
|
+
var { platform, arch } = process5;
|
|
234
234
|
async function getWindowsDefaultBrowserFromWsl() {
|
|
235
235
|
const powershellPath = await powerShellPath();
|
|
236
236
|
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
@@ -383,7 +383,7 @@ var baseOpen = async (options) => {
|
|
|
383
383
|
exeLocalXdgOpen = true;
|
|
384
384
|
} catch {
|
|
385
385
|
}
|
|
386
|
-
const useSystemXdgOpen =
|
|
386
|
+
const useSystemXdgOpen = process5.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
387
387
|
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
388
388
|
}
|
|
389
389
|
if (appArguments.length > 0) {
|
|
@@ -483,45 +483,6 @@ defineLazyProperty(apps, "browser", () => "browser");
|
|
|
483
483
|
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
484
484
|
var open_default = open;
|
|
485
485
|
|
|
486
|
-
// ../../lib/utils-js/src/crypto.ts
|
|
487
|
-
var getCrypto = () => {
|
|
488
|
-
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
489
|
-
return globalThis.crypto;
|
|
490
|
-
}
|
|
491
|
-
throw new Error("Web Crypto API not available \u2014 requires Node.js 22+ or a modern browser");
|
|
492
|
-
};
|
|
493
|
-
var getSubtle = () => {
|
|
494
|
-
const crypto = getCrypto();
|
|
495
|
-
if (crypto.subtle) {
|
|
496
|
-
return crypto.subtle;
|
|
497
|
-
}
|
|
498
|
-
throw new Error("SubtleCrypto not available \u2014 requires a secure context (HTTPS) or Node.js 22+");
|
|
499
|
-
};
|
|
500
|
-
var encodeBytes = (bytes, encoding) => {
|
|
501
|
-
if (encoding === "hex") {
|
|
502
|
-
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
503
|
-
}
|
|
504
|
-
const base64 = btoa(String.fromCharCode(...bytes));
|
|
505
|
-
if (encoding === "base64url") {
|
|
506
|
-
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
507
|
-
}
|
|
508
|
-
return base64;
|
|
509
|
-
};
|
|
510
|
-
var getRandomBytes = (length, encoding = "base64") => {
|
|
511
|
-
const bytes = new Uint8Array(length);
|
|
512
|
-
getCrypto().getRandomValues(bytes);
|
|
513
|
-
return encodeBytes(bytes, encoding);
|
|
514
|
-
};
|
|
515
|
-
var getDigest = async (input, encoding = "hex") => {
|
|
516
|
-
const digest = await getSubtle().digest(
|
|
517
|
-
"SHA-256",
|
|
518
|
-
new TextEncoder().encode(input)
|
|
519
|
-
);
|
|
520
|
-
return encodeBytes(new Uint8Array(digest), encoding);
|
|
521
|
-
};
|
|
522
|
-
var getNonce = () => getRandomBytes(16, "base64url");
|
|
523
|
-
var getVerifier = () => getRandomBytes(32, "base64url");
|
|
524
|
-
|
|
525
486
|
// src/auth.ts
|
|
526
487
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
527
488
|
var generatePKCE = async () => {
|
|
@@ -541,7 +502,7 @@ var registerClient = async (registrationEndpoint) => {
|
|
|
541
502
|
method: "POST",
|
|
542
503
|
headers: { "content-type": "application/json" },
|
|
543
504
|
body: JSON.stringify({
|
|
544
|
-
client_name:
|
|
505
|
+
client_name: STANDALONE_CLIENT.MCP,
|
|
545
506
|
redirect_uris: ["http://127.0.0.1/callback"]
|
|
546
507
|
})
|
|
547
508
|
});
|
|
@@ -578,7 +539,7 @@ var decodeJwtPayload = (token) => {
|
|
|
578
539
|
};
|
|
579
540
|
var performOAuthFlow = async (discoveryUrl) => {
|
|
580
541
|
const discovery = await fetchDiscovery(discoveryUrl);
|
|
581
|
-
let clientId =
|
|
542
|
+
let clientId = await deriveClientId(STANDALONE_CLIENT.MCP);
|
|
582
543
|
if (discovery.registration_endpoint) {
|
|
583
544
|
clientId = await registerClient(discovery.registration_endpoint);
|
|
584
545
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { writeAuthState, STANDALONE_CLIENT_AUTH_FILE } from './chunk-
|
|
1
|
+
import { deriveClientId, STANDALONE_CLIENT, getNonce, writeAuthState, STANDALONE_CLIENT_AUTH_FILE, getVerifier, getDigest } from './chunk-HLVEV5OH.js';
|
|
2
2
|
import { createServer } from 'http';
|
|
3
|
-
import
|
|
3
|
+
import process5 from 'process';
|
|
4
4
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
@@ -52,7 +52,7 @@ function isInsideContainer() {
|
|
|
52
52
|
|
|
53
53
|
// ../../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
54
54
|
var isWsl = () => {
|
|
55
|
-
if (
|
|
55
|
+
if (process5.platform !== "linux") {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
58
|
if (os.release().toLowerCase().includes("microsoft")) {
|
|
@@ -72,7 +72,7 @@ var isWsl = () => {
|
|
|
72
72
|
}
|
|
73
73
|
return false;
|
|
74
74
|
};
|
|
75
|
-
var is_wsl_default =
|
|
75
|
+
var is_wsl_default = process5.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
76
76
|
|
|
77
77
|
// ../../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
|
|
78
78
|
var wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
@@ -110,7 +110,7 @@ var powerShellPath = async () => {
|
|
|
110
110
|
if (is_wsl_default) {
|
|
111
111
|
return powerShellPathFromWsl();
|
|
112
112
|
}
|
|
113
|
-
return `${
|
|
113
|
+
return `${process5.env.SYSTEMROOT || process5.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
// ../../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
@@ -132,7 +132,7 @@ function defineLazyProperty(object, propertyName, valueGetter) {
|
|
|
132
132
|
}
|
|
133
133
|
var execFileAsync = promisify(execFile);
|
|
134
134
|
async function defaultBrowserId() {
|
|
135
|
-
if (
|
|
135
|
+
if (process5.platform !== "darwin") {
|
|
136
136
|
throw new Error("macOS only");
|
|
137
137
|
}
|
|
138
138
|
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
@@ -145,7 +145,7 @@ async function defaultBrowserId() {
|
|
|
145
145
|
}
|
|
146
146
|
var execFileAsync2 = promisify(execFile);
|
|
147
147
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
148
|
-
if (
|
|
148
|
+
if (process5.platform !== "darwin") {
|
|
149
149
|
throw new Error("macOS only");
|
|
150
150
|
}
|
|
151
151
|
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
@@ -208,18 +208,18 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
|
208
208
|
var execFileAsync4 = promisify(execFile);
|
|
209
209
|
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
210
210
|
async function defaultBrowser2() {
|
|
211
|
-
if (
|
|
211
|
+
if (process5.platform === "darwin") {
|
|
212
212
|
const id = await defaultBrowserId();
|
|
213
213
|
const name = await bundleName(id);
|
|
214
214
|
return { name, id };
|
|
215
215
|
}
|
|
216
|
-
if (
|
|
216
|
+
if (process5.platform === "linux") {
|
|
217
217
|
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
218
218
|
const id = stdout.trim();
|
|
219
219
|
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
220
220
|
return { name, id };
|
|
221
221
|
}
|
|
222
|
-
if (
|
|
222
|
+
if (process5.platform === "win32") {
|
|
223
223
|
return defaultBrowser();
|
|
224
224
|
}
|
|
225
225
|
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
@@ -229,7 +229,7 @@ async function defaultBrowser2() {
|
|
|
229
229
|
var execFile5 = promisify(childProcess.execFile);
|
|
230
230
|
var __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
|
|
231
231
|
var localXdgOpenPath = path.join(__dirname$1, "xdg-open");
|
|
232
|
-
var { platform, arch } =
|
|
232
|
+
var { platform, arch } = process5;
|
|
233
233
|
async function getWindowsDefaultBrowserFromWsl() {
|
|
234
234
|
const powershellPath = await powerShellPath();
|
|
235
235
|
const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
@@ -382,7 +382,7 @@ var baseOpen = async (options) => {
|
|
|
382
382
|
exeLocalXdgOpen = true;
|
|
383
383
|
} catch {
|
|
384
384
|
}
|
|
385
|
-
const useSystemXdgOpen =
|
|
385
|
+
const useSystemXdgOpen = process5.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
386
386
|
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
387
387
|
}
|
|
388
388
|
if (appArguments.length > 0) {
|
|
@@ -482,45 +482,6 @@ defineLazyProperty(apps, "browser", () => "browser");
|
|
|
482
482
|
defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
|
|
483
483
|
var open_default = open;
|
|
484
484
|
|
|
485
|
-
// ../../lib/utils-js/src/crypto.ts
|
|
486
|
-
var getCrypto = () => {
|
|
487
|
-
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
488
|
-
return globalThis.crypto;
|
|
489
|
-
}
|
|
490
|
-
throw new Error("Web Crypto API not available \u2014 requires Node.js 22+ or a modern browser");
|
|
491
|
-
};
|
|
492
|
-
var getSubtle = () => {
|
|
493
|
-
const crypto = getCrypto();
|
|
494
|
-
if (crypto.subtle) {
|
|
495
|
-
return crypto.subtle;
|
|
496
|
-
}
|
|
497
|
-
throw new Error("SubtleCrypto not available \u2014 requires a secure context (HTTPS) or Node.js 22+");
|
|
498
|
-
};
|
|
499
|
-
var encodeBytes = (bytes, encoding) => {
|
|
500
|
-
if (encoding === "hex") {
|
|
501
|
-
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
502
|
-
}
|
|
503
|
-
const base64 = btoa(String.fromCharCode(...bytes));
|
|
504
|
-
if (encoding === "base64url") {
|
|
505
|
-
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
506
|
-
}
|
|
507
|
-
return base64;
|
|
508
|
-
};
|
|
509
|
-
var getRandomBytes = (length, encoding = "base64") => {
|
|
510
|
-
const bytes = new Uint8Array(length);
|
|
511
|
-
getCrypto().getRandomValues(bytes);
|
|
512
|
-
return encodeBytes(bytes, encoding);
|
|
513
|
-
};
|
|
514
|
-
var getDigest = async (input, encoding = "hex") => {
|
|
515
|
-
const digest = await getSubtle().digest(
|
|
516
|
-
"SHA-256",
|
|
517
|
-
new TextEncoder().encode(input)
|
|
518
|
-
);
|
|
519
|
-
return encodeBytes(new Uint8Array(digest), encoding);
|
|
520
|
-
};
|
|
521
|
-
var getNonce = () => getRandomBytes(16, "base64url");
|
|
522
|
-
var getVerifier = () => getRandomBytes(32, "base64url");
|
|
523
|
-
|
|
524
485
|
// src/auth.ts
|
|
525
486
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
526
487
|
var generatePKCE = async () => {
|
|
@@ -540,7 +501,7 @@ var registerClient = async (registrationEndpoint) => {
|
|
|
540
501
|
method: "POST",
|
|
541
502
|
headers: { "content-type": "application/json" },
|
|
542
503
|
body: JSON.stringify({
|
|
543
|
-
client_name:
|
|
504
|
+
client_name: STANDALONE_CLIENT.MCP,
|
|
544
505
|
redirect_uris: ["http://127.0.0.1/callback"]
|
|
545
506
|
})
|
|
546
507
|
});
|
|
@@ -577,7 +538,7 @@ var decodeJwtPayload = (token) => {
|
|
|
577
538
|
};
|
|
578
539
|
var performOAuthFlow = async (discoveryUrl) => {
|
|
579
540
|
const discovery = await fetchDiscovery(discoveryUrl);
|
|
580
|
-
let clientId =
|
|
541
|
+
let clientId = await deriveClientId(STANDALONE_CLIENT.MCP);
|
|
581
542
|
if (discovery.registration_endpoint) {
|
|
582
543
|
clientId = await registerClient(discovery.registration_endpoint);
|
|
583
544
|
}
|
|
@@ -3,9 +3,48 @@ import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
|
|
6
|
+
// ../../lib/utils-js/src/crypto.ts
|
|
7
|
+
var getCrypto = () => {
|
|
8
|
+
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
9
|
+
return globalThis.crypto;
|
|
10
|
+
}
|
|
11
|
+
throw new Error("Web Crypto API not available \u2014 requires Node.js 22+ or a modern browser");
|
|
12
|
+
};
|
|
13
|
+
var getSubtle = () => {
|
|
14
|
+
const crypto = getCrypto();
|
|
15
|
+
if (crypto.subtle) {
|
|
16
|
+
return crypto.subtle;
|
|
17
|
+
}
|
|
18
|
+
throw new Error("SubtleCrypto not available \u2014 requires a secure context (HTTPS) or Node.js 22+");
|
|
19
|
+
};
|
|
20
|
+
var encodeBytes = (bytes, encoding) => {
|
|
21
|
+
if (encoding === "hex") {
|
|
22
|
+
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
23
|
+
}
|
|
24
|
+
const base64 = btoa(String.fromCharCode(...bytes));
|
|
25
|
+
if (encoding === "base64url") {
|
|
26
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
27
|
+
}
|
|
28
|
+
return base64;
|
|
29
|
+
};
|
|
30
|
+
var getRandomBytes = (length, encoding = "base64") => {
|
|
31
|
+
const bytes = new Uint8Array(length);
|
|
32
|
+
getCrypto().getRandomValues(bytes);
|
|
33
|
+
return encodeBytes(bytes, encoding);
|
|
34
|
+
};
|
|
35
|
+
var getDigest = async (input, encoding = "hex") => {
|
|
36
|
+
const digest = await getSubtle().digest(
|
|
37
|
+
"SHA-256",
|
|
38
|
+
new TextEncoder().encode(input)
|
|
39
|
+
);
|
|
40
|
+
return encodeBytes(new Uint8Array(digest), encoding);
|
|
41
|
+
};
|
|
42
|
+
var getNonce = () => getRandomBytes(16, "base64url");
|
|
43
|
+
var getVerifier = () => getRandomBytes(32, "base64url");
|
|
44
|
+
|
|
6
45
|
// ../../lib/utils-auth/src/constants.ts
|
|
7
46
|
var STANDALONE_CLIENT_DATA = {
|
|
8
|
-
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "auth.json" },
|
|
47
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
9
48
|
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
10
49
|
};
|
|
11
50
|
var STANDALONE_CLIENT = Object.fromEntries(
|
|
@@ -34,6 +73,7 @@ var EDITOR_ROLES = [
|
|
|
34
73
|
];
|
|
35
74
|
|
|
36
75
|
// ../../lib/utils-auth/src/index.ts
|
|
76
|
+
var deriveClientId = async (clientName) => (await getDigest(clientName)).slice(0, 32);
|
|
37
77
|
var AUTH_DIR = join(homedir(), ".stackable");
|
|
38
78
|
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
39
79
|
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
@@ -76,4 +116,4 @@ var getToken = async (filename) => {
|
|
|
76
116
|
return state.token;
|
|
77
117
|
};
|
|
78
118
|
|
|
79
|
-
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, getToken, writeAuthState };
|
|
119
|
+
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, deriveClientId, getDigest, getNonce, getToken, getVerifier, writeAuthState };
|
|
@@ -2,9 +2,48 @@ import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
|
|
5
|
+
// ../../lib/utils-js/src/crypto.ts
|
|
6
|
+
var getCrypto = () => {
|
|
7
|
+
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
8
|
+
return globalThis.crypto;
|
|
9
|
+
}
|
|
10
|
+
throw new Error("Web Crypto API not available \u2014 requires Node.js 22+ or a modern browser");
|
|
11
|
+
};
|
|
12
|
+
var getSubtle = () => {
|
|
13
|
+
const crypto = getCrypto();
|
|
14
|
+
if (crypto.subtle) {
|
|
15
|
+
return crypto.subtle;
|
|
16
|
+
}
|
|
17
|
+
throw new Error("SubtleCrypto not available \u2014 requires a secure context (HTTPS) or Node.js 22+");
|
|
18
|
+
};
|
|
19
|
+
var encodeBytes = (bytes, encoding) => {
|
|
20
|
+
if (encoding === "hex") {
|
|
21
|
+
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
22
|
+
}
|
|
23
|
+
const base64 = btoa(String.fromCharCode(...bytes));
|
|
24
|
+
if (encoding === "base64url") {
|
|
25
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
26
|
+
}
|
|
27
|
+
return base64;
|
|
28
|
+
};
|
|
29
|
+
var getRandomBytes = (length, encoding = "base64") => {
|
|
30
|
+
const bytes = new Uint8Array(length);
|
|
31
|
+
getCrypto().getRandomValues(bytes);
|
|
32
|
+
return encodeBytes(bytes, encoding);
|
|
33
|
+
};
|
|
34
|
+
var getDigest = async (input, encoding = "hex") => {
|
|
35
|
+
const digest = await getSubtle().digest(
|
|
36
|
+
"SHA-256",
|
|
37
|
+
new TextEncoder().encode(input)
|
|
38
|
+
);
|
|
39
|
+
return encodeBytes(new Uint8Array(digest), encoding);
|
|
40
|
+
};
|
|
41
|
+
var getNonce = () => getRandomBytes(16, "base64url");
|
|
42
|
+
var getVerifier = () => getRandomBytes(32, "base64url");
|
|
43
|
+
|
|
5
44
|
// ../../lib/utils-auth/src/constants.ts
|
|
6
45
|
var STANDALONE_CLIENT_DATA = {
|
|
7
|
-
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "auth.json" },
|
|
46
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
8
47
|
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
9
48
|
};
|
|
10
49
|
var STANDALONE_CLIENT = Object.fromEntries(
|
|
@@ -33,6 +72,7 @@ var EDITOR_ROLES = [
|
|
|
33
72
|
];
|
|
34
73
|
|
|
35
74
|
// ../../lib/utils-auth/src/index.ts
|
|
75
|
+
var deriveClientId = async (clientName) => (await getDigest(clientName)).slice(0, 32);
|
|
36
76
|
var AUTH_DIR = join(homedir(), ".stackable");
|
|
37
77
|
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.CLI);
|
|
38
78
|
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
@@ -75,4 +115,4 @@ var getToken = async (filename) => {
|
|
|
75
115
|
return state.token;
|
|
76
116
|
};
|
|
77
117
|
|
|
78
|
-
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, getToken, writeAuthState };
|
|
118
|
+
export { MCP_AUTH_FILE, STANDALONE_CLIENT, STANDALONE_CLIENT_AUTH_FILE, deriveClientId, getDigest, getNonce, getToken, getVerifier, writeAuthState };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-
|
|
2
|
+
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-BDOVEKRM.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
5
5
|
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
@@ -43,13 +43,15 @@ export const appStore = createStore<AppState>({
|
|
|
43
43
|
{
|
|
44
44
|
path: "surfaces/Content.tsx",
|
|
45
45
|
title: "Content Surface with Loading State",
|
|
46
|
-
code: `import { ui, useStore, useContextData,
|
|
46
|
+
code: `import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
|
|
47
47
|
import { appStore } from '../store'
|
|
48
48
|
|
|
49
49
|
export function Content() {
|
|
50
50
|
const viewState = useStore(appStore, (s) => s.viewState)
|
|
51
51
|
const { loading } = useContextData()
|
|
52
|
-
|
|
52
|
+
// Non-secret settings from settingsSchema (add settingsSchema to manifest.json to use). Ex:
|
|
53
|
+
// const settings = useSettings()
|
|
54
|
+
// const apiEndpoint = settings.apiEndpoint as string
|
|
53
55
|
|
|
54
56
|
if (loading) {
|
|
55
57
|
return (
|
|
@@ -197,13 +199,15 @@ export const appStore = createStore<AppState>({
|
|
|
197
199
|
{
|
|
198
200
|
path: "surfaces/Content.tsx",
|
|
199
201
|
title: "Current Content Surface",
|
|
200
|
-
code: `import { ui, useStore, useContextData,
|
|
202
|
+
code: `import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
|
|
201
203
|
import { appStore } from '../store'
|
|
202
204
|
|
|
203
205
|
export function Content() {
|
|
204
206
|
const viewState = useStore(appStore, (s) => s.viewState)
|
|
205
207
|
const { loading } = useContextData()
|
|
206
|
-
|
|
208
|
+
// Non-secret settings from settingsSchema (add settingsSchema to manifest.json to use). Ex:
|
|
209
|
+
// const settings = useSettings()
|
|
210
|
+
// const apiEndpoint = settings.apiEndpoint as string
|
|
207
211
|
|
|
208
212
|
if (loading) {
|
|
209
213
|
return (
|
|
@@ -3849,7 +3853,7 @@ var createMcpServer = (options = {}) => {
|
|
|
3849
3853
|
return await getToken(STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
3850
3854
|
} catch {
|
|
3851
3855
|
}
|
|
3852
|
-
const { performOAuthFlow } = await import('./auth-
|
|
3856
|
+
const { performOAuthFlow } = await import('./auth-5Z7FU2KG.js');
|
|
3853
3857
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3854
3858
|
return performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
|
|
3855
3859
|
};
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-
|
|
1
|
+
import { STANDALONE_CLIENT, MCP_AUTH_FILE, getToken, STANDALONE_CLIENT_AUTH_FILE } from './chunk-HLVEV5OH.js';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
3
|
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -41,13 +41,15 @@ export const appStore = createStore<AppState>({
|
|
|
41
41
|
{
|
|
42
42
|
path: "surfaces/Content.tsx",
|
|
43
43
|
title: "Content Surface with Loading State",
|
|
44
|
-
code: `import { ui, useStore, useContextData,
|
|
44
|
+
code: `import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
|
|
45
45
|
import { appStore } from '../store'
|
|
46
46
|
|
|
47
47
|
export function Content() {
|
|
48
48
|
const viewState = useStore(appStore, (s) => s.viewState)
|
|
49
49
|
const { loading } = useContextData()
|
|
50
|
-
|
|
50
|
+
// Non-secret settings from settingsSchema (add settingsSchema to manifest.json to use). Ex:
|
|
51
|
+
// const settings = useSettings()
|
|
52
|
+
// const apiEndpoint = settings.apiEndpoint as string
|
|
51
53
|
|
|
52
54
|
if (loading) {
|
|
53
55
|
return (
|
|
@@ -195,13 +197,15 @@ export const appStore = createStore<AppState>({
|
|
|
195
197
|
{
|
|
196
198
|
path: "surfaces/Content.tsx",
|
|
197
199
|
title: "Current Content Surface",
|
|
198
|
-
code: `import { ui, useStore, useContextData,
|
|
200
|
+
code: `import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
|
|
199
201
|
import { appStore } from '../store'
|
|
200
202
|
|
|
201
203
|
export function Content() {
|
|
202
204
|
const viewState = useStore(appStore, (s) => s.viewState)
|
|
203
205
|
const { loading } = useContextData()
|
|
204
|
-
|
|
206
|
+
// Non-secret settings from settingsSchema (add settingsSchema to manifest.json to use). Ex:
|
|
207
|
+
// const settings = useSettings()
|
|
208
|
+
// const apiEndpoint = settings.apiEndpoint as string
|
|
205
209
|
|
|
206
210
|
if (loading) {
|
|
207
211
|
return (
|
|
@@ -3847,7 +3851,7 @@ var createMcpServer = (options = {}) => {
|
|
|
3847
3851
|
return await getToken(STANDALONE_CLIENT_AUTH_FILE.MCP);
|
|
3848
3852
|
} catch {
|
|
3849
3853
|
}
|
|
3850
|
-
const { performOAuthFlow } = await import('./auth-
|
|
3854
|
+
const { performOAuthFlow } = await import('./auth-7BRIJUR5.js');
|
|
3851
3855
|
const MCP_API_BASE_URL = process.env.MCP_API_BASE_URL ?? DEFAULT_MCP_API_BASE_URL;
|
|
3852
3856
|
return performOAuthFlow(`${MCP_API_BASE_URL}/.well-known/oauth-authorization-server`);
|
|
3853
3857
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackable-labs/mcp-app-extension",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mcp-app-extension": "./dist/index.js"
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@modelcontextprotocol/sdk": "1.x",
|
|
25
25
|
"@stackable-labs/sdk-extension-contracts": "latest",
|
|
26
|
-
"oauth4webapi": "3.x",
|
|
27
26
|
"open": "10.x",
|
|
28
27
|
"zod": "3.x"
|
|
29
28
|
},
|