@muxoai/platform 1.2.1 → 1.2.3
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/.agents/plugins/marketplace.json +22 -0
- package/.claude-plugin/marketplace.json +17 -0
- package/.codex/config.toml +5 -0
- package/README.md +48 -28
- package/dist/cli.js +69 -20
- package/dist/engine.js +25 -15
- package/dist/mcp.d.ts +36 -0
- package/dist/mcp.js +522 -17
- package/dist/providers/composio-instant.js +442 -0
- package/dist/providers/composio-sdk.js +88 -30
- package/dist/providers/stripe-projects.js +43 -14
- package/dist/sdk.d.ts +67 -5
- package/dist/sdk.js +117 -10
- package/dist/server.js +359 -13
- package/package.json +4 -1
- package/plugins/muxo/.claude-plugin/plugin.json +2 -2
- package/plugins/muxo/.codex-plugin/plugin.json +12 -8
- package/plugins/muxo/.mcp.json +33 -1
- package/plugins/muxo/mcp.json +38 -0
- package/plugins/muxo/plugin.json +59 -0
- package/plugins/muxo/skills/setup/SKILL.md +28 -0
package/dist/mcp.js
CHANGED
|
@@ -1,23 +1,68 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { ROOT_DIR } from "./config.js";
|
|
5
|
+
/**
|
|
6
|
+
* Concise server instructions (<512 chars) per OpenAI Plugin MCP Server specification:
|
|
7
|
+
* https://developers.openai.com/plugins/build/mcp-server
|
|
8
|
+
*/
|
|
9
|
+
export const MUXO_MCP_SERVER_INSTRUCTIONS = "Muxo governs SaaS actions (Composio app.*), Instant tools (instant.*), Cloud Infrastructure (Stripe Projects resource.*), Supermemory v5 recall, and Microsoft Agent Governance Ed25519 receipts. Workflow: 1) search_tools & inspect_tool. 2) plan_action to get a plan_*. 3) If authHandoff.required is true, show redirectUrl and call wait_for_connection. 4) Execute via the matching risk tool (execute_read/write/admin/financial/provisioning/destructive). 5) Verify via get_receipt.";
|
|
1
10
|
export const MUXO_MCP_TOOLS = [
|
|
2
11
|
{
|
|
3
12
|
name: "get_profile",
|
|
4
|
-
|
|
5
|
-
|
|
13
|
+
title: "Get Authenticated Profile",
|
|
14
|
+
description: "Get the authenticated actor profile, user ID, email, workspace ID, and subscription tier.",
|
|
15
|
+
inputSchema: {
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {},
|
|
18
|
+
additionalProperties: false,
|
|
19
|
+
},
|
|
20
|
+
outputSchema: {
|
|
21
|
+
type: "object",
|
|
22
|
+
properties: {
|
|
23
|
+
id: { type: "string", description: "Unique user identifier" },
|
|
24
|
+
name: { type: "string", description: "Display name" },
|
|
25
|
+
email: { type: "string", description: "Email address" },
|
|
26
|
+
workspaceId: { type: "string", description: "Active workspace ID" },
|
|
27
|
+
workspaceName: { type: "string", description: "Active workspace name" },
|
|
28
|
+
tier: { type: "string", description: "Workspace subscription tier" },
|
|
29
|
+
},
|
|
30
|
+
required: ["id"],
|
|
31
|
+
},
|
|
32
|
+
annotations: {
|
|
33
|
+
readOnlyHint: true,
|
|
34
|
+
destructiveHint: false,
|
|
35
|
+
openWorldHint: false,
|
|
36
|
+
},
|
|
37
|
+
_meta: {
|
|
38
|
+
"openai/profile": true,
|
|
39
|
+
},
|
|
6
40
|
},
|
|
7
41
|
{
|
|
8
42
|
name: "get_organization",
|
|
9
|
-
|
|
10
|
-
|
|
43
|
+
title: "Get Organization & Billing Summary",
|
|
44
|
+
description: "Get workspace governance policy, monthly action usage, credit balance, Merchant-of-Record supplier settlement summary, and active connection/resource counts.",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {},
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
},
|
|
50
|
+
annotations: {
|
|
51
|
+
readOnlyHint: true,
|
|
52
|
+
destructiveHint: false,
|
|
53
|
+
openWorldHint: false,
|
|
54
|
+
},
|
|
11
55
|
},
|
|
12
56
|
{
|
|
13
57
|
name: "search_tools",
|
|
58
|
+
title: "Search Unified Tool Catalog",
|
|
14
59
|
description: "Search the unified Muxo catalog across Connected Apps (Composio SDK: app.*), Instant Tools (Composio Instant: instant.*), and Cloud Infrastructure (Stripe Projects: resource.*).",
|
|
15
60
|
inputSchema: {
|
|
16
61
|
type: "object",
|
|
17
62
|
properties: {
|
|
18
63
|
query: {
|
|
19
64
|
type: "string",
|
|
20
|
-
description: "Search keywords (e.g. 'postgres', 'github issue', 'web search', 'redis')",
|
|
65
|
+
description: "Search keywords (e.g. 'postgres', 'github issue', 'web search', 'seo audit', 'redis')",
|
|
21
66
|
},
|
|
22
67
|
lane: {
|
|
23
68
|
type: "string",
|
|
@@ -26,35 +71,56 @@ export const MUXO_MCP_TOOLS = [
|
|
|
26
71
|
},
|
|
27
72
|
risk_level: {
|
|
28
73
|
type: "string",
|
|
29
|
-
enum: [
|
|
74
|
+
enum: [
|
|
75
|
+
"read",
|
|
76
|
+
"write",
|
|
77
|
+
"admin",
|
|
78
|
+
"financial",
|
|
79
|
+
"provisioning",
|
|
80
|
+
"destructive",
|
|
81
|
+
],
|
|
30
82
|
},
|
|
31
83
|
limit: { type: "number", default: 20 },
|
|
32
84
|
},
|
|
85
|
+
additionalProperties: false,
|
|
86
|
+
},
|
|
87
|
+
annotations: {
|
|
88
|
+
readOnlyHint: true,
|
|
89
|
+
destructiveHint: false,
|
|
90
|
+
openWorldHint: true,
|
|
33
91
|
},
|
|
34
92
|
},
|
|
35
93
|
{
|
|
36
94
|
name: "inspect_tool",
|
|
37
|
-
|
|
95
|
+
title: "Inspect Tool Schema & Risk",
|
|
96
|
+
description: "Inspect a tool's full input JSON schema, risk classification, provider lane, LLM context URL, and credit cost before planning.",
|
|
38
97
|
inputSchema: {
|
|
39
98
|
type: "object",
|
|
40
99
|
required: ["tool_slug"],
|
|
41
100
|
properties: {
|
|
42
101
|
tool_slug: {
|
|
43
102
|
type: "string",
|
|
44
|
-
description: "Canonical Muxo tool slug (e.g. 'instant.
|
|
103
|
+
description: "Canonical Muxo tool slug (e.g. 'instant.seo.audit', 'app.gmail.send_email', or 'resource.turso.database')",
|
|
45
104
|
},
|
|
46
105
|
},
|
|
106
|
+
additionalProperties: false,
|
|
107
|
+
},
|
|
108
|
+
annotations: {
|
|
109
|
+
readOnlyHint: true,
|
|
110
|
+
destructiveHint: false,
|
|
111
|
+
openWorldHint: false,
|
|
47
112
|
},
|
|
48
113
|
},
|
|
49
114
|
{
|
|
50
115
|
name: "connection_status",
|
|
116
|
+
title: "Check Connection Status",
|
|
51
117
|
description: "Check connection status across Composio OAuth apps, Instant wallet, and linked Stripe Projects cloud providers.",
|
|
52
118
|
inputSchema: {
|
|
53
119
|
type: "object",
|
|
54
120
|
properties: {
|
|
55
121
|
provider: {
|
|
56
122
|
type: "string",
|
|
57
|
-
description: "Optional provider filter (e.g. 'github', 'slack', 'neon', '
|
|
123
|
+
description: "Optional provider filter (e.g. 'github', 'gmail', 'slack', 'neon', 'turso')",
|
|
58
124
|
},
|
|
59
125
|
sync_live: {
|
|
60
126
|
type: "boolean",
|
|
@@ -62,11 +128,18 @@ export const MUXO_MCP_TOOLS = [
|
|
|
62
128
|
description: "Whether to sync live status from upstream Composio and Stripe Projects",
|
|
63
129
|
},
|
|
64
130
|
},
|
|
131
|
+
additionalProperties: false,
|
|
132
|
+
},
|
|
133
|
+
annotations: {
|
|
134
|
+
readOnlyHint: true,
|
|
135
|
+
destructiveHint: false,
|
|
136
|
+
openWorldHint: true,
|
|
65
137
|
},
|
|
66
138
|
},
|
|
67
139
|
{
|
|
68
140
|
name: "start_connection",
|
|
69
|
-
|
|
141
|
+
title: "Start OAuth Connection Handoff",
|
|
142
|
+
description: "Initiate a managed OAuth connection handoff for a Connected App (Composio) or link a cloud provider (Stripe Projects).",
|
|
70
143
|
inputSchema: {
|
|
71
144
|
type: "object",
|
|
72
145
|
required: ["provider"],
|
|
@@ -85,10 +158,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
85
158
|
description: "Optional OAuth callback URL",
|
|
86
159
|
},
|
|
87
160
|
},
|
|
161
|
+
additionalProperties: false,
|
|
162
|
+
},
|
|
163
|
+
annotations: {
|
|
164
|
+
readOnlyHint: false,
|
|
165
|
+
destructiveHint: false,
|
|
166
|
+
openWorldHint: true,
|
|
88
167
|
},
|
|
89
168
|
},
|
|
90
169
|
{
|
|
91
170
|
name: "wait_for_connection",
|
|
171
|
+
title: "Wait for OAuth Connection Handoff",
|
|
92
172
|
description: "Poll and wait for an external user's pending OAuth connection handoff to become active before resuming a planned operation.",
|
|
93
173
|
inputSchema: {
|
|
94
174
|
type: "object",
|
|
@@ -104,11 +184,18 @@ export const MUXO_MCP_TOOLS = [
|
|
|
104
184
|
description: "Maximum seconds to poll for OAuth completion (0-120, default 15)",
|
|
105
185
|
},
|
|
106
186
|
},
|
|
187
|
+
additionalProperties: false,
|
|
188
|
+
},
|
|
189
|
+
annotations: {
|
|
190
|
+
readOnlyHint: true,
|
|
191
|
+
destructiveHint: false,
|
|
192
|
+
openWorldHint: true,
|
|
107
193
|
},
|
|
108
194
|
},
|
|
109
195
|
{
|
|
110
196
|
name: "plan_action",
|
|
111
|
-
|
|
197
|
+
title: "Create Governed Action Plan",
|
|
198
|
+
description: "Create a governed execution plan (plan_*) for any tool or infrastructure provisioning operation. Evaluates workspace policy, risk level, Supermemory v5 recall, Ed25519 signature, and credit balance.",
|
|
112
199
|
inputSchema: {
|
|
113
200
|
type: "object",
|
|
114
201
|
required: ["tool_slug"],
|
|
@@ -123,21 +210,35 @@ export const MUXO_MCP_TOOLS = [
|
|
|
123
210
|
description: "Audit reason explaining why this action is being planned",
|
|
124
211
|
},
|
|
125
212
|
},
|
|
213
|
+
additionalProperties: false,
|
|
214
|
+
},
|
|
215
|
+
annotations: {
|
|
216
|
+
readOnlyHint: false,
|
|
217
|
+
destructiveHint: false,
|
|
218
|
+
openWorldHint: false,
|
|
126
219
|
},
|
|
127
220
|
},
|
|
128
221
|
{
|
|
129
222
|
name: "get_plan",
|
|
130
|
-
|
|
223
|
+
title: "Get Action Plan",
|
|
224
|
+
description: "Inspect the status, risk level, governance decision record, and approval state of a planned action.",
|
|
131
225
|
inputSchema: {
|
|
132
226
|
type: "object",
|
|
133
227
|
required: ["plan_id"],
|
|
134
228
|
properties: {
|
|
135
229
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
136
230
|
},
|
|
231
|
+
additionalProperties: false,
|
|
232
|
+
},
|
|
233
|
+
annotations: {
|
|
234
|
+
readOnlyHint: true,
|
|
235
|
+
destructiveHint: false,
|
|
236
|
+
openWorldHint: false,
|
|
137
237
|
},
|
|
138
238
|
},
|
|
139
239
|
{
|
|
140
240
|
name: "get_run_context",
|
|
241
|
+
title: "Get Workspace Context & Memory",
|
|
141
242
|
description: "Get the workspace runtime context, Supermemory v5 contextual brain (static/dynamic profile + hybrid search recall), Microsoft Agent Governance status, active provisioned Stripe Projects resources, and redacted environment variable keys.",
|
|
142
243
|
inputSchema: {
|
|
143
244
|
type: "object",
|
|
@@ -147,10 +248,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
147
248
|
description: "Optional semantic search query to recall relevant workspace memories from Supermemory v5",
|
|
148
249
|
},
|
|
149
250
|
},
|
|
251
|
+
additionalProperties: false,
|
|
252
|
+
},
|
|
253
|
+
annotations: {
|
|
254
|
+
readOnlyHint: true,
|
|
255
|
+
destructiveHint: false,
|
|
256
|
+
openWorldHint: false,
|
|
150
257
|
},
|
|
151
258
|
},
|
|
152
259
|
{
|
|
153
260
|
name: "execute_read",
|
|
261
|
+
title: "Execute Read Plan",
|
|
154
262
|
description: "Execute an approved plan with riskLevel = 'read'.",
|
|
155
263
|
inputSchema: {
|
|
156
264
|
type: "object",
|
|
@@ -158,10 +266,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
158
266
|
properties: {
|
|
159
267
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
160
268
|
},
|
|
269
|
+
additionalProperties: false,
|
|
270
|
+
},
|
|
271
|
+
annotations: {
|
|
272
|
+
readOnlyHint: true,
|
|
273
|
+
destructiveHint: false,
|
|
274
|
+
openWorldHint: true,
|
|
161
275
|
},
|
|
162
276
|
},
|
|
163
277
|
{
|
|
164
278
|
name: "execute_write",
|
|
279
|
+
title: "Execute Write Plan",
|
|
165
280
|
description: "Execute an approved plan with riskLevel = 'write'.",
|
|
166
281
|
inputSchema: {
|
|
167
282
|
type: "object",
|
|
@@ -169,10 +284,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
169
284
|
properties: {
|
|
170
285
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
171
286
|
},
|
|
287
|
+
additionalProperties: false,
|
|
288
|
+
},
|
|
289
|
+
annotations: {
|
|
290
|
+
readOnlyHint: false,
|
|
291
|
+
destructiveHint: false,
|
|
292
|
+
openWorldHint: true,
|
|
172
293
|
},
|
|
173
294
|
},
|
|
174
295
|
{
|
|
175
296
|
name: "execute_admin",
|
|
297
|
+
title: "Execute Admin Plan",
|
|
176
298
|
description: "Execute an approved plan with riskLevel = 'admin'.",
|
|
177
299
|
inputSchema: {
|
|
178
300
|
type: "object",
|
|
@@ -180,10 +302,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
180
302
|
properties: {
|
|
181
303
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
182
304
|
},
|
|
305
|
+
additionalProperties: false,
|
|
306
|
+
},
|
|
307
|
+
annotations: {
|
|
308
|
+
readOnlyHint: false,
|
|
309
|
+
destructiveHint: false,
|
|
310
|
+
openWorldHint: true,
|
|
183
311
|
},
|
|
184
312
|
},
|
|
185
313
|
{
|
|
186
314
|
name: "execute_financial",
|
|
315
|
+
title: "Execute Financial Plan",
|
|
187
316
|
description: "Execute an approved plan with riskLevel = 'financial'.",
|
|
188
317
|
inputSchema: {
|
|
189
318
|
type: "object",
|
|
@@ -191,10 +320,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
191
320
|
properties: {
|
|
192
321
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
193
322
|
},
|
|
323
|
+
additionalProperties: false,
|
|
324
|
+
},
|
|
325
|
+
annotations: {
|
|
326
|
+
readOnlyHint: false,
|
|
327
|
+
destructiveHint: false,
|
|
328
|
+
openWorldHint: true,
|
|
194
329
|
},
|
|
195
330
|
},
|
|
196
331
|
{
|
|
197
332
|
name: "execute_provisioning",
|
|
333
|
+
title: "Execute Infrastructure Provisioning Plan",
|
|
198
334
|
description: "Execute an approved infrastructure provisioning plan with riskLevel = 'provisioning' via Stripe Projects.",
|
|
199
335
|
inputSchema: {
|
|
200
336
|
type: "object",
|
|
@@ -202,10 +338,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
202
338
|
properties: {
|
|
203
339
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
204
340
|
},
|
|
341
|
+
additionalProperties: false,
|
|
342
|
+
},
|
|
343
|
+
annotations: {
|
|
344
|
+
readOnlyHint: false,
|
|
345
|
+
destructiveHint: false,
|
|
346
|
+
openWorldHint: true,
|
|
205
347
|
},
|
|
206
348
|
},
|
|
207
349
|
{
|
|
208
350
|
name: "execute_destructive",
|
|
351
|
+
title: "Execute Destructive Plan",
|
|
209
352
|
description: "Execute an approved plan with riskLevel = 'destructive'.",
|
|
210
353
|
inputSchema: {
|
|
211
354
|
type: "object",
|
|
@@ -213,10 +356,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
213
356
|
properties: {
|
|
214
357
|
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
215
358
|
},
|
|
359
|
+
additionalProperties: false,
|
|
360
|
+
},
|
|
361
|
+
annotations: {
|
|
362
|
+
readOnlyHint: false,
|
|
363
|
+
destructiveHint: true,
|
|
364
|
+
openWorldHint: true,
|
|
216
365
|
},
|
|
217
366
|
},
|
|
218
367
|
{
|
|
219
368
|
name: "get_run",
|
|
369
|
+
title: "Get Execution Run",
|
|
220
370
|
description: "Get the execution status, output, duration, and metered cost of a run (run_*).",
|
|
221
371
|
inputSchema: {
|
|
222
372
|
type: "object",
|
|
@@ -224,10 +374,17 @@ export const MUXO_MCP_TOOLS = [
|
|
|
224
374
|
properties: {
|
|
225
375
|
run_id: { type: "string", description: "Run ID (run_*)" },
|
|
226
376
|
},
|
|
377
|
+
additionalProperties: false,
|
|
378
|
+
},
|
|
379
|
+
annotations: {
|
|
380
|
+
readOnlyHint: true,
|
|
381
|
+
destructiveHint: false,
|
|
382
|
+
openWorldHint: false,
|
|
227
383
|
},
|
|
228
384
|
},
|
|
229
385
|
{
|
|
230
386
|
name: "cancel_run",
|
|
387
|
+
title: "Cancel Execution Run",
|
|
231
388
|
description: "Cancel an in-progress run and issue a cancellation receipt.",
|
|
232
389
|
inputSchema: {
|
|
233
390
|
type: "object",
|
|
@@ -235,11 +392,18 @@ export const MUXO_MCP_TOOLS = [
|
|
|
235
392
|
properties: {
|
|
236
393
|
run_id: { type: "string", description: "Run ID (run_*)" },
|
|
237
394
|
},
|
|
395
|
+
additionalProperties: false,
|
|
396
|
+
},
|
|
397
|
+
annotations: {
|
|
398
|
+
readOnlyHint: false,
|
|
399
|
+
destructiveHint: true,
|
|
400
|
+
openWorldHint: false,
|
|
238
401
|
},
|
|
239
402
|
},
|
|
240
403
|
{
|
|
241
404
|
name: "get_receipt",
|
|
242
|
-
|
|
405
|
+
title: "Verify Execution Receipt",
|
|
406
|
+
description: "Fetch and cryptographically verify the HMAC-SHA256 + Ed25519 chained execution receipt (rcpt_*) for a run.",
|
|
243
407
|
inputSchema: {
|
|
244
408
|
type: "object",
|
|
245
409
|
required: ["receipt_id"],
|
|
@@ -249,9 +413,185 @@ export const MUXO_MCP_TOOLS = [
|
|
|
249
413
|
description: "Receipt ID (rcpt_*) or Run ID (run_*)",
|
|
250
414
|
},
|
|
251
415
|
},
|
|
416
|
+
additionalProperties: false,
|
|
417
|
+
},
|
|
418
|
+
annotations: {
|
|
419
|
+
readOnlyHint: true,
|
|
420
|
+
destructiveHint: false,
|
|
421
|
+
openWorldHint: false,
|
|
252
422
|
},
|
|
253
423
|
},
|
|
254
424
|
];
|
|
425
|
+
/**
|
|
426
|
+
* OpenAI Company Knowledge standard `search` and `fetch` tool definitions
|
|
427
|
+
* per https://developers.openai.com/plugins/build/mcp-server#company-knowledge-compatibility
|
|
428
|
+
*/
|
|
429
|
+
export const OPENAI_COMPANY_KNOWLEDGE_TOOLS = [
|
|
430
|
+
{
|
|
431
|
+
name: "search",
|
|
432
|
+
title: "Search Muxo Tools & Workspace Memory",
|
|
433
|
+
description: "Search across Muxo tools, provisioned cloud resources, and Supermemory v5 workspace knowledge.",
|
|
434
|
+
inputSchema: {
|
|
435
|
+
type: "object",
|
|
436
|
+
required: ["query"],
|
|
437
|
+
properties: {
|
|
438
|
+
query: { type: "string", description: "Search query string." },
|
|
439
|
+
},
|
|
440
|
+
additionalProperties: false,
|
|
441
|
+
},
|
|
442
|
+
annotations: {
|
|
443
|
+
readOnlyHint: true,
|
|
444
|
+
destructiveHint: false,
|
|
445
|
+
openWorldHint: false,
|
|
446
|
+
},
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
name: "fetch",
|
|
450
|
+
title: "Fetch Muxo Tool or Memory Record",
|
|
451
|
+
description: "Retrieve complete details for a Muxo tool, resource, or workspace memory record by ID.",
|
|
452
|
+
inputSchema: {
|
|
453
|
+
type: "object",
|
|
454
|
+
required: ["id"],
|
|
455
|
+
properties: {
|
|
456
|
+
id: {
|
|
457
|
+
type: "string",
|
|
458
|
+
description: "Identifier returned by search (e.g. 'tool:instant.seo.audit' or 'memory:mem_123').",
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
additionalProperties: false,
|
|
462
|
+
},
|
|
463
|
+
annotations: {
|
|
464
|
+
readOnlyHint: true,
|
|
465
|
+
destructiveHint: false,
|
|
466
|
+
openWorldHint: false,
|
|
467
|
+
},
|
|
468
|
+
},
|
|
469
|
+
];
|
|
470
|
+
function sha256Digest(content) {
|
|
471
|
+
const hash = crypto
|
|
472
|
+
.createHash("sha256")
|
|
473
|
+
.update(Buffer.from(content, "utf8"))
|
|
474
|
+
.digest("hex");
|
|
475
|
+
return `sha256:${hash}`;
|
|
476
|
+
}
|
|
477
|
+
function parseFrontmatter(markdown) {
|
|
478
|
+
const match = markdown.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
479
|
+
if (!match)
|
|
480
|
+
return {};
|
|
481
|
+
const result = {};
|
|
482
|
+
for (const line of match[1].split(/\r?\n/)) {
|
|
483
|
+
const idx = line.indexOf(":");
|
|
484
|
+
if (idx > 0) {
|
|
485
|
+
const k = line.slice(0, idx).trim();
|
|
486
|
+
const v = line.slice(idx + 1).trim();
|
|
487
|
+
if (k && v)
|
|
488
|
+
result[k] = v;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
}
|
|
493
|
+
function readSkillFileOrDefault(relPath, fallback) {
|
|
494
|
+
try {
|
|
495
|
+
const absPath = path.join(ROOT_DIR, "plugins", "muxo", "skills", relPath);
|
|
496
|
+
if (fs.existsSync(absPath)) {
|
|
497
|
+
return fs.readFileSync(absPath, "utf8");
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
// Fallback to embedded markdown
|
|
502
|
+
}
|
|
503
|
+
return fallback;
|
|
504
|
+
}
|
|
505
|
+
export function getMuxoMcpSkills() {
|
|
506
|
+
const muxoSkillMd = readSkillFileOrDefault("muxo/SKILL.md", `---
|
|
507
|
+
name: muxo
|
|
508
|
+
description: Route governed Muxo work between the hosted MCP-backed app and the local Muxo CLI across Connected Apps (Composio), Instant Tools, Cloud Infrastructure (Stripe Projects), Supermemory v5, and Microsoft Agent Governance.
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
# Muxo
|
|
512
|
+
|
|
513
|
+
Use \`search_tools\`, \`inspect_tool\`, \`plan_action\`, \`wait_for_connection\`, and \`execute_<risk>\` to run governed actions across Connected Apps (\`app.*\`), Instant Tools (\`instant.*\`), and Cloud Infrastructure (\`resource.*\`).
|
|
514
|
+
`);
|
|
515
|
+
const muxoCliMd = readSkillFileOrDefault("muxo/references/cli.md", `# Local Muxo CLI\n\nRun \`muxo login --signup\`, \`muxo search\`, \`muxo link <provider> --wait\`, \`muxo exec\`, and \`muxo env pull\`.`);
|
|
516
|
+
const muxoMcpMd = readSkillFileOrDefault("muxo/references/mcp.md", `# Hosted Muxo MCP App\n\nFollow \`search_tools\` -> \`inspect_tool\` -> \`plan_action\` -> \`wait_for_connection\` -> \`execute_<risk>\` -> \`get_receipt\`.`);
|
|
517
|
+
const setupSkillMd = readSkillFileOrDefault("setup/SKILL.md", `---
|
|
518
|
+
name: setup
|
|
519
|
+
description: Guided onboarding skill for setting up the Muxo plugin in OpenAI ChatGPT and Codex. Helps users verify workspace authorization, connect external SaaS apps via OAuth handoff, provision cloud infrastructure, or install the local Muxo CLI.
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
# Muxo Onboarding & Setup
|
|
523
|
+
|
|
524
|
+
Call \`get_profile\` and \`get_organization\` to verify your workspace connection, or run \`npx -y @muxoai/cli@latest login --signup\` in a terminal.
|
|
525
|
+
`);
|
|
526
|
+
const muxoFm = parseFrontmatter(muxoSkillMd);
|
|
527
|
+
const setupFm = parseFrontmatter(setupSkillMd);
|
|
528
|
+
const muxoFiles = [
|
|
529
|
+
{
|
|
530
|
+
path: "SKILL.md",
|
|
531
|
+
uri: "skill://muxo/muxo/SKILL.md",
|
|
532
|
+
size: Buffer.byteLength(muxoSkillMd, "utf8"),
|
|
533
|
+
digest: sha256Digest(muxoSkillMd),
|
|
534
|
+
mimeType: "text/markdown",
|
|
535
|
+
content: muxoSkillMd,
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
path: "references/cli.md",
|
|
539
|
+
uri: "skill://muxo/muxo/references/cli.md",
|
|
540
|
+
size: Buffer.byteLength(muxoCliMd, "utf8"),
|
|
541
|
+
digest: sha256Digest(muxoCliMd),
|
|
542
|
+
mimeType: "text/markdown",
|
|
543
|
+
content: muxoCliMd,
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
path: "references/mcp.md",
|
|
547
|
+
uri: "skill://muxo/muxo/references/mcp.md",
|
|
548
|
+
size: Buffer.byteLength(muxoMcpMd, "utf8"),
|
|
549
|
+
digest: sha256Digest(muxoMcpMd),
|
|
550
|
+
mimeType: "text/markdown",
|
|
551
|
+
content: muxoMcpMd,
|
|
552
|
+
},
|
|
553
|
+
];
|
|
554
|
+
const setupFiles = [
|
|
555
|
+
{
|
|
556
|
+
path: "SKILL.md",
|
|
557
|
+
uri: "skill://muxo/setup/SKILL.md",
|
|
558
|
+
size: Buffer.byteLength(setupSkillMd, "utf8"),
|
|
559
|
+
digest: sha256Digest(setupSkillMd),
|
|
560
|
+
mimeType: "text/markdown",
|
|
561
|
+
content: setupSkillMd,
|
|
562
|
+
},
|
|
563
|
+
];
|
|
564
|
+
const muxoName = muxoFm.name || "muxo";
|
|
565
|
+
const muxoDesc = muxoFm.description ||
|
|
566
|
+
"Route governed Muxo work between the hosted MCP-backed app and the local Muxo CLI.";
|
|
567
|
+
const setupName = setupFm.name || "setup";
|
|
568
|
+
const setupDesc = setupFm.description ||
|
|
569
|
+
"Guided onboarding skill for setting up the Muxo plugin in OpenAI ChatGPT and Codex.";
|
|
570
|
+
return [
|
|
571
|
+
{
|
|
572
|
+
name: muxoName,
|
|
573
|
+
description: muxoDesc,
|
|
574
|
+
uri: "skill://muxo/muxo/SKILL.md",
|
|
575
|
+
version: muxoFiles[0].digest,
|
|
576
|
+
frontmatter: {
|
|
577
|
+
name: muxoName,
|
|
578
|
+
description: muxoDesc,
|
|
579
|
+
},
|
|
580
|
+
files: muxoFiles,
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
name: setupName,
|
|
584
|
+
description: setupDesc,
|
|
585
|
+
uri: "skill://muxo/setup/SKILL.md",
|
|
586
|
+
version: setupFiles[0].digest,
|
|
587
|
+
frontmatter: {
|
|
588
|
+
name: setupName,
|
|
589
|
+
description: setupDesc,
|
|
590
|
+
},
|
|
591
|
+
files: setupFiles,
|
|
592
|
+
},
|
|
593
|
+
];
|
|
594
|
+
}
|
|
255
595
|
export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
256
596
|
switch (toolName) {
|
|
257
597
|
case "get_profile":
|
|
@@ -313,6 +653,65 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
313
653
|
return engine.cancelRun(ctx, String(args.run_id || ""));
|
|
314
654
|
case "get_receipt":
|
|
315
655
|
return engine.getReceipt(ctx, String(args.receipt_id || args.run_id || ""));
|
|
656
|
+
// OpenAI Company Knowledge standard `search` and `fetch` tool support
|
|
657
|
+
case "search": {
|
|
658
|
+
const q = String(args.query || "").trim();
|
|
659
|
+
const [toolsRes, memRes] = await Promise.all([
|
|
660
|
+
engine.searchTools({ query: q, limit: 10 }),
|
|
661
|
+
engine.getMemoryOverview(ctx, q),
|
|
662
|
+
]);
|
|
663
|
+
const toolHits = toolsRes.tools.map((t) => ({
|
|
664
|
+
id: `tool:${t.slug}`,
|
|
665
|
+
title: `${t.name} (${t.slug})`,
|
|
666
|
+
url: t.providerUrl || `https://docs.muxo.ai/tools/${encodeURIComponent(t.slug)}`,
|
|
667
|
+
snippet: `${t.description} [lane=${t.lane}, risk=${t.riskLevel}, cost=${t.creditCost}cr]`,
|
|
668
|
+
}));
|
|
669
|
+
const memHits = (memRes.memories || []).slice(0, 5).map((m) => ({
|
|
670
|
+
id: `memory:${m.id}`,
|
|
671
|
+
title: m.title,
|
|
672
|
+
url: `https://app.muxo.ai/?memory=${encodeURIComponent(m.id)}`,
|
|
673
|
+
snippet: m.content.slice(0, 240),
|
|
674
|
+
}));
|
|
675
|
+
return {
|
|
676
|
+
results: [...toolHits, ...memHits],
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
case "fetch": {
|
|
680
|
+
const rawId = String(args.id || "").trim();
|
|
681
|
+
const slug = rawId.startsWith("tool:") ? rawId.slice(5) : rawId;
|
|
682
|
+
if (rawId.startsWith("memory:")) {
|
|
683
|
+
const memId = rawId.slice(7);
|
|
684
|
+
const memRes = await engine.getMemoryOverview(ctx);
|
|
685
|
+
const found = (memRes.memories || []).find((m) => m.id === memId);
|
|
686
|
+
if (!found)
|
|
687
|
+
throw new Error(`Memory record not found: ${rawId}`);
|
|
688
|
+
return {
|
|
689
|
+
id: rawId,
|
|
690
|
+
title: found.title,
|
|
691
|
+
text: found.content,
|
|
692
|
+
url: `https://app.muxo.ai/?memory=${encodeURIComponent(found.id)}`,
|
|
693
|
+
metadata: {
|
|
694
|
+
namespace: found.namespace,
|
|
695
|
+
kind: found.kind,
|
|
696
|
+
createdAt: found.createdAt,
|
|
697
|
+
},
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
const tool = await engine.inspectTool(slug);
|
|
701
|
+
return {
|
|
702
|
+
id: `tool:${tool.slug}`,
|
|
703
|
+
title: tool.name,
|
|
704
|
+
text: JSON.stringify(tool, null, 2),
|
|
705
|
+
url: tool.providerUrl ||
|
|
706
|
+
`https://docs.muxo.ai/tools/${encodeURIComponent(tool.slug)}`,
|
|
707
|
+
metadata: {
|
|
708
|
+
slug: tool.slug,
|
|
709
|
+
lane: tool.lane,
|
|
710
|
+
riskLevel: tool.riskLevel,
|
|
711
|
+
creditCost: String(tool.creditCost),
|
|
712
|
+
},
|
|
713
|
+
};
|
|
714
|
+
}
|
|
316
715
|
default:
|
|
317
716
|
throw new Error(`Unknown MCP tool: ${toolName}`);
|
|
318
717
|
}
|
|
@@ -321,22 +720,32 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
321
720
|
const id = rpc.id ?? null;
|
|
322
721
|
const method = String(rpc.method || "");
|
|
323
722
|
const params = (rpc.params || {});
|
|
324
|
-
if (method === "notifications/initialized"
|
|
723
|
+
if (method === "notifications/initialized" ||
|
|
724
|
+
method.startsWith("notifications/")) {
|
|
325
725
|
return null;
|
|
326
726
|
}
|
|
327
727
|
try {
|
|
328
728
|
if (method === "initialize") {
|
|
729
|
+
const requestedProtocol = typeof params.protocolVersion === "string" &&
|
|
730
|
+
params.protocolVersion.trim()
|
|
731
|
+
? params.protocolVersion.trim()
|
|
732
|
+
: "2025-06-18";
|
|
329
733
|
return {
|
|
330
734
|
jsonrpc: "2.0",
|
|
331
735
|
id,
|
|
332
736
|
result: {
|
|
333
|
-
protocolVersion:
|
|
737
|
+
protocolVersion: requestedProtocol,
|
|
738
|
+
instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
|
|
334
739
|
serverInfo: {
|
|
335
740
|
name: "muxo-mcp-server",
|
|
336
|
-
version: "1.
|
|
741
|
+
version: "1.2.3",
|
|
337
742
|
},
|
|
338
743
|
capabilities: {
|
|
339
|
-
tools: {},
|
|
744
|
+
tools: { listChanged: false },
|
|
745
|
+
resources: { listChanged: false },
|
|
746
|
+
extensions: {
|
|
747
|
+
"io.modelcontextprotocol/skills": {},
|
|
748
|
+
},
|
|
340
749
|
},
|
|
341
750
|
},
|
|
342
751
|
};
|
|
@@ -357,10 +766,14 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
357
766
|
const toolName = String(params.name || "");
|
|
358
767
|
const toolArgs = (params.arguments || {});
|
|
359
768
|
const output = await dispatchMcpToolCall(engine, ctx, toolName, toolArgs);
|
|
769
|
+
const structuredContent = output && typeof output === "object" && !Array.isArray(output)
|
|
770
|
+
? output
|
|
771
|
+
: { data: output };
|
|
360
772
|
return {
|
|
361
773
|
jsonrpc: "2.0",
|
|
362
774
|
id,
|
|
363
775
|
result: {
|
|
776
|
+
structuredContent,
|
|
364
777
|
content: [
|
|
365
778
|
{
|
|
366
779
|
type: "text",
|
|
@@ -371,6 +784,98 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
371
784
|
},
|
|
372
785
|
};
|
|
373
786
|
}
|
|
787
|
+
// SEP-2640 Skills Import Extension (`io.modelcontextprotocol/skills`)
|
|
788
|
+
if (method === "skills/list") {
|
|
789
|
+
const skills = getMuxoMcpSkills().map((s) => ({
|
|
790
|
+
name: s.name,
|
|
791
|
+
description: s.description,
|
|
792
|
+
uri: s.uri,
|
|
793
|
+
version: s.version,
|
|
794
|
+
digest: s.files[0]?.digest || "",
|
|
795
|
+
files: s.files.length,
|
|
796
|
+
}));
|
|
797
|
+
return {
|
|
798
|
+
jsonrpc: "2.0",
|
|
799
|
+
id,
|
|
800
|
+
result: { skills },
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
if (method === "skills/get") {
|
|
804
|
+
const requestedName = String(params.name || "muxo").trim();
|
|
805
|
+
const skill = getMuxoMcpSkills().find((s) => s.name === requestedName);
|
|
806
|
+
if (!skill) {
|
|
807
|
+
return {
|
|
808
|
+
jsonrpc: "2.0",
|
|
809
|
+
id,
|
|
810
|
+
error: {
|
|
811
|
+
code: -32602,
|
|
812
|
+
message: `Skill not found: ${requestedName}`,
|
|
813
|
+
},
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
return {
|
|
817
|
+
jsonrpc: "2.0",
|
|
818
|
+
id,
|
|
819
|
+
result: {
|
|
820
|
+
skill: {
|
|
821
|
+
name: skill.name,
|
|
822
|
+
description: skill.description,
|
|
823
|
+
uri: skill.uri,
|
|
824
|
+
version: skill.version,
|
|
825
|
+
digest: skill.files[0]?.digest || "",
|
|
826
|
+
},
|
|
827
|
+
frontmatter: skill.frontmatter,
|
|
828
|
+
files: skill.files.map((f) => ({
|
|
829
|
+
path: f.path,
|
|
830
|
+
uri: f.uri,
|
|
831
|
+
size: f.size,
|
|
832
|
+
digest: f.digest,
|
|
833
|
+
mimeType: f.mimeType,
|
|
834
|
+
})),
|
|
835
|
+
},
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
if (method === "resources/list") {
|
|
839
|
+
const resources = getMuxoMcpSkills().flatMap((s) => s.files.map((f) => ({
|
|
840
|
+
uri: f.uri,
|
|
841
|
+
name: `${s.name}/${f.path}`,
|
|
842
|
+
description: s.description,
|
|
843
|
+
mimeType: f.mimeType,
|
|
844
|
+
})));
|
|
845
|
+
return {
|
|
846
|
+
jsonrpc: "2.0",
|
|
847
|
+
id,
|
|
848
|
+
result: { resources },
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
if (method === "resources/read") {
|
|
852
|
+
const uri = String(params.uri || "").trim();
|
|
853
|
+
const allFiles = getMuxoMcpSkills().flatMap((s) => s.files);
|
|
854
|
+
const found = allFiles.find((f) => f.uri === uri);
|
|
855
|
+
if (!found) {
|
|
856
|
+
return {
|
|
857
|
+
jsonrpc: "2.0",
|
|
858
|
+
id,
|
|
859
|
+
error: {
|
|
860
|
+
code: -32602,
|
|
861
|
+
message: `Resource not found: ${uri}`,
|
|
862
|
+
},
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
return {
|
|
866
|
+
jsonrpc: "2.0",
|
|
867
|
+
id,
|
|
868
|
+
result: {
|
|
869
|
+
contents: [
|
|
870
|
+
{
|
|
871
|
+
uri: found.uri,
|
|
872
|
+
mimeType: found.mimeType,
|
|
873
|
+
text: found.content,
|
|
874
|
+
},
|
|
875
|
+
],
|
|
876
|
+
},
|
|
877
|
+
};
|
|
878
|
+
}
|
|
374
879
|
return {
|
|
375
880
|
jsonrpc: "2.0",
|
|
376
881
|
id,
|