@fabricorg/sdk-mcp 0.1.9 → 0.1.11
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.cjs +3 -145
- package/dist/index.d.cts +23 -49
- package/dist/index.d.ts +23 -49
- package/dist/index.js +1 -142
- package/dist/src-Dvp0pFUZ.cjs +164 -0
- package/dist/src-Dvp0pFUZ.cjs.map +1 -0
- package/dist/src-OoM54hoY.js +153 -0
- package/dist/src-OoM54hoY.js.map +1 -0
- package/dist/stdio.cjs +33 -163
- package/dist/stdio.cjs.map +1 -1
- package/dist/stdio.d.cts +4 -3
- package/dist/stdio.d.ts +4 -3
- package/dist/stdio.js +32 -161
- package/dist/stdio.js.map +1 -1
- package/package.json +8 -8
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region \0@oxc-project+runtime@0.152.0/helpers/esm/asyncToGenerator.js
|
|
4
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) {
|
|
5
|
+
try {
|
|
6
|
+
var i = n[a](c), u = i.value;
|
|
7
|
+
} catch (n) {
|
|
8
|
+
e(n);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
i.done ? t(u) : Promise.resolve(u).then(r, o);
|
|
12
|
+
}
|
|
13
|
+
function _asyncToGenerator(n) {
|
|
14
|
+
return function() {
|
|
15
|
+
var t = this, e = arguments;
|
|
16
|
+
return new Promise(function(r, o) {
|
|
17
|
+
var a = n.apply(t, e);
|
|
18
|
+
function _next(n) {
|
|
19
|
+
asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
|
|
20
|
+
}
|
|
21
|
+
function _throw(n) {
|
|
22
|
+
asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
|
|
23
|
+
}
|
|
24
|
+
_next(void 0);
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
//#region src/index.ts
|
|
30
|
+
/**
|
|
31
|
+
* @fabricorg/sdk-mcp
|
|
32
|
+
*
|
|
33
|
+
* Builds an MCP (Model Context Protocol) server that exposes a Fabric
|
|
34
|
+
* workspace's whole integration catalog as MCP tools — any MCP-compatible
|
|
35
|
+
* agent (Claude Desktop, Cursor, Continue, OpenAI agents, …) can point at
|
|
36
|
+
* one endpoint and get every connected vendor.
|
|
37
|
+
*
|
|
38
|
+
* Three generic tools (corsair-style):
|
|
39
|
+
* - `fabric_list_integrations` — what's connected for this tenant
|
|
40
|
+
* - `fabric_list_operations` — endpoints for one integration
|
|
41
|
+
* - `fabric_call` — execute an operation
|
|
42
|
+
*
|
|
43
|
+
* Usage (stdio transport, e.g. Claude Desktop):
|
|
44
|
+
* import { createFabricMcpServer } from "@fabricorg/sdk-mcp";
|
|
45
|
+
* import { createFabric } from "@fabricorg/sdk";
|
|
46
|
+
* import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
47
|
+
*
|
|
48
|
+
* const fabric = createFabric({ apiKey: process.env.FABRIC_API_KEY });
|
|
49
|
+
* const server = createFabricMcpServer({ fabric });
|
|
50
|
+
* await server.connect(new StdioServerTransport());
|
|
51
|
+
*
|
|
52
|
+
* Or use the prebuilt stdio entry: `import "@fabricorg/sdk-mcp/stdio";`
|
|
53
|
+
* (The `fabric mcp serve` CLI command is the recommended user-facing path.)
|
|
54
|
+
*/
|
|
55
|
+
/**
|
|
56
|
+
* Build a configured `McpServer` exposing the workspace catalog. Caller is
|
|
57
|
+
* responsible for `.connect(transport)` so the same server works over stdio,
|
|
58
|
+
* HTTP, or any other MCP transport.
|
|
59
|
+
*/
|
|
60
|
+
function createFabricMcpServer(options) {
|
|
61
|
+
var _options$name, _options$version;
|
|
62
|
+
const fabric = options.fabric;
|
|
63
|
+
const server = new McpServer({
|
|
64
|
+
name: (_options$name = options.name) !== null && _options$name !== void 0 ? _options$name : "fabric",
|
|
65
|
+
version: (_options$version = options.version) !== null && _options$version !== void 0 ? _options$version : "0.1.0"
|
|
66
|
+
});
|
|
67
|
+
server.registerTool("fabric_list_integrations", {
|
|
68
|
+
title: "List Fabric Integrations",
|
|
69
|
+
description: "List integrations connected for the authenticated Fabric workspace. Returns slug, display name, current connection status, permission mode (open/cautious/strict/readonly), and source (plugin/mcp-server/connector).",
|
|
70
|
+
inputSchema: {}
|
|
71
|
+
}, _asyncToGenerator(function* () {
|
|
72
|
+
const integrations = yield fabric.integrations.list();
|
|
73
|
+
return { content: [{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: JSON.stringify(integrations, null, 2)
|
|
76
|
+
}] };
|
|
77
|
+
}));
|
|
78
|
+
server.registerTool("fabric_list_operations", {
|
|
79
|
+
title: "List Operations for an Integration",
|
|
80
|
+
description: "List the dot-notation operations available on a single Fabric integration. Returns an array of `{ operation, riskLevel, description }`. Supply the slug from `fabric_list_integrations`.",
|
|
81
|
+
inputSchema: { slug: z.string().describe("Integration slug, e.g. \"slack\", \"github\", \"linear\".") }
|
|
82
|
+
}, function() {
|
|
83
|
+
var _ref = _asyncToGenerator(function* ({ slug }) {
|
|
84
|
+
const integration = fabric.integrations[slug];
|
|
85
|
+
if (!integration) return {
|
|
86
|
+
content: [{
|
|
87
|
+
type: "text",
|
|
88
|
+
text: `Integration "${slug}" is not registered for this workspace.`
|
|
89
|
+
}],
|
|
90
|
+
isError: true
|
|
91
|
+
};
|
|
92
|
+
try {
|
|
93
|
+
var _integration$call;
|
|
94
|
+
const ops = yield (_integration$call = integration.call) === null || _integration$call === void 0 ? void 0 : _integration$call.call(integration, "__operations");
|
|
95
|
+
return { content: [{
|
|
96
|
+
type: "text",
|
|
97
|
+
text: JSON.stringify(ops, null, 2)
|
|
98
|
+
}] };
|
|
99
|
+
} catch (_unused) {
|
|
100
|
+
return { content: [{
|
|
101
|
+
type: "text",
|
|
102
|
+
text: `Operation listing for "${slug}" requires portal endpoint /api/v1/integrations/${slug}/operations (not yet exposed). Use fabric_call with a known operation path in the meantime.`
|
|
103
|
+
}] };
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return function(_x) {
|
|
107
|
+
return _ref.apply(this, arguments);
|
|
108
|
+
};
|
|
109
|
+
}());
|
|
110
|
+
server.registerTool("fabric_call", {
|
|
111
|
+
title: "Call a Fabric Integration Operation",
|
|
112
|
+
description: "Execute an operation on a connected Fabric integration. Args is a JSON object whose shape depends on the specific operation. Returns the upstream response, or { status: 'pending_approval' | 'denied' } when the workspace permission policy gates the call.",
|
|
113
|
+
inputSchema: {
|
|
114
|
+
slug: z.string().describe("Integration slug, e.g. \"slack\"."),
|
|
115
|
+
operation: z.string().describe("Dot-notation operation, e.g. \"messages.send\" or \"channels.list\"."),
|
|
116
|
+
args: z.record(z.string(), z.unknown()).optional().describe("Arguments object. Shape depends on the operation.")
|
|
117
|
+
}
|
|
118
|
+
}, function() {
|
|
119
|
+
var _ref2 = _asyncToGenerator(function* ({ slug, operation, args }) {
|
|
120
|
+
const integration = fabric.integrations[slug];
|
|
121
|
+
if (!(integration === null || integration === void 0 ? void 0 : integration.call)) return {
|
|
122
|
+
content: [{
|
|
123
|
+
type: "text",
|
|
124
|
+
text: `Integration "${slug}" is not registered for this workspace.`
|
|
125
|
+
}],
|
|
126
|
+
isError: true
|
|
127
|
+
};
|
|
128
|
+
try {
|
|
129
|
+
const result = yield integration.call(operation, args !== null && args !== void 0 ? args : {});
|
|
130
|
+
return { content: [{
|
|
131
|
+
type: "text",
|
|
132
|
+
text: JSON.stringify(result, null, 2)
|
|
133
|
+
}] };
|
|
134
|
+
} catch (err) {
|
|
135
|
+
return {
|
|
136
|
+
content: [{
|
|
137
|
+
type: "text",
|
|
138
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
139
|
+
}],
|
|
140
|
+
isError: true
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return function(_x2) {
|
|
145
|
+
return _ref2.apply(this, arguments);
|
|
146
|
+
};
|
|
147
|
+
}());
|
|
148
|
+
return server;
|
|
149
|
+
}
|
|
150
|
+
//#endregion
|
|
151
|
+
export { _asyncToGenerator as n, createFabricMcpServer as t };
|
|
152
|
+
|
|
153
|
+
//# sourceMappingURL=src-OoM54hoY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-OoM54hoY.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * @fabricorg/sdk-mcp\n *\n * Builds an MCP (Model Context Protocol) server that exposes a Fabric\n * workspace's whole integration catalog as MCP tools — any MCP-compatible\n * agent (Claude Desktop, Cursor, Continue, OpenAI agents, …) can point at\n * one endpoint and get every connected vendor.\n *\n * Three generic tools (corsair-style):\n * - `fabric_list_integrations` — what's connected for this tenant\n * - `fabric_list_operations` — endpoints for one integration\n * - `fabric_call` — execute an operation\n *\n * Usage (stdio transport, e.g. Claude Desktop):\n * import { createFabricMcpServer } from \"@fabricorg/sdk-mcp\";\n * import { createFabric } from \"@fabricorg/sdk\";\n * import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n *\n * const fabric = createFabric({ apiKey: process.env.FABRIC_API_KEY });\n * const server = createFabricMcpServer({ fabric });\n * await server.connect(new StdioServerTransport());\n *\n * Or use the prebuilt stdio entry: `import \"@fabricorg/sdk-mcp/stdio\";`\n * (The `fabric mcp serve` CLI command is the recommended user-facing path.)\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\n// Avoid importing @fabricorg/sdk concrete types at runtime; we only need its\n// shape so the server is decoupled from a specific SDK version. Consumers\n// pass an `FabricClient` instance. Exported because the declaration bundler\n// drops the `export {}` marker that keeps unexported types in a .d.ts private.\nexport type FabricLike = {\n\tintegrations: {\n\t\tlist(): Promise<\n\t\t\tArray<{\n\t\t\t\tslug: string;\n\t\t\t\tname: string;\n\t\t\t\tstatus: string;\n\t\t\t\tmode: string;\n\t\t\t\tsource: string;\n\t\t\t}>\n\t\t>;\n\t\t[slug: string]: unknown;\n\t};\n};\n\nexport interface CreateFabricMcpServerOptions {\n\t/** A configured FabricClient (createFabric) instance. Required. */\n\tfabric: FabricLike;\n\t/** Server name reported on the MCP handshake. Default `\"fabric\"`. */\n\tname?: string;\n\t/** Server version. Default `\"0.1.0\"`. */\n\tversion?: string;\n}\n\n/**\n * Build a configured `McpServer` exposing the workspace catalog. Caller is\n * responsible for `.connect(transport)` so the same server works over stdio,\n * HTTP, or any other MCP transport.\n */\nexport function createFabricMcpServer(\n\toptions: CreateFabricMcpServerOptions,\n): McpServer {\n\tconst fabric = options.fabric;\n\tconst server = new McpServer({\n\t\tname: options.name ?? \"fabric\",\n\t\tversion: options.version ?? \"0.1.0\",\n\t});\n\n\tserver.registerTool(\n\t\t\"fabric_list_integrations\",\n\t\t{\n\t\t\ttitle: \"List Fabric Integrations\",\n\t\t\tdescription:\n\t\t\t\t\"List integrations connected for the authenticated Fabric workspace. \" +\n\t\t\t\t\"Returns slug, display name, current connection status, permission mode \" +\n\t\t\t\t\"(open/cautious/strict/readonly), and source (plugin/mcp-server/connector).\",\n\t\t\tinputSchema: {},\n\t\t},\n\t\tasync () => {\n\t\t\tconst integrations = await fabric.integrations.list();\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: JSON.stringify(integrations, null, 2),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"fabric_list_operations\",\n\t\t{\n\t\t\ttitle: \"List Operations for an Integration\",\n\t\t\tdescription:\n\t\t\t\t\"List the dot-notation operations available on a single Fabric integration. \" +\n\t\t\t\t\"Returns an array of `{ operation, riskLevel, description }`. Supply the \" +\n\t\t\t\t\"slug from `fabric_list_integrations`.\",\n\t\t\tinputSchema: {\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Integration slug, e.g. \"slack\", \"github\", \"linear\".',\n\t\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\tasync ({ slug }) => {\n\t\t\t// Endpoint metadata isn't exposed via the SDK's HTTP surface yet, so we\n\t\t\t// hit a known introspection path the portal returns under\n\t\t\t// `/integrations/:slug/operations`. Until that route lands, we surface a\n\t\t\t// helpful TODO so agents don't silently get an empty list.\n\t\t\tconst integration = (\n\t\t\t\tfabric.integrations as Record<string, unknown>\n\t\t\t)[slug] as\n\t\t\t\t| {\n\t\t\t\t\t\tcall?: (op: string, args?: unknown) => Promise<unknown>;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t\tif (!integration) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Integration \"${slug}\" is not registered for this workspace.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\t// Best-effort: the portal may expose `__operations` as a\n\t\t\t\t// magic operation that returns the catalog.\n\t\t\t\tconst ops = await integration.call?.(\"__operations\");\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{ type: \"text\", text: JSON.stringify(ops, null, 2) },\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Operation listing for \"${slug}\" requires portal endpoint /api/v1/integrations/${slug}/operations (not yet exposed). Use fabric_call with a known operation path in the meantime.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"fabric_call\",\n\t\t{\n\t\t\ttitle: \"Call a Fabric Integration Operation\",\n\t\t\tdescription:\n\t\t\t\t\"Execute an operation on a connected Fabric integration. Args is a JSON \" +\n\t\t\t\t\"object whose shape depends on the specific operation. Returns the \" +\n\t\t\t\t\"upstream response, or { status: 'pending_approval' | 'denied' } when \" +\n\t\t\t\t\"the workspace permission policy gates the call.\",\n\t\t\tinputSchema: {\n\t\t\t\tslug: z.string().describe('Integration slug, e.g. \"slack\".'),\n\t\t\t\toperation: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Dot-notation operation, e.g. \"messages.send\" or \"channels.list\".',\n\t\t\t\t\t),\n\t\t\t\targs: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Arguments object. Shape depends on the operation.\",\n\t\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\tasync ({ slug, operation, args }) => {\n\t\t\tconst integration = (\n\t\t\t\tfabric.integrations as Record<string, unknown>\n\t\t\t)[slug] as\n\t\t\t\t| {\n\t\t\t\t\t\tcall?: (op: string, args?: unknown) => Promise<unknown>;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t\tif (!integration?.call) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Integration \"${slug}\" is not registered for this workspace.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await integration.call(operation, args ?? {});\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{ type: \"text\", text: JSON.stringify(result, null, 2) },\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tconst message =\n\t\t\t\t\terr instanceof Error ? err.message : String(err);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Error: ${message}` }],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\treturn server;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,sBACf,SACY;;CACZ,MAAM,SAAS,QAAQ;CACvB,MAAM,SAAS,IAAI,UAAU;EAC5B,OAAA,gBAAM,QAAQ,UAAA,QAAA,kBAAA,KAAA,IAAA,gBAAQ;EACtB,UAAA,mBAAS,QAAQ,aAAA,QAAA,qBAAA,KAAA,IAAA,mBAAW;CAC7B,CAAC;CAED,OAAO,aACN,4BACA;EACC,OAAO;EACP,aACC;EAGD,aAAa,CAAC;CACf,GAAA,kBAAA,aACY;EACX,MAAM,eAAe,MAAM,OAAO,aAAa,KAAK;EACpD,OAAO,EACN,SAAS,CACR;GACC,MAAM;GACN,MAAM,KAAK,UAAU,cAAc,MAAM,CAAC;EAC3C,CACD,EACD;CACD,CAAA,CACD;CAEA,OAAO,aACN,0BACA;EACC,OAAO;EACP,aACC;EAGD,aAAa,EACZ,MAAM,EACJ,OAAO,CAAC,CACR,SACA,2DACD,EACF;CACD,GAAA,WAAA;EACO,IAAA,OAAA,kBAAA,WAAA,EAAE,QAAW;GAKnB,MAAM,cACL,OAAO,aACN;GAKF,IAAI,CAAC,aACJ,OAAO;IACN,SAAS,CACR;KACC,MAAM;KACN,MAAM,gBAAgB,KAAK;IAC5B,CACD;IACA,SAAS;GACV;GAED,IAAI;;IAGH,MAAM,MAAM,OAAA,oBAAM,YAAY,UAAA,QAAA,sBAAA,KAAA,IAAA,KAAA,IAAA,kBAAA,KAAA,aAAO,cAAc;IACnD,OAAO,EACN,SAAS,CACR;KAAE,MAAM;KAAQ,MAAM,KAAK,UAAU,KAAK,MAAM,CAAC;IAAE,CACpD,EACD;GACD,SAAA,SAAQ;IACP,OAAO,EACN,SAAS,CACR;KACC,MAAM;KACN,MAAM,0BAA0B,KAAK,kDAAkD,KAAK;IAC7F,CACD,EACD;GACD;EACD,CAAA;EA1CO,OAAA,SAAA,IAAA;;;CA0CP,EAAA,CACD;CAEA,OAAO,aACN,eACA;EACC,OAAO;EACP,aACC;EAID,aAAa;GACZ,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS,mCAAiC;GAC3D,WAAW,EACT,OAAO,CAAC,CACR,SACA,sEACD;GACD,MAAM,EACJ,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAC/B,SAAS,CAAC,CACV,SACA,mDACD;EACF;CACD,GAAA,WAAA;EACO,IAAA,QAAA,kBAAA,WAAA,EAAE,MAAM,WAAW,QAAW;GACpC,MAAM,cACL,OAAO,aACN;GAKF,IAAI,EAAA,gBAAA,QAAA,gBAAA,KAAA,IAAA,KAAA,IAAC,YAAa,OACjB,OAAO;IACN,SAAS,CACR;KACC,MAAM;KACN,MAAM,gBAAgB,KAAK;IAC5B,CACD;IACA,SAAS;GACV;GAED,IAAI;IACH,MAAM,SAAS,MAAM,YAAY,KAAK,WAAW,SAAA,QAAA,SAAA,KAAA,IAAA,OAAQ,CAAC,CAAC;IAC3D,OAAO,EACN,SAAS,CACR;KAAE,MAAM;KAAQ,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;IAAE,CACvD,EACD;GACD,SAAS,KAAK;IAGb,OAAO;KACN,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,UAFhC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;KAEK,CAAC;KACrD,SAAS;IACV;GACD;EACD,CAAA;EAlCO,OAAA,SAAA,KAAA;;;CAkCP,EAAA,CACD;CAEA,OAAO;AACR"}
|
package/dist/stdio.cjs
CHANGED
|
@@ -1,168 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
step(generator.throw(value));
|
|
20
|
-
} catch (e) {
|
|
21
|
-
reject(e);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
25
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
function createFabricMcpServer(options) {
|
|
29
|
-
var _a, _b;
|
|
30
|
-
const fabric = options.fabric;
|
|
31
|
-
const server = new mcp_js.McpServer({
|
|
32
|
-
name: (_a = options.name) != null ? _a : "fabric",
|
|
33
|
-
version: (_b = options.version) != null ? _b : "0.1.0"
|
|
34
|
-
});
|
|
35
|
-
server.registerTool(
|
|
36
|
-
"fabric_list_integrations",
|
|
37
|
-
{
|
|
38
|
-
title: "List Fabric Integrations",
|
|
39
|
-
description: "List integrations connected for the authenticated Fabric workspace. Returns slug, display name, current connection status, permission mode (open/cautious/strict/readonly), and source (plugin/mcp-server/connector).",
|
|
40
|
-
inputSchema: {}
|
|
41
|
-
},
|
|
42
|
-
() => __async(null, null, function* () {
|
|
43
|
-
const integrations = yield fabric.integrations.list();
|
|
44
|
-
return {
|
|
45
|
-
content: [
|
|
46
|
-
{
|
|
47
|
-
type: "text",
|
|
48
|
-
text: JSON.stringify(integrations, null, 2)
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
};
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
server.registerTool(
|
|
55
|
-
"fabric_list_operations",
|
|
56
|
-
{
|
|
57
|
-
title: "List Operations for an Integration",
|
|
58
|
-
description: "List the dot-notation operations available on a single Fabric integration. Returns an array of `{ operation, riskLevel, description }`. Supply the slug from `fabric_list_integrations`.",
|
|
59
|
-
inputSchema: {
|
|
60
|
-
slug: zod.z.string().describe(
|
|
61
|
-
'Integration slug, e.g. "slack", "github", "linear".'
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
(_0) => __async(null, [_0], function* ({ slug }) {
|
|
66
|
-
var _a2;
|
|
67
|
-
const integration = fabric.integrations[slug];
|
|
68
|
-
if (!integration) {
|
|
69
|
-
return {
|
|
70
|
-
content: [
|
|
71
|
-
{
|
|
72
|
-
type: "text",
|
|
73
|
-
text: `Integration "${slug}" is not registered for this workspace.`
|
|
74
|
-
}
|
|
75
|
-
],
|
|
76
|
-
isError: true
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
const ops = yield (_a2 = integration.call) == null ? void 0 : _a2.call(integration, "__operations");
|
|
81
|
-
return {
|
|
82
|
-
content: [
|
|
83
|
-
{ type: "text", text: JSON.stringify(ops, null, 2) }
|
|
84
|
-
]
|
|
85
|
-
};
|
|
86
|
-
} catch (e) {
|
|
87
|
-
return {
|
|
88
|
-
content: [
|
|
89
|
-
{
|
|
90
|
-
type: "text",
|
|
91
|
-
text: `Operation listing for "${slug}" requires portal endpoint /api/v1/integrations/${slug}/operations (not yet exposed). Use fabric_call with a known operation path in the meantime.`
|
|
92
|
-
}
|
|
93
|
-
]
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
})
|
|
97
|
-
);
|
|
98
|
-
server.registerTool(
|
|
99
|
-
"fabric_call",
|
|
100
|
-
{
|
|
101
|
-
title: "Call a Fabric Integration Operation",
|
|
102
|
-
description: "Execute an operation on a connected Fabric integration. Args is a JSON object whose shape depends on the specific operation. Returns the upstream response, or { status: 'pending_approval' | 'denied' } when the workspace permission policy gates the call.",
|
|
103
|
-
inputSchema: {
|
|
104
|
-
slug: zod.z.string().describe('Integration slug, e.g. "slack".'),
|
|
105
|
-
operation: zod.z.string().describe(
|
|
106
|
-
'Dot-notation operation, e.g. "messages.send" or "channels.list".'
|
|
107
|
-
),
|
|
108
|
-
args: zod.z.record(zod.z.string(), zod.z.unknown()).optional().describe(
|
|
109
|
-
"Arguments object. Shape depends on the operation."
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
(_0) => __async(null, [_0], function* ({ slug, operation, args }) {
|
|
114
|
-
const integration = fabric.integrations[slug];
|
|
115
|
-
if (!(integration == null ? void 0 : integration.call)) {
|
|
116
|
-
return {
|
|
117
|
-
content: [
|
|
118
|
-
{
|
|
119
|
-
type: "text",
|
|
120
|
-
text: `Integration "${slug}" is not registered for this workspace.`
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
isError: true
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
const result = yield integration.call(operation, args != null ? args : {});
|
|
128
|
-
return {
|
|
129
|
-
content: [
|
|
130
|
-
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
131
|
-
]
|
|
132
|
-
};
|
|
133
|
-
} catch (err) {
|
|
134
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
135
|
-
return {
|
|
136
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
137
|
-
isError: true
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
);
|
|
142
|
-
return server;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// src/stdio.ts
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_src = require("./src-Dvp0pFUZ.cjs");
|
|
3
|
+
let _fabricorg_sdk = require("@fabricorg/sdk");
|
|
4
|
+
let _modelcontextprotocol_sdk_server_stdio_js = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
//#region src/stdio.ts
|
|
6
|
+
/**
|
|
7
|
+
* @fabricorg/sdk-mcp/stdio
|
|
8
|
+
*
|
|
9
|
+
* Convenience entry: runs a stdio MCP server using `FABRIC_API_KEY`
|
|
10
|
+
* (and optional `FABRIC_BASE_URL` / `FABRIC_ORG`) from the environment.
|
|
11
|
+
*
|
|
12
|
+
* Designed to be exec'd by an MCP client (Claude Desktop, Cursor, etc.).
|
|
13
|
+
* The `fabric mcp serve` CLI command is the recommended invocation; this
|
|
14
|
+
* file is the underlying script.
|
|
15
|
+
*
|
|
16
|
+
* Stdout is reserved for the JSON-RPC framing — log only to stderr.
|
|
17
|
+
*/
|
|
146
18
|
function runStdio() {
|
|
147
|
-
|
|
148
|
-
const fabric = sdk.createFabric({});
|
|
149
|
-
const server = createFabricMcpServer({ fabric });
|
|
150
|
-
const transport = new stdio_js.StdioServerTransport();
|
|
151
|
-
yield server.connect(transport);
|
|
152
|
-
process.stderr.write("[fabric-mcp] stdio transport connected\n");
|
|
153
|
-
});
|
|
19
|
+
return _runStdio.apply(this, arguments);
|
|
154
20
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
21
|
+
function _runStdio() {
|
|
22
|
+
_runStdio = require_src._asyncToGenerator(function* () {
|
|
23
|
+
const fabric = (0, _fabricorg_sdk.createFabric)({});
|
|
24
|
+
const server = require_src.createFabricMcpServer({ fabric });
|
|
25
|
+
const transport = new _modelcontextprotocol_sdk_server_stdio_js.StdioServerTransport();
|
|
26
|
+
yield server.connect(transport);
|
|
27
|
+
process.stderr.write("[fabric-mcp] stdio transport connected\n");
|
|
28
|
+
});
|
|
29
|
+
return _runStdio.apply(this, arguments);
|
|
164
30
|
}
|
|
165
|
-
|
|
31
|
+
if (typeof process !== "undefined" && Array.isArray(process.argv) && process.argv[1] !== void 0 && (process.argv[1].endsWith("stdio.js") || process.argv[1].endsWith("stdio.cjs"))) runStdio().catch((err) => {
|
|
32
|
+
process.stderr.write(`[fabric-mcp] fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
//#endregion
|
|
166
36
|
exports.runStdio = runStdio;
|
|
167
|
-
|
|
37
|
+
|
|
168
38
|
//# sourceMappingURL=stdio.cjs.map
|
package/dist/stdio.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/stdio.ts"],"names":["McpServer","z","_a","createFabric","StdioServerTransport"],"mappings":"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","file":"stdio.cjs","sourcesContent":["/**\n * @fabricorg/sdk-mcp\n *\n * Builds an MCP (Model Context Protocol) server that exposes a Fabric\n * workspace's whole integration catalog as MCP tools — any MCP-compatible\n * agent (Claude Desktop, Cursor, Continue, OpenAI agents, …) can point at\n * one endpoint and get every connected vendor.\n *\n * Three generic tools (corsair-style):\n * - `fabric_list_integrations` — what's connected for this tenant\n * - `fabric_list_operations` — endpoints for one integration\n * - `fabric_call` — execute an operation\n *\n * Usage (stdio transport, e.g. Claude Desktop):\n * import { createFabricMcpServer } from \"@fabricorg/sdk-mcp\";\n * import { createFabric } from \"@fabricorg/sdk\";\n * import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n *\n * const fabric = createFabric({ apiKey: process.env.FABRIC_API_KEY });\n * const server = createFabricMcpServer({ fabric });\n * await server.connect(new StdioServerTransport());\n *\n * Or use the prebuilt stdio entry: `import \"@fabricorg/sdk-mcp/stdio\";`\n * (The `fabric mcp serve` CLI command is the recommended user-facing path.)\n */\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\n\n// Avoid importing @fabricorg/sdk concrete types at runtime; we only need its\n// shape so the server is decoupled from a specific SDK version. Consumers\n// pass an `FabricClient` instance.\ntype FabricLike = {\n\tintegrations: {\n\t\tlist(): Promise<\n\t\t\tArray<{\n\t\t\t\tslug: string;\n\t\t\t\tname: string;\n\t\t\t\tstatus: string;\n\t\t\t\tmode: string;\n\t\t\t\tsource: string;\n\t\t\t}>\n\t\t>;\n\t\t[slug: string]: unknown;\n\t};\n};\n\nexport interface CreateFabricMcpServerOptions {\n\t/** A configured FabricClient (createFabric) instance. Required. */\n\tfabric: FabricLike;\n\t/** Server name reported on the MCP handshake. Default `\"fabric\"`. */\n\tname?: string;\n\t/** Server version. Default `\"0.1.0\"`. */\n\tversion?: string;\n}\n\n/**\n * Build a configured `McpServer` exposing the workspace catalog. Caller is\n * responsible for `.connect(transport)` so the same server works over stdio,\n * HTTP, or any other MCP transport.\n */\nexport function createFabricMcpServer(\n\toptions: CreateFabricMcpServerOptions,\n): McpServer {\n\tconst fabric = options.fabric;\n\tconst server = new McpServer({\n\t\tname: options.name ?? \"fabric\",\n\t\tversion: options.version ?? \"0.1.0\",\n\t});\n\n\tserver.registerTool(\n\t\t\"fabric_list_integrations\",\n\t\t{\n\t\t\ttitle: \"List Fabric Integrations\",\n\t\t\tdescription:\n\t\t\t\t\"List integrations connected for the authenticated Fabric workspace. \" +\n\t\t\t\t\"Returns slug, display name, current connection status, permission mode \" +\n\t\t\t\t\"(open/cautious/strict/readonly), and source (plugin/mcp-server/connector).\",\n\t\t\tinputSchema: {},\n\t\t},\n\t\tasync () => {\n\t\t\tconst integrations = await fabric.integrations.list();\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: JSON.stringify(integrations, null, 2),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"fabric_list_operations\",\n\t\t{\n\t\t\ttitle: \"List Operations for an Integration\",\n\t\t\tdescription:\n\t\t\t\t\"List the dot-notation operations available on a single Fabric integration. \" +\n\t\t\t\t\"Returns an array of `{ operation, riskLevel, description }`. Supply the \" +\n\t\t\t\t\"slug from `fabric_list_integrations`.\",\n\t\t\tinputSchema: {\n\t\t\t\tslug: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Integration slug, e.g. \"slack\", \"github\", \"linear\".',\n\t\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\tasync ({ slug }) => {\n\t\t\t// Endpoint metadata isn't exposed via the SDK's HTTP surface yet, so we\n\t\t\t// hit a known introspection path the portal returns under\n\t\t\t// `/integrations/:slug/operations`. Until that route lands, we surface a\n\t\t\t// helpful TODO so agents don't silently get an empty list.\n\t\t\tconst integration = (\n\t\t\t\tfabric.integrations as Record<string, unknown>\n\t\t\t)[slug] as\n\t\t\t\t| {\n\t\t\t\t\t\tcall?: (op: string, args?: unknown) => Promise<unknown>;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t\tif (!integration) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Integration \"${slug}\" is not registered for this workspace.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\t// Best-effort: the portal may expose `__operations` as a\n\t\t\t\t// magic operation that returns the catalog.\n\t\t\t\tconst ops = await integration.call?.(\"__operations\");\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{ type: \"text\", text: JSON.stringify(ops, null, 2) },\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Operation listing for \"${slug}\" requires portal endpoint /api/v1/integrations/${slug}/operations (not yet exposed). Use fabric_call with a known operation path in the meantime.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.registerTool(\n\t\t\"fabric_call\",\n\t\t{\n\t\t\ttitle: \"Call a Fabric Integration Operation\",\n\t\t\tdescription:\n\t\t\t\t\"Execute an operation on a connected Fabric integration. Args is a JSON \" +\n\t\t\t\t\"object whose shape depends on the specific operation. Returns the \" +\n\t\t\t\t\"upstream response, or { status: 'pending_approval' | 'denied' } when \" +\n\t\t\t\t\"the workspace permission policy gates the call.\",\n\t\t\tinputSchema: {\n\t\t\t\tslug: z.string().describe('Integration slug, e.g. \"slack\".'),\n\t\t\t\toperation: z\n\t\t\t\t\t.string()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t'Dot-notation operation, e.g. \"messages.send\" or \"channels.list\".',\n\t\t\t\t\t),\n\t\t\t\targs: z\n\t\t\t\t\t.record(z.string(), z.unknown())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.describe(\n\t\t\t\t\t\t\"Arguments object. Shape depends on the operation.\",\n\t\t\t\t\t),\n\t\t\t},\n\t\t},\n\t\tasync ({ slug, operation, args }) => {\n\t\t\tconst integration = (\n\t\t\t\tfabric.integrations as Record<string, unknown>\n\t\t\t)[slug] as\n\t\t\t\t| {\n\t\t\t\t\t\tcall?: (op: string, args?: unknown) => Promise<unknown>;\n\t\t\t\t }\n\t\t\t\t| undefined;\n\t\t\tif (!integration?.call) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `Integration \"${slug}\" is not registered for this workspace.`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst result = await integration.call(operation, args ?? {});\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{ type: \"text\", text: JSON.stringify(result, null, 2) },\n\t\t\t\t\t],\n\t\t\t\t};\n\t\t\t} catch (err) {\n\t\t\t\tconst message =\n\t\t\t\t\terr instanceof Error ? err.message : String(err);\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Error: ${message}` }],\n\t\t\t\t\tisError: true,\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t);\n\n\treturn server;\n}\n","/**\n * @fabricorg/sdk-mcp/stdio\n *\n * Convenience entry: runs a stdio MCP server using `FABRIC_API_KEY`\n * (and optional `FABRIC_BASE_URL` / `FABRIC_ORG`) from the environment.\n *\n * Designed to be exec'd by an MCP client (Claude Desktop, Cursor, etc.).\n * The `fabric mcp serve` CLI command is the recommended invocation; this\n * file is the underlying script.\n *\n * Stdout is reserved for the JSON-RPC framing — log only to stderr.\n */\n\nimport { createFabric } from \"@fabricorg/sdk\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createFabricMcpServer } from \"./index.js\";\n\nexport async function runStdio(): Promise<void> {\n\tconst fabric = createFabric({});\n\tconst server = createFabricMcpServer({ fabric });\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n\tprocess.stderr.write(\"[fabric-mcp] stdio transport connected\\n\");\n}\n\n// When invoked directly (node dist/stdio.js), kick off the server.\nconst isDirectInvocation =\n\ttypeof process !== \"undefined\" &&\n\tArray.isArray(process.argv) &&\n\tprocess.argv[1] !== undefined &&\n\t(process.argv[1].endsWith(\"stdio.js\") ||\n\t\tprocess.argv[1].endsWith(\"stdio.cjs\"));\n\nif (isDirectInvocation) {\n\trunStdio().catch((err) => {\n\t\tprocess.stderr.write(\n\t\t\t`[fabric-mcp] fatal: ${err instanceof Error ? err.message : String(err)}\\n`,\n\t\t);\n\t\tprocess.exit(1);\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"stdio.cjs","names":["createFabric","createFabricMcpServer","StdioServerTransport"],"sources":["../src/stdio.ts"],"sourcesContent":["/**\n * @fabricorg/sdk-mcp/stdio\n *\n * Convenience entry: runs a stdio MCP server using `FABRIC_API_KEY`\n * (and optional `FABRIC_BASE_URL` / `FABRIC_ORG`) from the environment.\n *\n * Designed to be exec'd by an MCP client (Claude Desktop, Cursor, etc.).\n * The `fabric mcp serve` CLI command is the recommended invocation; this\n * file is the underlying script.\n *\n * Stdout is reserved for the JSON-RPC framing — log only to stderr.\n */\n\nimport { createFabric } from \"@fabricorg/sdk\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { createFabricMcpServer } from \"./index.js\";\n\nexport async function runStdio(): Promise<void> {\n\tconst fabric = createFabric({});\n\tconst server = createFabricMcpServer({ fabric });\n\tconst transport = new StdioServerTransport();\n\tawait server.connect(transport);\n\tprocess.stderr.write(\"[fabric-mcp] stdio transport connected\\n\");\n}\n\n// When invoked directly (node dist/stdio.js), kick off the server.\nconst isDirectInvocation =\n\ttypeof process !== \"undefined\" &&\n\tArray.isArray(process.argv) &&\n\tprocess.argv[1] !== undefined &&\n\t(process.argv[1].endsWith(\"stdio.js\") ||\n\t\tprocess.argv[1].endsWith(\"stdio.cjs\"));\n\nif (isDirectInvocation) {\n\trunStdio().catch((err) => {\n\t\tprocess.stderr.write(\n\t\t\t`[fabric-mcp] fatal: ${err instanceof Error ? err.message : String(err)}\\n`,\n\t\t);\n\t\tprocess.exit(1);\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,SAAsB,WAAA;;;;CAA0B,YAAA,YAAA,kBAAA,aAAA;EAC/C,MAAM,UAAA,GAASA,eAAAA,aAAAA,CAAa,CAAC,CAAC;EAC9B,MAAM,SAASC,YAAAA,sBAAsB,EAAE,OAAO,CAAC;EAC/C,MAAM,YAAY,IAAIC,0CAAAA,qBAAqB;EAC3C,MAAM,OAAO,QAAQ,SAAS;EAC9B,QAAQ,OAAO,MAAM,0CAA0C;CAChE,CAAA;;;AAUA,IANC,OAAO,YAAY,eACnB,MAAM,QAAQ,QAAQ,IAAI,KAC1B,QAAQ,KAAK,OAAO,KAAA,MACnB,QAAQ,KAAK,EAAE,CAAC,SAAS,UAAU,KACnC,QAAQ,KAAK,EAAE,CAAC,SAAS,WAAW,IAGrC,SAAS,CAAC,CAAC,OAAO,QAAQ;CACzB,QAAQ,OAAO,MACd,uBAAuB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,EAAE,GACzE;CACA,QAAQ,KAAK,CAAC;AACf,CAAC"}
|
package/dist/stdio.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/stdio.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* @fabricorg/sdk-mcp/stdio
|
|
3
4
|
*
|
|
@@ -10,6 +11,6 @@
|
|
|
10
11
|
*
|
|
11
12
|
* Stdout is reserved for the JSON-RPC framing — log only to stderr.
|
|
12
13
|
*/
|
|
13
|
-
declare function runStdio(): Promise<void>;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export declare function runStdio(): Promise<void>;
|
|
15
|
+
//#endregion
|
|
16
|
+
//# sourceMappingURL=stdio.d.cts.map
|
package/dist/stdio.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//#region src/stdio.d.ts
|
|
1
2
|
/**
|
|
2
3
|
* @fabricorg/sdk-mcp/stdio
|
|
3
4
|
*
|
|
@@ -10,6 +11,6 @@
|
|
|
10
11
|
*
|
|
11
12
|
* Stdout is reserved for the JSON-RPC framing — log only to stderr.
|
|
12
13
|
*/
|
|
13
|
-
declare function runStdio(): Promise<void>;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export declare function runStdio(): Promise<void>;
|
|
15
|
+
//#endregion
|
|
16
|
+
//# sourceMappingURL=stdio.d.ts.map
|
package/dist/stdio.js
CHANGED
|
@@ -1,166 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
step(generator.throw(value));
|
|
18
|
-
} catch (e) {
|
|
19
|
-
reject(e);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
23
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
24
|
-
});
|
|
25
|
-
};
|
|
26
|
-
function createFabricMcpServer(options) {
|
|
27
|
-
var _a, _b;
|
|
28
|
-
const fabric = options.fabric;
|
|
29
|
-
const server = new McpServer({
|
|
30
|
-
name: (_a = options.name) != null ? _a : "fabric",
|
|
31
|
-
version: (_b = options.version) != null ? _b : "0.1.0"
|
|
32
|
-
});
|
|
33
|
-
server.registerTool(
|
|
34
|
-
"fabric_list_integrations",
|
|
35
|
-
{
|
|
36
|
-
title: "List Fabric Integrations",
|
|
37
|
-
description: "List integrations connected for the authenticated Fabric workspace. Returns slug, display name, current connection status, permission mode (open/cautious/strict/readonly), and source (plugin/mcp-server/connector).",
|
|
38
|
-
inputSchema: {}
|
|
39
|
-
},
|
|
40
|
-
() => __async(null, null, function* () {
|
|
41
|
-
const integrations = yield fabric.integrations.list();
|
|
42
|
-
return {
|
|
43
|
-
content: [
|
|
44
|
-
{
|
|
45
|
-
type: "text",
|
|
46
|
-
text: JSON.stringify(integrations, null, 2)
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
};
|
|
50
|
-
})
|
|
51
|
-
);
|
|
52
|
-
server.registerTool(
|
|
53
|
-
"fabric_list_operations",
|
|
54
|
-
{
|
|
55
|
-
title: "List Operations for an Integration",
|
|
56
|
-
description: "List the dot-notation operations available on a single Fabric integration. Returns an array of `{ operation, riskLevel, description }`. Supply the slug from `fabric_list_integrations`.",
|
|
57
|
-
inputSchema: {
|
|
58
|
-
slug: z.string().describe(
|
|
59
|
-
'Integration slug, e.g. "slack", "github", "linear".'
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
(_0) => __async(null, [_0], function* ({ slug }) {
|
|
64
|
-
var _a2;
|
|
65
|
-
const integration = fabric.integrations[slug];
|
|
66
|
-
if (!integration) {
|
|
67
|
-
return {
|
|
68
|
-
content: [
|
|
69
|
-
{
|
|
70
|
-
type: "text",
|
|
71
|
-
text: `Integration "${slug}" is not registered for this workspace.`
|
|
72
|
-
}
|
|
73
|
-
],
|
|
74
|
-
isError: true
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
try {
|
|
78
|
-
const ops = yield (_a2 = integration.call) == null ? void 0 : _a2.call(integration, "__operations");
|
|
79
|
-
return {
|
|
80
|
-
content: [
|
|
81
|
-
{ type: "text", text: JSON.stringify(ops, null, 2) }
|
|
82
|
-
]
|
|
83
|
-
};
|
|
84
|
-
} catch (e) {
|
|
85
|
-
return {
|
|
86
|
-
content: [
|
|
87
|
-
{
|
|
88
|
-
type: "text",
|
|
89
|
-
text: `Operation listing for "${slug}" requires portal endpoint /api/v1/integrations/${slug}/operations (not yet exposed). Use fabric_call with a known operation path in the meantime.`
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
server.registerTool(
|
|
97
|
-
"fabric_call",
|
|
98
|
-
{
|
|
99
|
-
title: "Call a Fabric Integration Operation",
|
|
100
|
-
description: "Execute an operation on a connected Fabric integration. Args is a JSON object whose shape depends on the specific operation. Returns the upstream response, or { status: 'pending_approval' | 'denied' } when the workspace permission policy gates the call.",
|
|
101
|
-
inputSchema: {
|
|
102
|
-
slug: z.string().describe('Integration slug, e.g. "slack".'),
|
|
103
|
-
operation: z.string().describe(
|
|
104
|
-
'Dot-notation operation, e.g. "messages.send" or "channels.list".'
|
|
105
|
-
),
|
|
106
|
-
args: z.record(z.string(), z.unknown()).optional().describe(
|
|
107
|
-
"Arguments object. Shape depends on the operation."
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
(_0) => __async(null, [_0], function* ({ slug, operation, args }) {
|
|
112
|
-
const integration = fabric.integrations[slug];
|
|
113
|
-
if (!(integration == null ? void 0 : integration.call)) {
|
|
114
|
-
return {
|
|
115
|
-
content: [
|
|
116
|
-
{
|
|
117
|
-
type: "text",
|
|
118
|
-
text: `Integration "${slug}" is not registered for this workspace.`
|
|
119
|
-
}
|
|
120
|
-
],
|
|
121
|
-
isError: true
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
try {
|
|
125
|
-
const result = yield integration.call(operation, args != null ? args : {});
|
|
126
|
-
return {
|
|
127
|
-
content: [
|
|
128
|
-
{ type: "text", text: JSON.stringify(result, null, 2) }
|
|
129
|
-
]
|
|
130
|
-
};
|
|
131
|
-
} catch (err) {
|
|
132
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
133
|
-
return {
|
|
134
|
-
content: [{ type: "text", text: `Error: ${message}` }],
|
|
135
|
-
isError: true
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
})
|
|
139
|
-
);
|
|
140
|
-
return server;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// src/stdio.ts
|
|
1
|
+
import { n as _asyncToGenerator, t as createFabricMcpServer } from "./src-OoM54hoY.js";
|
|
2
|
+
import { createFabric } from "@fabricorg/sdk";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
//#region src/stdio.ts
|
|
5
|
+
/**
|
|
6
|
+
* @fabricorg/sdk-mcp/stdio
|
|
7
|
+
*
|
|
8
|
+
* Convenience entry: runs a stdio MCP server using `FABRIC_API_KEY`
|
|
9
|
+
* (and optional `FABRIC_BASE_URL` / `FABRIC_ORG`) from the environment.
|
|
10
|
+
*
|
|
11
|
+
* Designed to be exec'd by an MCP client (Claude Desktop, Cursor, etc.).
|
|
12
|
+
* The `fabric mcp serve` CLI command is the recommended invocation; this
|
|
13
|
+
* file is the underlying script.
|
|
14
|
+
*
|
|
15
|
+
* Stdout is reserved for the JSON-RPC framing — log only to stderr.
|
|
16
|
+
*/
|
|
144
17
|
function runStdio() {
|
|
145
|
-
|
|
146
|
-
const fabric = createFabric({});
|
|
147
|
-
const server = createFabricMcpServer({ fabric });
|
|
148
|
-
const transport = new StdioServerTransport();
|
|
149
|
-
yield server.connect(transport);
|
|
150
|
-
process.stderr.write("[fabric-mcp] stdio transport connected\n");
|
|
151
|
-
});
|
|
18
|
+
return _runStdio.apply(this, arguments);
|
|
152
19
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
20
|
+
function _runStdio() {
|
|
21
|
+
_runStdio = _asyncToGenerator(function* () {
|
|
22
|
+
const fabric = createFabric({});
|
|
23
|
+
const server = createFabricMcpServer({ fabric });
|
|
24
|
+
const transport = new StdioServerTransport();
|
|
25
|
+
yield server.connect(transport);
|
|
26
|
+
process.stderr.write("[fabric-mcp] stdio transport connected\n");
|
|
27
|
+
});
|
|
28
|
+
return _runStdio.apply(this, arguments);
|
|
162
29
|
}
|
|
163
|
-
|
|
30
|
+
if (typeof process !== "undefined" && Array.isArray(process.argv) && process.argv[1] !== void 0 && (process.argv[1].endsWith("stdio.js") || process.argv[1].endsWith("stdio.cjs"))) runStdio().catch((err) => {
|
|
31
|
+
process.stderr.write(`[fabric-mcp] fatal: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
});
|
|
34
|
+
//#endregion
|
|
164
35
|
export { runStdio };
|
|
165
|
-
|
|
36
|
+
|
|
166
37
|
//# sourceMappingURL=stdio.js.map
|