@stackable-labs/mcp-app-extension 0.3.0 → 0.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/auth-AJDGAQSE.js +669 -0
- package/dist/auth-JRYNP3PL.js +668 -0
- package/dist/chunk-4XCX3LVH.js +73 -0
- package/dist/chunk-6EMXRSXY.js +72 -0
- package/dist/index.js +6 -44
- package/dist/server.js +6 -46
- package/package.json +3 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
|
|
6
|
+
// ../../lib/contracts/src/permissions.ts
|
|
7
|
+
var SUPER_ROLE = {
|
|
8
|
+
ADMIN: "org:super_admin"
|
|
9
|
+
};
|
|
10
|
+
var ORG_ROLE = {
|
|
11
|
+
ADMIN: "org:admin",
|
|
12
|
+
OWNER: "org:owner"};
|
|
13
|
+
var EDITOR_ROLES = [
|
|
14
|
+
SUPER_ROLE.ADMIN,
|
|
15
|
+
ORG_ROLE.ADMIN,
|
|
16
|
+
ORG_ROLE.OWNER
|
|
17
|
+
];
|
|
18
|
+
[
|
|
19
|
+
...Object.values(SUPER_ROLE),
|
|
20
|
+
...Object.values(EDITOR_ROLES)
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
// ../../lib/utils-auth/src/constants.ts
|
|
24
|
+
var STANDALONE_CLIENT = {
|
|
25
|
+
CLI: "@stackable-labs/cli-app-extension",
|
|
26
|
+
MCP: "@stackable-labs/mcp-app-extension"
|
|
27
|
+
};
|
|
28
|
+
Object.values(STANDALONE_CLIENT);
|
|
29
|
+
|
|
30
|
+
// ../../lib/utils-auth/src/index.ts
|
|
31
|
+
var AUTH_DIR = join(homedir(), ".stackable");
|
|
32
|
+
join(AUTH_DIR, "auth.json");
|
|
33
|
+
join(AUTH_DIR, "mcp-auth.json");
|
|
34
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? "auth.json");
|
|
35
|
+
var readAuthState = async (filename) => {
|
|
36
|
+
try {
|
|
37
|
+
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
38
|
+
return JSON.parse(content);
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var writeAuthState = async (state, filename) => {
|
|
44
|
+
await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
|
|
45
|
+
await writeFile(resolveAuthFile(filename), JSON.stringify(state, null, 2), { mode: 384 });
|
|
46
|
+
};
|
|
47
|
+
var decodeJwtPayload = (token) => {
|
|
48
|
+
try {
|
|
49
|
+
const [, payload] = token.split(".");
|
|
50
|
+
if (!payload) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
54
|
+
return JSON.parse(json);
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var getToken = async (filename) => {
|
|
60
|
+
const state = await readAuthState(filename);
|
|
61
|
+
if (!state) {
|
|
62
|
+
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
63
|
+
}
|
|
64
|
+
const payload = decodeJwtPayload(state.token);
|
|
65
|
+
if (payload?.exp && typeof payload.exp === "number") {
|
|
66
|
+
if (Date.now() >= payload.exp * 1e3) {
|
|
67
|
+
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return state.token;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { STANDALONE_CLIENT, getToken, writeAuthState };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { mkdir, writeFile, readFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
|
|
5
|
+
// ../../lib/utils-auth/src/constants.ts
|
|
6
|
+
var STANDALONE_CLIENT = {
|
|
7
|
+
CLI: "@stackable-labs/cli-app-extension",
|
|
8
|
+
MCP: "@stackable-labs/mcp-app-extension"
|
|
9
|
+
};
|
|
10
|
+
Object.values(STANDALONE_CLIENT);
|
|
11
|
+
|
|
12
|
+
// ../../lib/contracts/src/permissions.ts
|
|
13
|
+
var SUPER_ROLE = {
|
|
14
|
+
ADMIN: "org:super_admin"
|
|
15
|
+
};
|
|
16
|
+
var ORG_ROLE = {
|
|
17
|
+
ADMIN: "org:admin",
|
|
18
|
+
OWNER: "org:owner"};
|
|
19
|
+
var EDITOR_ROLES = [
|
|
20
|
+
SUPER_ROLE.ADMIN,
|
|
21
|
+
ORG_ROLE.ADMIN,
|
|
22
|
+
ORG_ROLE.OWNER
|
|
23
|
+
];
|
|
24
|
+
[
|
|
25
|
+
...Object.values(SUPER_ROLE),
|
|
26
|
+
...Object.values(EDITOR_ROLES)
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
// ../../lib/utils-auth/src/index.ts
|
|
30
|
+
var AUTH_DIR = join(homedir(), ".stackable");
|
|
31
|
+
join(AUTH_DIR, "auth.json");
|
|
32
|
+
join(AUTH_DIR, "mcp-auth.json");
|
|
33
|
+
var resolveAuthFile = (filename) => join(AUTH_DIR, filename ?? "auth.json");
|
|
34
|
+
var readAuthState = async (filename) => {
|
|
35
|
+
try {
|
|
36
|
+
const content = await readFile(resolveAuthFile(filename), "utf8");
|
|
37
|
+
return JSON.parse(content);
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var writeAuthState = async (state, filename) => {
|
|
43
|
+
await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
|
|
44
|
+
await writeFile(resolveAuthFile(filename), JSON.stringify(state, null, 2), { mode: 384 });
|
|
45
|
+
};
|
|
46
|
+
var decodeJwtPayload = (token) => {
|
|
47
|
+
try {
|
|
48
|
+
const [, payload] = token.split(".");
|
|
49
|
+
if (!payload) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const json = Buffer.from(payload, "base64url").toString("utf8");
|
|
53
|
+
return JSON.parse(json);
|
|
54
|
+
} catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var getToken = async (filename) => {
|
|
59
|
+
const state = await readAuthState(filename);
|
|
60
|
+
if (!state) {
|
|
61
|
+
throw new Error("Not authenticated. Run `stackable-app-extension auth login` first.");
|
|
62
|
+
}
|
|
63
|
+
const payload = decodeJwtPayload(state.token);
|
|
64
|
+
if (payload?.exp && typeof payload.exp === "number") {
|
|
65
|
+
if (Date.now() >= payload.exp * 1e3) {
|
|
66
|
+
throw new Error("Session expired. Run `stackable-app-extension auth login` to re-authenticate.");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return state.token;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export { STANDALONE_CLIENT, getToken, writeAuthState };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { STANDALONE_CLIENT, getToken } from './chunk-4XCX3LVH.js';
|
|
2
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
4
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
5
|
import { IDENTITY_EVENTS, ACTIVITY_EVENTS, SURFACE_TARGETS, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
@@ -3751,28 +3752,6 @@ pair(EXAMPLE_SNIPPETS, EXAMPLE_SNIPPETS2);
|
|
|
3751
3752
|
pair(CAPABILITY_SNIPPETS, CAPABILITY_SNIPPETS2);
|
|
3752
3753
|
pair(EVENT_SNIPPETS, EVENT_SNIPPETS2);
|
|
3753
3754
|
|
|
3754
|
-
// ../../lib/contracts/src/permissions.ts
|
|
3755
|
-
var SUPER_ROLE = {
|
|
3756
|
-
ADMIN: "org:super_admin"
|
|
3757
|
-
};
|
|
3758
|
-
var ORG_ROLE = {
|
|
3759
|
-
ADMIN: "org:admin",
|
|
3760
|
-
OWNER: "org:owner"};
|
|
3761
|
-
var EDITOR_ROLES = [
|
|
3762
|
-
SUPER_ROLE.ADMIN,
|
|
3763
|
-
ORG_ROLE.ADMIN,
|
|
3764
|
-
ORG_ROLE.OWNER
|
|
3765
|
-
];
|
|
3766
|
-
[
|
|
3767
|
-
...Object.values(SUPER_ROLE),
|
|
3768
|
-
...Object.values(EDITOR_ROLES)
|
|
3769
|
-
];
|
|
3770
|
-
|
|
3771
|
-
// ../../lib/utils-services/src/auth/index.ts
|
|
3772
|
-
var STANDALONE_CLIENT = {
|
|
3773
|
-
MCP: "@stackable-labs/mcp-app-extension"
|
|
3774
|
-
};
|
|
3775
|
-
|
|
3776
3755
|
// package.json
|
|
3777
3756
|
var package_default = {
|
|
3778
3757
|
version: "0.0.0"};
|
|
@@ -3780,6 +3759,7 @@ var package_default = {
|
|
|
3780
3759
|
// src/server.ts
|
|
3781
3760
|
var MCP_CLIENT_NAME = STANDALONE_CLIENT.MCP;
|
|
3782
3761
|
var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
|
|
3762
|
+
var DEFAULT_MCP_DISCOVERY_URL = "https://api-use1.stackablelabs.io/mcp/.well-known/oauth-authorization-server";
|
|
3783
3763
|
var textContent = (text) => ({ content: [{ type: "text", text }] });
|
|
3784
3764
|
var errorContent = (text) => ({ content: [{ type: "text", text }], isError: true });
|
|
3785
3765
|
var createMcpServer = (options = {}) => {
|
|
@@ -3791,31 +3771,13 @@ var createMcpServer = (options = {}) => {
|
|
|
3791
3771
|
if (options.authContext?.token) {
|
|
3792
3772
|
return options.authContext.token;
|
|
3793
3773
|
}
|
|
3794
|
-
const { readFile } = await import('fs/promises');
|
|
3795
|
-
const { join } = await import('path');
|
|
3796
|
-
const { homedir } = await import('os');
|
|
3797
|
-
const authFile = join(homedir(), ".stackable", "auth.json");
|
|
3798
|
-
let state;
|
|
3799
3774
|
try {
|
|
3800
|
-
|
|
3801
|
-
state = JSON.parse(content);
|
|
3775
|
+
return await getToken("mcp-auth.json");
|
|
3802
3776
|
} catch {
|
|
3803
|
-
throw new Error("Not authenticated. Run 'stackable-app-extension auth login' first.");
|
|
3804
|
-
}
|
|
3805
|
-
const [, payload] = state.token.split(".");
|
|
3806
|
-
if (payload) {
|
|
3807
|
-
try {
|
|
3808
|
-
const decoded = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
3809
|
-
if (decoded.exp && Date.now() >= decoded.exp * 1e3) {
|
|
3810
|
-
throw new Error("Session expired. Run 'stackable-app-extension auth login' to re-authenticate.");
|
|
3811
|
-
}
|
|
3812
|
-
} catch (err) {
|
|
3813
|
-
if (err instanceof Error && err.message.includes("expired")) {
|
|
3814
|
-
throw err;
|
|
3815
|
-
}
|
|
3816
|
-
}
|
|
3817
3777
|
}
|
|
3818
|
-
|
|
3778
|
+
const { performOAuthFlow } = await import('./auth-AJDGAQSE.js');
|
|
3779
|
+
const discoveryUrl = process.env.MCP_DISCOVERY_URL ?? DEFAULT_MCP_DISCOVERY_URL;
|
|
3780
|
+
return performOAuthFlow(discoveryUrl);
|
|
3819
3781
|
};
|
|
3820
3782
|
const authHeaders = (token) => ({
|
|
3821
3783
|
authorization: `Bearer ${token}`,
|
package/dist/server.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
+
import { STANDALONE_CLIENT, getToken } from './chunk-6EMXRSXY.js';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
import { IDENTITY_EVENTS, ACTIVITY_EVENTS, SURFACE_TARGETS, PERMISSIONS, CAPABILITY_PERMISSION_MAP, ALLOWED_ICONS, UI_TAGS, UI_TAG_ATTRIBUTES, tagToComponentName } from '@stackable-labs/sdk-extension-contracts';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
|
|
5
|
-
// src/server.ts
|
|
6
|
-
|
|
7
6
|
// ../../sdk/extension/ai-docs/src/generated/template-content.ts
|
|
8
7
|
var PATTERN_SECTIONS = [
|
|
9
8
|
{
|
|
@@ -3751,28 +3750,6 @@ pair(EXAMPLE_SNIPPETS, EXAMPLE_SNIPPETS2);
|
|
|
3751
3750
|
pair(CAPABILITY_SNIPPETS, CAPABILITY_SNIPPETS2);
|
|
3752
3751
|
pair(EVENT_SNIPPETS, EVENT_SNIPPETS2);
|
|
3753
3752
|
|
|
3754
|
-
// ../../lib/contracts/src/permissions.ts
|
|
3755
|
-
var SUPER_ROLE = {
|
|
3756
|
-
ADMIN: "org:super_admin"
|
|
3757
|
-
};
|
|
3758
|
-
var ORG_ROLE = {
|
|
3759
|
-
ADMIN: "org:admin",
|
|
3760
|
-
OWNER: "org:owner"};
|
|
3761
|
-
var EDITOR_ROLES = [
|
|
3762
|
-
SUPER_ROLE.ADMIN,
|
|
3763
|
-
ORG_ROLE.ADMIN,
|
|
3764
|
-
ORG_ROLE.OWNER
|
|
3765
|
-
];
|
|
3766
|
-
[
|
|
3767
|
-
...Object.values(SUPER_ROLE),
|
|
3768
|
-
...Object.values(EDITOR_ROLES)
|
|
3769
|
-
];
|
|
3770
|
-
|
|
3771
|
-
// ../../lib/utils-services/src/auth/index.ts
|
|
3772
|
-
var STANDALONE_CLIENT = {
|
|
3773
|
-
MCP: "@stackable-labs/mcp-app-extension"
|
|
3774
|
-
};
|
|
3775
|
-
|
|
3776
3753
|
// package.json
|
|
3777
3754
|
var package_default = {
|
|
3778
3755
|
version: "0.0.0"};
|
|
@@ -3780,6 +3757,7 @@ var package_default = {
|
|
|
3780
3757
|
// src/server.ts
|
|
3781
3758
|
var MCP_CLIENT_NAME = STANDALONE_CLIENT.MCP;
|
|
3782
3759
|
var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
|
|
3760
|
+
var DEFAULT_MCP_DISCOVERY_URL = "https://api-use1.stackablelabs.io/mcp/.well-known/oauth-authorization-server";
|
|
3783
3761
|
var textContent = (text) => ({ content: [{ type: "text", text }] });
|
|
3784
3762
|
var errorContent = (text) => ({ content: [{ type: "text", text }], isError: true });
|
|
3785
3763
|
var createMcpServer = (options = {}) => {
|
|
@@ -3791,31 +3769,13 @@ var createMcpServer = (options = {}) => {
|
|
|
3791
3769
|
if (options.authContext?.token) {
|
|
3792
3770
|
return options.authContext.token;
|
|
3793
3771
|
}
|
|
3794
|
-
const { readFile } = await import('fs/promises');
|
|
3795
|
-
const { join } = await import('path');
|
|
3796
|
-
const { homedir } = await import('os');
|
|
3797
|
-
const authFile = join(homedir(), ".stackable", "auth.json");
|
|
3798
|
-
let state;
|
|
3799
3772
|
try {
|
|
3800
|
-
|
|
3801
|
-
state = JSON.parse(content);
|
|
3773
|
+
return await getToken("mcp-auth.json");
|
|
3802
3774
|
} catch {
|
|
3803
|
-
throw new Error("Not authenticated. Run 'stackable-app-extension auth login' first.");
|
|
3804
|
-
}
|
|
3805
|
-
const [, payload] = state.token.split(".");
|
|
3806
|
-
if (payload) {
|
|
3807
|
-
try {
|
|
3808
|
-
const decoded = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
|
|
3809
|
-
if (decoded.exp && Date.now() >= decoded.exp * 1e3) {
|
|
3810
|
-
throw new Error("Session expired. Run 'stackable-app-extension auth login' to re-authenticate.");
|
|
3811
|
-
}
|
|
3812
|
-
} catch (err) {
|
|
3813
|
-
if (err instanceof Error && err.message.includes("expired")) {
|
|
3814
|
-
throw err;
|
|
3815
|
-
}
|
|
3816
|
-
}
|
|
3817
3775
|
}
|
|
3818
|
-
|
|
3776
|
+
const { performOAuthFlow } = await import('./auth-JRYNP3PL.js');
|
|
3777
|
+
const discoveryUrl = process.env.MCP_DISCOVERY_URL ?? DEFAULT_MCP_DISCOVERY_URL;
|
|
3778
|
+
return performOAuthFlow(discoveryUrl);
|
|
3819
3779
|
};
|
|
3820
3780
|
const authHeaders = (token) => ({
|
|
3821
3781
|
authorization: `Bearer ${token}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackable-labs/mcp-app-extension",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mcp-app-extension": "./dist/index.js"
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@modelcontextprotocol/sdk": "1.x",
|
|
25
25
|
"@stackable-labs/sdk-extension-contracts": "latest",
|
|
26
|
+
"oauth4webapi": "3.x",
|
|
27
|
+
"open": "10.x",
|
|
26
28
|
"zod": "3.x"
|
|
27
29
|
},
|
|
28
30
|
"description": "MCP server for AI-assisted Stackable extension development.",
|