@stackable-labs/mcp-app-extension 2.3.0 → 2.4.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/index.js +83 -80
- package/dist/server.js +70 -69
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
-
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, TEMPLATE_FLAVORS, MESSAGING_ACTION_EXAMPLES, PERMISSIONS, CAPABILITY_PERMISSION_MAP, HOOK_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_CATEGORIES, UI_TAG_ATTRIBUTES, tagToComponentName, EVENT_HOOK_PERMISSION_MAP, MESSAGING_SEND_EXAMPLES } from '@stackable-labs/sdk-extension-contracts';
|
|
5
|
-
import path, { join } from 'path';
|
|
6
4
|
import fs4, { readFile, mkdir, writeFile, constants } from 'fs/promises';
|
|
5
|
+
import path, { join } from 'path';
|
|
7
6
|
import os, { homedir } from 'os';
|
|
8
|
-
import {
|
|
7
|
+
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, TEMPLATE_FLAVORS, MESSAGING_ACTION_EXAMPLES, PERMISSIONS, CAPABILITY_PERMISSION_MAP, HOOK_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_CATEGORIES, UI_TAG_ATTRIBUTES, tagToComponentName, EVENT_HOOK_PERMISSION_MAP, MESSAGING_SEND_EXAMPLES } from '@stackable-labs/sdk-extension-contracts';
|
|
9
8
|
import { z } from 'zod';
|
|
9
|
+
import { validatePatternFormat } from '@stackable-labs/lib-contracts';
|
|
10
10
|
import { createServer } from 'http';
|
|
11
11
|
import process6 from 'process';
|
|
12
12
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
@@ -15,6 +15,69 @@ import { promisify } from 'util';
|
|
|
15
15
|
import childProcess, { execFile } from 'child_process';
|
|
16
16
|
import fs3 from 'fs';
|
|
17
17
|
|
|
18
|
+
// ../../lib/utils-auth/src/constants.ts
|
|
19
|
+
var STANDALONE_CLIENT_DATA = {
|
|
20
|
+
STACKABLE_LABS: {
|
|
21
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
22
|
+
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
23
|
+
},
|
|
24
|
+
STACKABLE_OPS: {
|
|
25
|
+
MCP: { name: "@stackable-ops/mcp", authFile: "mcp-ops-auth.json" }
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var projectField = (field) => Object.fromEntries(
|
|
29
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([org, roles]) => [
|
|
30
|
+
org,
|
|
31
|
+
Object.fromEntries(Object.entries(roles).map(([role, entry]) => [role, entry[field]]))
|
|
32
|
+
])
|
|
33
|
+
);
|
|
34
|
+
var STANDALONE_CLIENT = projectField("name");
|
|
35
|
+
var STANDALONE_CLIENT_AUTH_FILE = projectField("authFile");
|
|
36
|
+
Object.values(STANDALONE_CLIENT_DATA).flatMap((roles) => Object.values(roles).map((entry) => entry.name));
|
|
37
|
+
|
|
38
|
+
// ../../lib/utils-auth/src/cli/shared.ts
|
|
39
|
+
var AUTH_DIR = join(homedir(), ".stackable");
|
|
40
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
41
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP);
|
|
42
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
43
|
+
var readAuthState = async (filename) => {
|
|
44
|
+
try {
|
|
45
|
+
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
46
|
+
return JSON.parse(content);
|
|
47
|
+
} catch {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var writeAuthState = async (state, filename) => {
|
|
52
|
+
await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
|
|
53
|
+
await writeFile(resolveAuthFile(filename), JSON.stringify(state, null, 2), { mode: 384 });
|
|
54
|
+
};
|
|
55
|
+
var decodeJwtPayload = (token) => {
|
|
56
|
+
try {
|
|
57
|
+
const [, payload] = token.split(".");
|
|
58
|
+
if (!payload) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
62
|
+
return JSON.parse(json);
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var getToken = async (filename) => {
|
|
68
|
+
const state = await readAuthState(filename);
|
|
69
|
+
if (!state) {
|
|
70
|
+
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
71
|
+
}
|
|
72
|
+
const payload = decodeJwtPayload(state.token);
|
|
73
|
+
if (payload?.exp && typeof payload.exp === "number") {
|
|
74
|
+
if (Date.now() >= payload.exp * 1e3) {
|
|
75
|
+
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return state.token;
|
|
79
|
+
};
|
|
80
|
+
|
|
18
81
|
// ../../sdk/extension/ai-docs/src/generated/template-content.ts
|
|
19
82
|
var PATTERN_SECTIONS = [
|
|
20
83
|
{
|
|
@@ -5637,6 +5700,15 @@ pair(EXAMPLE_SNIPPETS, EXAMPLE_SNIPPETS2);
|
|
|
5637
5700
|
pair(CAPABILITY_SNIPPETS, CAPABILITY_SNIPPETS2);
|
|
5638
5701
|
pair(EVENT_SNIPPETS, EVENT_SNIPPETS2);
|
|
5639
5702
|
|
|
5703
|
+
// ../../lib/utils-mcp/src/index.ts
|
|
5704
|
+
var textContent = (text) => ({
|
|
5705
|
+
content: [{ type: "text", text }]
|
|
5706
|
+
});
|
|
5707
|
+
var errorContent = (text) => ({
|
|
5708
|
+
isError: true,
|
|
5709
|
+
content: [{ type: "text", text }]
|
|
5710
|
+
});
|
|
5711
|
+
|
|
5640
5712
|
// ../../lib/utils-js/src/crypto.ts
|
|
5641
5713
|
var getCrypto = () => {
|
|
5642
5714
|
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
@@ -5676,79 +5748,9 @@ var getDigest = async (input, encoding = "hex") => {
|
|
|
5676
5748
|
var getNonce = () => getRandomBytes(16, "base64url");
|
|
5677
5749
|
var getVerifier = () => getRandomBytes(32, "base64url");
|
|
5678
5750
|
|
|
5679
|
-
// ../../lib/utils-auth/src/constants.ts
|
|
5680
|
-
var STANDALONE_CLIENT_DATA = {
|
|
5681
|
-
STACKABLE_LABS: {
|
|
5682
|
-
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
5683
|
-
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
5684
|
-
},
|
|
5685
|
-
STACKABLE_OPS: {
|
|
5686
|
-
MCP: { name: "@stackable-ops/mcp", authFile: "mcp-ops-auth.json" }
|
|
5687
|
-
}
|
|
5688
|
-
};
|
|
5689
|
-
var projectField = (field) => Object.fromEntries(
|
|
5690
|
-
Object.entries(STANDALONE_CLIENT_DATA).map(([org, roles]) => [
|
|
5691
|
-
org,
|
|
5692
|
-
Object.fromEntries(Object.entries(roles).map(([role, entry]) => [role, entry[field]]))
|
|
5693
|
-
])
|
|
5694
|
-
);
|
|
5695
|
-
var STANDALONE_CLIENT = projectField("name");
|
|
5696
|
-
var STANDALONE_CLIENT_AUTH_FILE = projectField("authFile");
|
|
5697
|
-
Object.values(STANDALONE_CLIENT_DATA).flatMap((roles) => Object.values(roles).map((entry) => entry.name));
|
|
5698
|
-
var AUTH_DIR = join(homedir(), ".stackable");
|
|
5699
|
-
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
5700
|
-
var readAuthState = async (filename) => {
|
|
5701
|
-
try {
|
|
5702
|
-
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
5703
|
-
return JSON.parse(content);
|
|
5704
|
-
} catch {
|
|
5705
|
-
return null;
|
|
5706
|
-
}
|
|
5707
|
-
};
|
|
5708
|
-
var writeAuthState = async (state, filename) => {
|
|
5709
|
-
await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
|
|
5710
|
-
await writeFile(resolveAuthFile(filename), JSON.stringify(state, null, 2), { mode: 384 });
|
|
5711
|
-
};
|
|
5712
|
-
var decodeJwtPayload = (token) => {
|
|
5713
|
-
try {
|
|
5714
|
-
const [, payload] = token.split(".");
|
|
5715
|
-
if (!payload) {
|
|
5716
|
-
return null;
|
|
5717
|
-
}
|
|
5718
|
-
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
5719
|
-
return JSON.parse(json);
|
|
5720
|
-
} catch {
|
|
5721
|
-
return null;
|
|
5722
|
-
}
|
|
5723
|
-
};
|
|
5724
|
-
var getToken = async (filename) => {
|
|
5725
|
-
const state = await readAuthState(filename);
|
|
5726
|
-
if (!state) {
|
|
5727
|
-
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
5728
|
-
}
|
|
5729
|
-
const payload = decodeJwtPayload(state.token);
|
|
5730
|
-
if (payload?.exp && typeof payload.exp === "number") {
|
|
5731
|
-
if (Date.now() >= payload.exp * 1e3) {
|
|
5732
|
-
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
5733
|
-
}
|
|
5734
|
-
}
|
|
5735
|
-
return state.token;
|
|
5736
|
-
};
|
|
5737
|
-
|
|
5738
5751
|
// ../../lib/utils-auth/src/index.ts
|
|
5739
5752
|
var deriveDcrClientId = async (clientName) => (await getDigest(clientName)).slice(0, 32);
|
|
5740
5753
|
var deriveClientId = async (clientName) => deriveDcrClientId(clientName);
|
|
5741
|
-
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
5742
|
-
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP);
|
|
5743
|
-
|
|
5744
|
-
// ../../lib/utils-mcp/src/index.ts
|
|
5745
|
-
var textContent = (text) => ({
|
|
5746
|
-
content: [{ type: "text", text }]
|
|
5747
|
-
});
|
|
5748
|
-
var errorContent = (text) => ({
|
|
5749
|
-
isError: true,
|
|
5750
|
-
content: [{ type: "text", text }]
|
|
5751
|
-
});
|
|
5752
5754
|
|
|
5753
5755
|
// package.json
|
|
5754
5756
|
var package_default = {
|
|
@@ -5904,11 +5906,12 @@ var toolRegistrars = [
|
|
|
5904
5906
|
];
|
|
5905
5907
|
|
|
5906
5908
|
// src/server.ts
|
|
5907
|
-
var
|
|
5908
|
-
var
|
|
5909
|
+
var MCP_LABS_AUTH_FILE2 = STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP;
|
|
5910
|
+
var MCP_LABS_CLIENT_NAME = STANDALONE_CLIENT.STACKABLE_LABS.MCP;
|
|
5909
5911
|
var DEFAULT_MCP_LABS_API_BASE_URL2 = "https://mcp.stackablelabs.io";
|
|
5910
|
-
var
|
|
5911
|
-
var
|
|
5912
|
+
var DEFAULT_ADMIN_LABS_API_URL = "https://api-x.stackablelabs.io/admin";
|
|
5913
|
+
var adminApiBaseUrl = () => process.env.ADMIN_LABS_API_BASE_URL ?? DEFAULT_ADMIN_LABS_API_URL;
|
|
5914
|
+
var mcpApiBaseUrl = () => process.env.MCP_LABS_API_BASE_URL ?? DEFAULT_MCP_LABS_API_BASE_URL2;
|
|
5912
5915
|
var createMcpServer = (options = {}) => {
|
|
5913
5916
|
const server2 = new McpServer({
|
|
5914
5917
|
name: "stackable-extension-dev",
|
|
@@ -5919,7 +5922,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5919
5922
|
return options.authContext.token;
|
|
5920
5923
|
}
|
|
5921
5924
|
try {
|
|
5922
|
-
return await getToken(
|
|
5925
|
+
return await getToken(MCP_LABS_AUTH_FILE2);
|
|
5923
5926
|
} catch {
|
|
5924
5927
|
}
|
|
5925
5928
|
if (!options.performOAuthFlow) {
|
|
@@ -5932,7 +5935,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5932
5935
|
const authHeaders = (token) => ({
|
|
5933
5936
|
authorization: `Bearer ${token}`,
|
|
5934
5937
|
"content-type": "application/json",
|
|
5935
|
-
"x-client-name":
|
|
5938
|
+
"x-client-name": MCP_LABS_CLIENT_NAME
|
|
5936
5939
|
});
|
|
5937
5940
|
const callApi = async (path2) => {
|
|
5938
5941
|
const token = await getAuthToken();
|
|
@@ -5959,7 +5962,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5959
5962
|
const e = err;
|
|
5960
5963
|
if (e.message.includes("fetch")) {
|
|
5961
5964
|
return errorContent(
|
|
5962
|
-
`MCP auth flow failed: ${e.message}. Check MCP_LABS_API_BASE_URL env var (currently "${mcpApiBaseUrl()}"). To re-auth from scratch: rm ${
|
|
5965
|
+
`MCP auth flow failed: ${e.message}. Check MCP_LABS_API_BASE_URL env var (currently "${mcpApiBaseUrl()}"). To re-auth from scratch: rm ${MCP_LABS_AUTH_FILE2}`
|
|
5963
5966
|
);
|
|
5964
5967
|
}
|
|
5965
5968
|
return errorContent(e.message);
|
package/dist/server.js
CHANGED
|
@@ -1,13 +1,72 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, TEMPLATE_FLAVORS, MESSAGING_ACTION_EXAMPLES, PERMISSIONS, CAPABILITY_PERMISSION_MAP, HOOK_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_CATEGORIES, UI_TAG_ATTRIBUTES, tagToComponentName, EVENT_HOOK_PERMISSION_MAP, MESSAGING_SEND_EXAMPLES } from '@stackable-labs/sdk-extension-contracts';
|
|
3
|
-
import { join } from 'path';
|
|
4
2
|
import { readFile } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
5
4
|
import { homedir } from 'os';
|
|
6
|
-
import {
|
|
5
|
+
import { IDENTITY_EVENT, ACTIVITY_EVENT, SURFACE_TARGET, TEMPLATE_FLAVORS, MESSAGING_ACTION_EXAMPLES, PERMISSIONS, CAPABILITY_PERMISSION_MAP, HOOK_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_CATEGORIES, UI_TAG_ATTRIBUTES, tagToComponentName, EVENT_HOOK_PERMISSION_MAP, MESSAGING_SEND_EXAMPLES } from '@stackable-labs/sdk-extension-contracts';
|
|
7
6
|
import { z } from 'zod';
|
|
7
|
+
import { validatePatternFormat } from '@stackable-labs/lib-contracts';
|
|
8
8
|
|
|
9
9
|
// src/server.ts
|
|
10
10
|
|
|
11
|
+
// ../../lib/utils-auth/src/constants.ts
|
|
12
|
+
var STANDALONE_CLIENT_DATA = {
|
|
13
|
+
STACKABLE_LABS: {
|
|
14
|
+
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
15
|
+
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
16
|
+
},
|
|
17
|
+
STACKABLE_OPS: {
|
|
18
|
+
MCP: { name: "@stackable-ops/mcp", authFile: "mcp-ops-auth.json" }
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
var projectField = (field) => Object.fromEntries(
|
|
22
|
+
Object.entries(STANDALONE_CLIENT_DATA).map(([org, roles]) => [
|
|
23
|
+
org,
|
|
24
|
+
Object.fromEntries(Object.entries(roles).map(([role, entry]) => [role, entry[field]]))
|
|
25
|
+
])
|
|
26
|
+
);
|
|
27
|
+
var STANDALONE_CLIENT = projectField("name");
|
|
28
|
+
var STANDALONE_CLIENT_AUTH_FILE = projectField("authFile");
|
|
29
|
+
Object.values(STANDALONE_CLIENT_DATA).flatMap((roles) => Object.values(roles).map((entry) => entry.name));
|
|
30
|
+
|
|
31
|
+
// ../../lib/utils-auth/src/cli/shared.ts
|
|
32
|
+
var AUTH_DIR = join(homedir(), ".stackable");
|
|
33
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
34
|
+
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP);
|
|
35
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
36
|
+
var readAuthState = async (filename) => {
|
|
37
|
+
try {
|
|
38
|
+
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
39
|
+
return JSON.parse(content);
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var decodeJwtPayload = (token) => {
|
|
45
|
+
try {
|
|
46
|
+
const [, payload] = token.split(".");
|
|
47
|
+
if (!payload) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
51
|
+
return JSON.parse(json);
|
|
52
|
+
} catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var getToken = async (filename) => {
|
|
57
|
+
const state = await readAuthState(filename);
|
|
58
|
+
if (!state) {
|
|
59
|
+
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
60
|
+
}
|
|
61
|
+
const payload = decodeJwtPayload(state.token);
|
|
62
|
+
if (payload?.exp && typeof payload.exp === "number") {
|
|
63
|
+
if (Date.now() >= payload.exp * 1e3) {
|
|
64
|
+
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return state.token;
|
|
68
|
+
};
|
|
69
|
+
|
|
11
70
|
// ../../sdk/extension/ai-docs/src/generated/template-content.ts
|
|
12
71
|
var PATTERN_SECTIONS = [
|
|
13
72
|
{
|
|
@@ -5630,65 +5689,6 @@ pair(EXAMPLE_SNIPPETS, EXAMPLE_SNIPPETS2);
|
|
|
5630
5689
|
pair(CAPABILITY_SNIPPETS, CAPABILITY_SNIPPETS2);
|
|
5631
5690
|
pair(EVENT_SNIPPETS, EVENT_SNIPPETS2);
|
|
5632
5691
|
|
|
5633
|
-
// ../../lib/utils-auth/src/constants.ts
|
|
5634
|
-
var STANDALONE_CLIENT_DATA = {
|
|
5635
|
-
STACKABLE_LABS: {
|
|
5636
|
-
CLI: { name: "@stackable-labs/cli-app-extension", authFile: "cli-auth.json" },
|
|
5637
|
-
MCP: { name: "@stackable-labs/mcp-app-extension", authFile: "mcp-auth.json" }
|
|
5638
|
-
},
|
|
5639
|
-
STACKABLE_OPS: {
|
|
5640
|
-
MCP: { name: "@stackable-ops/mcp", authFile: "mcp-ops-auth.json" }
|
|
5641
|
-
}
|
|
5642
|
-
};
|
|
5643
|
-
var projectField = (field) => Object.fromEntries(
|
|
5644
|
-
Object.entries(STANDALONE_CLIENT_DATA).map(([org, roles]) => [
|
|
5645
|
-
org,
|
|
5646
|
-
Object.fromEntries(Object.entries(roles).map(([role, entry]) => [role, entry[field]]))
|
|
5647
|
-
])
|
|
5648
|
-
);
|
|
5649
|
-
var STANDALONE_CLIENT = projectField("name");
|
|
5650
|
-
var STANDALONE_CLIENT_AUTH_FILE = projectField("authFile");
|
|
5651
|
-
Object.values(STANDALONE_CLIENT_DATA).flatMap((roles) => Object.values(roles).map((entry) => entry.name));
|
|
5652
|
-
var AUTH_DIR = join(homedir(), ".stackable");
|
|
5653
|
-
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
5654
|
-
var readAuthState = async (filename) => {
|
|
5655
|
-
try {
|
|
5656
|
-
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
5657
|
-
return JSON.parse(content);
|
|
5658
|
-
} catch {
|
|
5659
|
-
return null;
|
|
5660
|
-
}
|
|
5661
|
-
};
|
|
5662
|
-
var decodeJwtPayload = (token) => {
|
|
5663
|
-
try {
|
|
5664
|
-
const [, payload] = token.split(".");
|
|
5665
|
-
if (!payload) {
|
|
5666
|
-
return null;
|
|
5667
|
-
}
|
|
5668
|
-
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
5669
|
-
return JSON.parse(json);
|
|
5670
|
-
} catch {
|
|
5671
|
-
return null;
|
|
5672
|
-
}
|
|
5673
|
-
};
|
|
5674
|
-
var getToken = async (filename) => {
|
|
5675
|
-
const state = await readAuthState(filename);
|
|
5676
|
-
if (!state) {
|
|
5677
|
-
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
5678
|
-
}
|
|
5679
|
-
const payload = decodeJwtPayload(state.token);
|
|
5680
|
-
if (payload?.exp && typeof payload.exp === "number") {
|
|
5681
|
-
if (Date.now() >= payload.exp * 1e3) {
|
|
5682
|
-
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
5683
|
-
}
|
|
5684
|
-
}
|
|
5685
|
-
return state.token;
|
|
5686
|
-
};
|
|
5687
|
-
|
|
5688
|
-
// ../../lib/utils-auth/src/index.ts
|
|
5689
|
-
join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.CLI);
|
|
5690
|
-
var MCP_AUTH_FILE = join(AUTH_DIR, STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP);
|
|
5691
|
-
|
|
5692
5692
|
// ../../lib/utils-mcp/src/index.ts
|
|
5693
5693
|
var textContent = (text) => ({
|
|
5694
5694
|
content: [{ type: "text", text }]
|
|
@@ -5852,11 +5852,12 @@ var toolRegistrars = [
|
|
|
5852
5852
|
];
|
|
5853
5853
|
|
|
5854
5854
|
// src/server.ts
|
|
5855
|
-
var
|
|
5856
|
-
var
|
|
5855
|
+
var MCP_LABS_AUTH_FILE2 = STANDALONE_CLIENT_AUTH_FILE.STACKABLE_LABS.MCP;
|
|
5856
|
+
var MCP_LABS_CLIENT_NAME = STANDALONE_CLIENT.STACKABLE_LABS.MCP;
|
|
5857
5857
|
var DEFAULT_MCP_LABS_API_BASE_URL2 = "https://mcp.stackablelabs.io";
|
|
5858
|
-
var
|
|
5859
|
-
var
|
|
5858
|
+
var DEFAULT_ADMIN_LABS_API_URL = "https://api-x.stackablelabs.io/admin";
|
|
5859
|
+
var adminApiBaseUrl = () => process.env.ADMIN_LABS_API_BASE_URL ?? DEFAULT_ADMIN_LABS_API_URL;
|
|
5860
|
+
var mcpApiBaseUrl = () => process.env.MCP_LABS_API_BASE_URL ?? DEFAULT_MCP_LABS_API_BASE_URL2;
|
|
5860
5861
|
var createMcpServer = (options = {}) => {
|
|
5861
5862
|
const server = new McpServer({
|
|
5862
5863
|
name: "stackable-extension-dev",
|
|
@@ -5867,7 +5868,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5867
5868
|
return options.authContext.token;
|
|
5868
5869
|
}
|
|
5869
5870
|
try {
|
|
5870
|
-
return await getToken(
|
|
5871
|
+
return await getToken(MCP_LABS_AUTH_FILE2);
|
|
5871
5872
|
} catch {
|
|
5872
5873
|
}
|
|
5873
5874
|
if (!options.performOAuthFlow) {
|
|
@@ -5880,7 +5881,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5880
5881
|
const authHeaders = (token) => ({
|
|
5881
5882
|
authorization: `Bearer ${token}`,
|
|
5882
5883
|
"content-type": "application/json",
|
|
5883
|
-
"x-client-name":
|
|
5884
|
+
"x-client-name": MCP_LABS_CLIENT_NAME
|
|
5884
5885
|
});
|
|
5885
5886
|
const callApi = async (path) => {
|
|
5886
5887
|
const token = await getAuthToken();
|
|
@@ -5907,7 +5908,7 @@ var createMcpServer = (options = {}) => {
|
|
|
5907
5908
|
const e = err;
|
|
5908
5909
|
if (e.message.includes("fetch")) {
|
|
5909
5910
|
return errorContent(
|
|
5910
|
-
`MCP auth flow failed: ${e.message}. Check MCP_LABS_API_BASE_URL env var (currently "${mcpApiBaseUrl()}"). To re-auth from scratch: rm ${
|
|
5911
|
+
`MCP auth flow failed: ${e.message}. Check MCP_LABS_API_BASE_URL env var (currently "${mcpApiBaseUrl()}"). To re-auth from scratch: rm ${MCP_LABS_AUTH_FILE2}`
|
|
5911
5912
|
);
|
|
5912
5913
|
}
|
|
5913
5914
|
return errorContent(e.message);
|