@muxoai/platform 1.4.0 → 1.4.2
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 +2 -2
- package/.claude-plugin/marketplace.json +2 -2
- package/ARCHITECTURE.md +16 -6
- package/README.md +2 -2
- package/dist/cli.js +323 -13
- package/dist/composio-catalog.d.ts +234 -0
- package/dist/composio-catalog.js +1894 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.js +27 -1
- package/dist/durable-workflow.d.ts +45 -0
- package/dist/durable-workflow.js +90 -0
- package/dist/engine.d.ts +293 -5
- package/dist/engine.js +1502 -88
- package/dist/mcp-schema.d.ts +286 -0
- package/dist/mcp-schema.js +2559 -0
- package/dist/mcp.d.ts +2 -30
- package/dist/mcp.js +913 -558
- package/dist/memory-graph.d.ts +21 -0
- package/dist/memory-graph.js +173 -0
- package/dist/nl.js +155 -0
- package/dist/oauth.d.ts +32 -0
- package/dist/oauth.js +134 -0
- package/dist/policy.d.ts +182 -1
- package/dist/policy.js +1524 -0
- package/dist/providers/composio-instant.js +262 -7
- package/dist/providers/composio-sdk.d.ts +125 -5
- package/dist/providers/composio-sdk.js +901 -82
- package/dist/providers/microsoft-governance.d.ts +28 -1
- package/dist/providers/microsoft-governance.js +224 -11
- package/dist/providers/stripe-billing.d.ts +42 -0
- package/dist/providers/stripe-billing.js +230 -1
- package/dist/providers/stripe-projects.d.ts +455 -3
- package/dist/providers/stripe-projects.js +2570 -129
- package/dist/providers/supermemory.d.ts +74 -1
- package/dist/providers/supermemory.js +426 -0
- package/dist/provisioning-managed.d.ts +50 -0
- package/dist/provisioning-managed.js +155 -0
- package/dist/sdk.d.ts +440 -3
- package/dist/sdk.js +305 -3
- package/dist/server.js +2343 -264
- package/dist/store.d.ts +113 -6
- package/dist/store.js +677 -52
- package/dist/types.d.ts +207 -3
- package/dist/ui/console-html.d.ts +40 -1
- package/dist/ui/console-html.js +1813 -629
- package/dist/ui/design-tokens.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -3
- package/plugins/muxo/.claude-plugin/plugin.json +2 -2
- package/plugins/muxo/.codex-plugin/plugin.json +15 -8
- package/plugins/muxo/.cursor-plugin/plugin.json +30 -0
- package/plugins/muxo/hooks/session-start.sh +15 -3
- package/plugins/muxo/hooks/user-prompt-submit.sh +14 -1
- package/plugins/muxo/mcp.json +0 -10
- package/plugins/muxo/plugin.json +4 -4
- package/plugins/muxo/skills/muxo/SKILL.md +59 -9
- package/plugins/muxo/skills/muxo/references/cli.md +5 -1
- package/plugins/muxo/skills/muxo/references/mcp.md +13 -7
- package/plugins/muxo/skills/muxo-activity-summary/SKILL.md +81 -0
- package/plugins/muxo/skills/setup/SKILL.md +9 -1
- package/src/catalogues/stripe-projects-catalog.json +140 -0
package/dist/mcp.js
CHANGED
|
@@ -2,524 +2,9 @@ import crypto from "node:crypto";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { ROOT_DIR } from "./config.js";
|
|
5
|
+
import { APPROVED_PLAN_STATUSES, DEFAULT_LEGACY_MCP_PROTOCOL_VERSION, DEFAULT_TOOL_SECURITY_SCHEMES, LATEST_MCP_PROTOCOL_VERSION, MCP_ERR_HEADER_MISMATCH, MCP_ERR_MISSING_REQUIRED_CLIENT_CAPABILITY, MCP_ERR_UNSUPPORTED_PROTOCOL_VERSION, MUXO_MCP_RESOURCE_TEMPLATES, MUXO_MCP_SERVER_INSTRUCTIONS, MUXO_MCP_TOOLS, MUXO_UI_MCP_APP_URI, MUXO_UI_RESOURCES, MUXO_UI_WIDGET_URI, OPENAI_COMPANY_KNOWLEDGE_TOOLS, PUBLIC_MCP_TOOL_NAMES, PUBLIC_TOOL_SECURITY_SCHEMES, SUPPORTED_MCP_PROTOCOL_VERSIONS, UI_RENDERED_MCP_TOOL_NAMES, attachMcpHarnessGuidance, MuxoToolError, buildApprovalUrl, buildMcpDiscoverResult, buildMcpErrorResultMeta, buildMcpToolDescriptor, buildMcpToolResultMeta, buildOnboardTeamGuide, clampWaitSeconds, completeMcpArgument, decodeMcpHeaderValue, errorPayloadFrom, extractOpenAiClientMeta, findMcpSkill, isSupportedMcpProtocolVersion, renderMuxoUiWidgetHtml, securitySchemesForTool, validateMcpHttpHeadersAndMeta, } from "./mcp-schema.js";
|
|
5
6
|
import { MUXO_VERSION } from "./version.js";
|
|
6
|
-
|
|
7
|
-
{ type: "noauth" },
|
|
8
|
-
{
|
|
9
|
-
type: "oauth2",
|
|
10
|
-
scopes: ["muxo:mcp", "muxo:read", "muxo:execute", "muxo:provision"],
|
|
11
|
-
},
|
|
12
|
-
];
|
|
13
|
-
/**
|
|
14
|
-
* Concise server instructions (<512 chars) per OpenAI Plugin MCP Server specification:
|
|
15
|
-
* https://developers.openai.com/plugins/build/mcp-server
|
|
16
|
-
*/
|
|
17
|
-
export const MUXO_MCP_SERVER_INSTRUCTIONS = "Muxo governs SaaS actions (Connected Apps: app.*), Instant tools (instant.*), Cloud Infrastructure (resource.*), Workspace Memory recall, and verifiable audit records. 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.";
|
|
18
|
-
export const MUXO_MCP_TOOLS = [
|
|
19
|
-
{
|
|
20
|
-
name: "get_profile",
|
|
21
|
-
title: "Get Authenticated Profile",
|
|
22
|
-
description: "Get the authenticated actor profile, user ID, email, workspace ID, and subscription tier.",
|
|
23
|
-
inputSchema: {
|
|
24
|
-
type: "object",
|
|
25
|
-
properties: {},
|
|
26
|
-
additionalProperties: false,
|
|
27
|
-
},
|
|
28
|
-
outputSchema: {
|
|
29
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
30
|
-
type: "object",
|
|
31
|
-
properties: {
|
|
32
|
-
id: {
|
|
33
|
-
type: "string",
|
|
34
|
-
minLength: 1,
|
|
35
|
-
pattern: "\\S",
|
|
36
|
-
description: "Unique identifier for the user.",
|
|
37
|
-
},
|
|
38
|
-
name: {
|
|
39
|
-
type: "string",
|
|
40
|
-
description: "Full name of the user.",
|
|
41
|
-
},
|
|
42
|
-
email: {
|
|
43
|
-
type: "string",
|
|
44
|
-
description: "Email address of the user.",
|
|
45
|
-
},
|
|
46
|
-
nickname: {
|
|
47
|
-
type: "string",
|
|
48
|
-
description: "Handle or username of the user.",
|
|
49
|
-
},
|
|
50
|
-
workspaceId: {
|
|
51
|
-
type: "string",
|
|
52
|
-
description: "Active workspace ID.",
|
|
53
|
-
},
|
|
54
|
-
workspaceName: {
|
|
55
|
-
type: "string",
|
|
56
|
-
description: "Active workspace name.",
|
|
57
|
-
},
|
|
58
|
-
tier: {
|
|
59
|
-
type: "string",
|
|
60
|
-
description: "Workspace subscription tier.",
|
|
61
|
-
},
|
|
62
|
-
authType: {
|
|
63
|
-
type: "string",
|
|
64
|
-
description: "Authentication type (session or api_key).",
|
|
65
|
-
},
|
|
66
|
-
actorId: {
|
|
67
|
-
type: "string",
|
|
68
|
-
description: "Actor identifier.",
|
|
69
|
-
},
|
|
70
|
-
user: {
|
|
71
|
-
type: "object",
|
|
72
|
-
description: "User profile record.",
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
required: ["id"],
|
|
76
|
-
additionalProperties: false,
|
|
77
|
-
},
|
|
78
|
-
securitySchemes: [
|
|
79
|
-
{ type: "noauth" },
|
|
80
|
-
{ type: "oauth2", scopes: ["muxo:read"] },
|
|
81
|
-
],
|
|
82
|
-
annotations: {
|
|
83
|
-
readOnlyHint: true,
|
|
84
|
-
destructiveHint: false,
|
|
85
|
-
openWorldHint: false,
|
|
86
|
-
},
|
|
87
|
-
_meta: {
|
|
88
|
-
"openai/profile": true,
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "get_organization",
|
|
93
|
-
title: "Get Organization & Billing Summary",
|
|
94
|
-
description: "Get workspace governance policy, monthly action usage, credit balance, Merchant-of-Record supplier settlement summary, and active connection/resource counts.",
|
|
95
|
-
inputSchema: {
|
|
96
|
-
type: "object",
|
|
97
|
-
properties: {},
|
|
98
|
-
additionalProperties: false,
|
|
99
|
-
},
|
|
100
|
-
annotations: {
|
|
101
|
-
readOnlyHint: true,
|
|
102
|
-
destructiveHint: false,
|
|
103
|
-
openWorldHint: false,
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
name: "search_tools",
|
|
108
|
-
title: "Search Unified Tool Catalog",
|
|
109
|
-
description: "Search the unified Muxo catalog across Connected Apps (app.*), Instant Tools (instant.*), and Cloud Infrastructure (resource.*).",
|
|
110
|
-
inputSchema: {
|
|
111
|
-
type: "object",
|
|
112
|
-
properties: {
|
|
113
|
-
query: {
|
|
114
|
-
type: "string",
|
|
115
|
-
description: "Search keywords (e.g. 'postgres', 'github issue', 'web search', 'seo audit', 'redis')",
|
|
116
|
-
},
|
|
117
|
-
lane: {
|
|
118
|
-
type: "string",
|
|
119
|
-
enum: ["all", "composio_sdk", "composio_instant", "stripe_projects"],
|
|
120
|
-
default: "all",
|
|
121
|
-
},
|
|
122
|
-
risk_level: {
|
|
123
|
-
type: "string",
|
|
124
|
-
enum: [
|
|
125
|
-
"read",
|
|
126
|
-
"write",
|
|
127
|
-
"admin",
|
|
128
|
-
"financial",
|
|
129
|
-
"provisioning",
|
|
130
|
-
"destructive",
|
|
131
|
-
],
|
|
132
|
-
},
|
|
133
|
-
limit: { type: "number", default: 20 },
|
|
134
|
-
},
|
|
135
|
-
additionalProperties: false,
|
|
136
|
-
},
|
|
137
|
-
annotations: {
|
|
138
|
-
readOnlyHint: true,
|
|
139
|
-
destructiveHint: false,
|
|
140
|
-
openWorldHint: true,
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: "inspect_tool",
|
|
145
|
-
title: "Inspect Tool Schema & Risk",
|
|
146
|
-
description: "Inspect a tool's full input JSON schema, risk classification, provider lane, LLM context URL, and credit cost before planning.",
|
|
147
|
-
inputSchema: {
|
|
148
|
-
type: "object",
|
|
149
|
-
required: ["tool_slug"],
|
|
150
|
-
properties: {
|
|
151
|
-
tool_slug: {
|
|
152
|
-
type: "string",
|
|
153
|
-
description: "Canonical Muxo tool slug (e.g. 'instant.seo.audit', 'app.gmail.send_email', or 'resource.turso.database')",
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
|
-
additionalProperties: false,
|
|
157
|
-
},
|
|
158
|
-
annotations: {
|
|
159
|
-
readOnlyHint: true,
|
|
160
|
-
destructiveHint: false,
|
|
161
|
-
openWorldHint: false,
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
name: "connection_status",
|
|
166
|
-
title: "Check Connection Status",
|
|
167
|
-
description: "Check connection status across Connected Apps, Instant Tools, and linked Cloud Infrastructure providers.",
|
|
168
|
-
inputSchema: {
|
|
169
|
-
type: "object",
|
|
170
|
-
properties: {
|
|
171
|
-
provider: {
|
|
172
|
-
type: "string",
|
|
173
|
-
description: "Optional provider filter (e.g. 'github', 'gmail', 'slack', 'neon', 'turso')",
|
|
174
|
-
},
|
|
175
|
-
sync_live: {
|
|
176
|
-
type: "boolean",
|
|
177
|
-
default: true,
|
|
178
|
-
description: "Whether to sync live connection status from upstream providers",
|
|
179
|
-
},
|
|
180
|
-
},
|
|
181
|
-
additionalProperties: false,
|
|
182
|
-
},
|
|
183
|
-
annotations: {
|
|
184
|
-
readOnlyHint: true,
|
|
185
|
-
destructiveHint: false,
|
|
186
|
-
openWorldHint: true,
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
name: "start_connection",
|
|
191
|
-
title: "Start OAuth Connection Handoff",
|
|
192
|
-
description: "Initiate a managed OAuth connection handoff for a Connected App or link a Cloud Infrastructure provider.",
|
|
193
|
-
inputSchema: {
|
|
194
|
-
type: "object",
|
|
195
|
-
required: ["provider"],
|
|
196
|
-
properties: {
|
|
197
|
-
provider: {
|
|
198
|
-
type: "string",
|
|
199
|
-
description: "Provider or toolkit slug (e.g. 'github', 'gmail', 'slack', 'neon')",
|
|
200
|
-
},
|
|
201
|
-
lane: {
|
|
202
|
-
type: "string",
|
|
203
|
-
enum: ["composio_sdk", "stripe_projects"],
|
|
204
|
-
description: "Provider lane (defaults to composio_sdk unless prefixed with resource.)",
|
|
205
|
-
},
|
|
206
|
-
callback_url: {
|
|
207
|
-
type: "string",
|
|
208
|
-
description: "Optional OAuth callback URL",
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
additionalProperties: false,
|
|
212
|
-
},
|
|
213
|
-
annotations: {
|
|
214
|
-
readOnlyHint: false,
|
|
215
|
-
destructiveHint: false,
|
|
216
|
-
openWorldHint: true,
|
|
217
|
-
},
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
name: "wait_for_connection",
|
|
221
|
-
title: "Wait for OAuth Connection Handoff",
|
|
222
|
-
description: "Poll and wait for an external user's pending OAuth connection handoff to become active before resuming a planned operation.",
|
|
223
|
-
inputSchema: {
|
|
224
|
-
type: "object",
|
|
225
|
-
required: ["provider"],
|
|
226
|
-
properties: {
|
|
227
|
-
provider: {
|
|
228
|
-
type: "string",
|
|
229
|
-
description: "Provider or toolkit slug (e.g. 'github', 'gmail', 'slack', 'notion', 'linear')",
|
|
230
|
-
},
|
|
231
|
-
timeout_seconds: {
|
|
232
|
-
type: "number",
|
|
233
|
-
default: 15,
|
|
234
|
-
description: "Maximum seconds to poll for OAuth completion (0-120, default 15)",
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
additionalProperties: false,
|
|
238
|
-
},
|
|
239
|
-
annotations: {
|
|
240
|
-
readOnlyHint: true,
|
|
241
|
-
destructiveHint: false,
|
|
242
|
-
openWorldHint: true,
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
name: "plan_action",
|
|
247
|
-
title: "Create Governed Action Plan",
|
|
248
|
-
description: "Create a governed execution plan (plan_*) for any tool, billing operation, or infrastructure provisioning operation. Accepts either an exact tool_slug (e.g. 'instant.seo.audit', 'billing.credits.topup', 'resource.turso.database') or a natural-language instruction (e.g. 'audit seo for https://muxo.ai'). Evaluates workspace policy, risk level, Workspace Memory recall, safety guardrails, BYOK vs Muxo-funded mode, and credit balance.",
|
|
249
|
-
inputSchema: {
|
|
250
|
-
type: "object",
|
|
251
|
-
required: ["tool_slug"],
|
|
252
|
-
properties: {
|
|
253
|
-
tool_slug: {
|
|
254
|
-
type: "string",
|
|
255
|
-
description: "Muxo tool slug (e.g. 'instant.seo.audit', 'billing.credits.topup') or natural-language request",
|
|
256
|
-
},
|
|
257
|
-
input: {
|
|
258
|
-
type: "object",
|
|
259
|
-
description: "Arguments matching the tool's inputSchema (auto-extracted when tool_slug is natural language)",
|
|
260
|
-
},
|
|
261
|
-
reason: {
|
|
262
|
-
type: "string",
|
|
263
|
-
description: "Audit reason explaining why this action is being planned",
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
additionalProperties: false,
|
|
267
|
-
},
|
|
268
|
-
annotations: {
|
|
269
|
-
readOnlyHint: false,
|
|
270
|
-
destructiveHint: false,
|
|
271
|
-
openWorldHint: false,
|
|
272
|
-
},
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
name: "get_plan",
|
|
276
|
-
title: "Get Action Plan",
|
|
277
|
-
description: "Inspect the status, risk level, governance decision record, and approval state of a planned action.",
|
|
278
|
-
inputSchema: {
|
|
279
|
-
type: "object",
|
|
280
|
-
required: ["plan_id"],
|
|
281
|
-
properties: {
|
|
282
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
283
|
-
},
|
|
284
|
-
additionalProperties: false,
|
|
285
|
-
},
|
|
286
|
-
annotations: {
|
|
287
|
-
readOnlyHint: true,
|
|
288
|
-
destructiveHint: false,
|
|
289
|
-
openWorldHint: false,
|
|
290
|
-
},
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
name: "get_run_context",
|
|
294
|
-
title: "Get Workspace Context & Memory",
|
|
295
|
-
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.",
|
|
296
|
-
inputSchema: {
|
|
297
|
-
type: "object",
|
|
298
|
-
properties: {
|
|
299
|
-
query: {
|
|
300
|
-
type: "string",
|
|
301
|
-
description: "Optional semantic search query to recall relevant workspace memories from Supermemory v5",
|
|
302
|
-
},
|
|
303
|
-
},
|
|
304
|
-
additionalProperties: false,
|
|
305
|
-
},
|
|
306
|
-
annotations: {
|
|
307
|
-
readOnlyHint: true,
|
|
308
|
-
destructiveHint: false,
|
|
309
|
-
openWorldHint: false,
|
|
310
|
-
},
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
name: "execute_read",
|
|
314
|
-
title: "Execute Read Plan",
|
|
315
|
-
description: "Execute an approved plan with riskLevel = 'read'.",
|
|
316
|
-
inputSchema: {
|
|
317
|
-
type: "object",
|
|
318
|
-
required: ["plan_id"],
|
|
319
|
-
properties: {
|
|
320
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
321
|
-
},
|
|
322
|
-
additionalProperties: false,
|
|
323
|
-
},
|
|
324
|
-
annotations: {
|
|
325
|
-
readOnlyHint: true,
|
|
326
|
-
destructiveHint: false,
|
|
327
|
-
openWorldHint: true,
|
|
328
|
-
},
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
name: "execute_write",
|
|
332
|
-
title: "Execute Write Plan",
|
|
333
|
-
description: "Execute an approved plan with riskLevel = 'write'.",
|
|
334
|
-
inputSchema: {
|
|
335
|
-
type: "object",
|
|
336
|
-
required: ["plan_id"],
|
|
337
|
-
properties: {
|
|
338
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
339
|
-
},
|
|
340
|
-
additionalProperties: false,
|
|
341
|
-
},
|
|
342
|
-
annotations: {
|
|
343
|
-
readOnlyHint: false,
|
|
344
|
-
destructiveHint: false,
|
|
345
|
-
openWorldHint: true,
|
|
346
|
-
},
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
name: "execute_admin",
|
|
350
|
-
title: "Execute Admin Plan",
|
|
351
|
-
description: "Execute an approved plan with riskLevel = 'admin'.",
|
|
352
|
-
inputSchema: {
|
|
353
|
-
type: "object",
|
|
354
|
-
required: ["plan_id"],
|
|
355
|
-
properties: {
|
|
356
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
357
|
-
},
|
|
358
|
-
additionalProperties: false,
|
|
359
|
-
},
|
|
360
|
-
annotations: {
|
|
361
|
-
readOnlyHint: false,
|
|
362
|
-
destructiveHint: false,
|
|
363
|
-
openWorldHint: true,
|
|
364
|
-
},
|
|
365
|
-
},
|
|
366
|
-
{
|
|
367
|
-
name: "execute_financial",
|
|
368
|
-
title: "Execute Financial Plan",
|
|
369
|
-
description: "Execute an approved plan with riskLevel = 'financial'.",
|
|
370
|
-
inputSchema: {
|
|
371
|
-
type: "object",
|
|
372
|
-
required: ["plan_id"],
|
|
373
|
-
properties: {
|
|
374
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
375
|
-
},
|
|
376
|
-
additionalProperties: false,
|
|
377
|
-
},
|
|
378
|
-
annotations: {
|
|
379
|
-
readOnlyHint: false,
|
|
380
|
-
destructiveHint: false,
|
|
381
|
-
openWorldHint: true,
|
|
382
|
-
},
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
name: "execute_provisioning",
|
|
386
|
-
title: "Execute Infrastructure Provisioning Plan",
|
|
387
|
-
description: "Execute an approved infrastructure provisioning plan with riskLevel = 'provisioning' via Stripe Projects.",
|
|
388
|
-
inputSchema: {
|
|
389
|
-
type: "object",
|
|
390
|
-
required: ["plan_id"],
|
|
391
|
-
properties: {
|
|
392
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
393
|
-
},
|
|
394
|
-
additionalProperties: false,
|
|
395
|
-
},
|
|
396
|
-
annotations: {
|
|
397
|
-
readOnlyHint: false,
|
|
398
|
-
destructiveHint: false,
|
|
399
|
-
openWorldHint: true,
|
|
400
|
-
},
|
|
401
|
-
},
|
|
402
|
-
{
|
|
403
|
-
name: "execute_destructive",
|
|
404
|
-
title: "Execute Destructive Plan",
|
|
405
|
-
description: "Execute an approved plan with riskLevel = 'destructive'.",
|
|
406
|
-
inputSchema: {
|
|
407
|
-
type: "object",
|
|
408
|
-
required: ["plan_id"],
|
|
409
|
-
properties: {
|
|
410
|
-
plan_id: { type: "string", description: "Plan ID (plan_*)" },
|
|
411
|
-
},
|
|
412
|
-
additionalProperties: false,
|
|
413
|
-
},
|
|
414
|
-
annotations: {
|
|
415
|
-
readOnlyHint: false,
|
|
416
|
-
destructiveHint: true,
|
|
417
|
-
openWorldHint: true,
|
|
418
|
-
},
|
|
419
|
-
},
|
|
420
|
-
{
|
|
421
|
-
name: "get_run",
|
|
422
|
-
title: "Get Execution Run",
|
|
423
|
-
description: "Get the execution status, output, duration, and metered cost of a run (run_*).",
|
|
424
|
-
inputSchema: {
|
|
425
|
-
type: "object",
|
|
426
|
-
required: ["run_id"],
|
|
427
|
-
properties: {
|
|
428
|
-
run_id: { type: "string", description: "Run ID (run_*)" },
|
|
429
|
-
},
|
|
430
|
-
additionalProperties: false,
|
|
431
|
-
},
|
|
432
|
-
annotations: {
|
|
433
|
-
readOnlyHint: true,
|
|
434
|
-
destructiveHint: false,
|
|
435
|
-
openWorldHint: false,
|
|
436
|
-
},
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
name: "cancel_run",
|
|
440
|
-
title: "Cancel Execution Run",
|
|
441
|
-
description: "Cancel an in-progress run and issue a cancellation receipt.",
|
|
442
|
-
inputSchema: {
|
|
443
|
-
type: "object",
|
|
444
|
-
required: ["run_id"],
|
|
445
|
-
properties: {
|
|
446
|
-
run_id: { type: "string", description: "Run ID (run_*)" },
|
|
447
|
-
},
|
|
448
|
-
additionalProperties: false,
|
|
449
|
-
},
|
|
450
|
-
annotations: {
|
|
451
|
-
readOnlyHint: false,
|
|
452
|
-
destructiveHint: true,
|
|
453
|
-
openWorldHint: false,
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
name: "get_receipt",
|
|
458
|
-
title: "Verify Execution Receipt",
|
|
459
|
-
description: "Fetch and cryptographically verify the HMAC-SHA256 + Ed25519 chained execution receipt (rcpt_*) for a run.",
|
|
460
|
-
inputSchema: {
|
|
461
|
-
type: "object",
|
|
462
|
-
required: ["receipt_id"],
|
|
463
|
-
properties: {
|
|
464
|
-
receipt_id: {
|
|
465
|
-
type: "string",
|
|
466
|
-
description: "Receipt ID (rcpt_*) or Run ID (run_*)",
|
|
467
|
-
},
|
|
468
|
-
},
|
|
469
|
-
additionalProperties: false,
|
|
470
|
-
},
|
|
471
|
-
annotations: {
|
|
472
|
-
readOnlyHint: true,
|
|
473
|
-
destructiveHint: false,
|
|
474
|
-
openWorldHint: false,
|
|
475
|
-
},
|
|
476
|
-
},
|
|
477
|
-
];
|
|
478
|
-
/**
|
|
479
|
-
* OpenAI Company Knowledge standard `search` and `fetch` tool definitions
|
|
480
|
-
* per https://developers.openai.com/plugins/build/mcp-server#company-knowledge-compatibility
|
|
481
|
-
*/
|
|
482
|
-
export const OPENAI_COMPANY_KNOWLEDGE_TOOLS = [
|
|
483
|
-
{
|
|
484
|
-
name: "search",
|
|
485
|
-
title: "Search Muxo Tools & Workspace Memory",
|
|
486
|
-
description: "Search across Muxo tools, provisioned cloud resources, and Supermemory v5 workspace knowledge.",
|
|
487
|
-
inputSchema: {
|
|
488
|
-
type: "object",
|
|
489
|
-
required: ["query"],
|
|
490
|
-
properties: {
|
|
491
|
-
query: { type: "string", description: "Search query string." },
|
|
492
|
-
},
|
|
493
|
-
additionalProperties: false,
|
|
494
|
-
},
|
|
495
|
-
annotations: {
|
|
496
|
-
readOnlyHint: true,
|
|
497
|
-
destructiveHint: false,
|
|
498
|
-
openWorldHint: false,
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
name: "fetch",
|
|
503
|
-
title: "Fetch Muxo Tool or Memory Record",
|
|
504
|
-
description: "Retrieve complete details for a Muxo tool, resource, or workspace memory record by ID.",
|
|
505
|
-
inputSchema: {
|
|
506
|
-
type: "object",
|
|
507
|
-
required: ["id"],
|
|
508
|
-
properties: {
|
|
509
|
-
id: {
|
|
510
|
-
type: "string",
|
|
511
|
-
description: "Identifier returned by search (e.g. 'tool:instant.seo.audit' or 'memory:mem_123').",
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
additionalProperties: false,
|
|
515
|
-
},
|
|
516
|
-
annotations: {
|
|
517
|
-
readOnlyHint: true,
|
|
518
|
-
destructiveHint: false,
|
|
519
|
-
openWorldHint: false,
|
|
520
|
-
},
|
|
521
|
-
},
|
|
522
|
-
];
|
|
7
|
+
export { DEFAULT_LEGACY_MCP_PROTOCOL_VERSION, DEFAULT_TOOL_SECURITY_SCHEMES, LATEST_MCP_PROTOCOL_VERSION, MCP_ERR_HEADER_MISMATCH, MCP_ERR_MISSING_REQUIRED_CLIENT_CAPABILITY, MCP_ERR_UNSUPPORTED_PROTOCOL_VERSION, MUXO_MCP_RESOURCE_TEMPLATES, MUXO_MCP_SERVER_INSTRUCTIONS, MUXO_MCP_TOOLS, MUXO_UI_MCP_APP_URI, MUXO_UI_RESOURCES, MUXO_UI_WIDGET_URI, OPENAI_COMPANY_KNOWLEDGE_TOOLS, PUBLIC_MCP_TOOL_NAMES, PUBLIC_TOOL_SECURITY_SCHEMES, SUPPORTED_MCP_PROTOCOL_VERSIONS, UI_RENDERED_MCP_TOOL_NAMES, attachMcpHarnessGuidance, buildMcpDiscoverResult, buildMcpErrorResultMeta, buildMcpToolDescriptor, buildMcpToolResultMeta, completeMcpArgument, decodeMcpHeaderValue, extractOpenAiClientMeta, isSupportedMcpProtocolVersion, renderMuxoUiWidgetHtml, securitySchemesForTool, validateMcpHttpHeadersAndMeta, };
|
|
523
8
|
function sha256Digest(content) {
|
|
524
9
|
const hash = crypto
|
|
525
10
|
.createHash("sha256")
|
|
@@ -558,7 +43,7 @@ function readSkillFileOrDefault(relPath, fallback) {
|
|
|
558
43
|
export function getMuxoMcpSkills() {
|
|
559
44
|
const muxoSkillMd = readSkillFileOrDefault("muxo/SKILL.md", `---
|
|
560
45
|
name: muxo
|
|
561
|
-
description: Route governed Muxo work between the hosted MCP-backed app and the local Muxo CLI across Connected Apps
|
|
46
|
+
description: Route governed Muxo work between the hosted MCP-backed app and the local Muxo CLI across Muxo Connected Apps, Instant Tools, Cloud Infrastructure (Stripe Projects), Supermemory v5, and Microsoft Agent Governance.
|
|
562
47
|
---
|
|
563
48
|
|
|
564
49
|
# Muxo
|
|
@@ -683,18 +168,22 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
683
168
|
provider: args.provider ? String(args.provider) : undefined,
|
|
684
169
|
syncLive: args.sync_live !== false,
|
|
685
170
|
});
|
|
686
|
-
case "start_connection":
|
|
687
|
-
|
|
171
|
+
case "start_connection": {
|
|
172
|
+
const conn = await engine.startConnection(ctx, {
|
|
688
173
|
provider: String(args.provider || ""),
|
|
689
174
|
lane: args.lane,
|
|
690
175
|
callbackUrl: args.callback_url ? String(args.callback_url) : undefined,
|
|
691
176
|
});
|
|
177
|
+
return {
|
|
178
|
+
ok: true,
|
|
179
|
+
...conn,
|
|
180
|
+
connection: conn,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
692
183
|
case "wait_for_connection":
|
|
693
184
|
return engine.waitForConnection(ctx, {
|
|
694
185
|
provider: String(args.provider || ""),
|
|
695
|
-
timeoutSeconds: args.timeout_seconds
|
|
696
|
-
? Number(args.timeout_seconds)
|
|
697
|
-
: 15,
|
|
186
|
+
timeoutSeconds: clampWaitSeconds(args.timeout_seconds),
|
|
698
187
|
});
|
|
699
188
|
case "plan_action":
|
|
700
189
|
return engine.planAction(ctx, {
|
|
@@ -708,9 +197,157 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
708
197
|
reason: args.reason ? String(args.reason) : undefined,
|
|
709
198
|
});
|
|
710
199
|
case "get_plan":
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
200
|
+
if (args.wait_for_approval === true || args.wait === true) {
|
|
201
|
+
return engine.waitForPlanApproval(ctx, {
|
|
202
|
+
planId: String(args.plan_id || ""),
|
|
203
|
+
timeoutSeconds: clampWaitSeconds(args.timeout_seconds, 15, 60),
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
{
|
|
207
|
+
const plan = engine.getPlan(ctx, String(args.plan_id || ""));
|
|
208
|
+
return {
|
|
209
|
+
ok: true,
|
|
210
|
+
approved: APPROVED_PLAN_STATUSES.has(plan.approvalStatus),
|
|
211
|
+
timedOut: false,
|
|
212
|
+
plan,
|
|
213
|
+
approvalStatus: plan.approvalStatus,
|
|
214
|
+
approvalUrl: buildApprovalUrl(engine.config.baseUrl, plan.id),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
case "get_run_context": {
|
|
218
|
+
const action = String(args.action || "").trim().toLowerCase();
|
|
219
|
+
const prompt = String(args.prompt || "").trim();
|
|
220
|
+
const query = args.query ? String(args.query) : undefined;
|
|
221
|
+
const rawParamRules = Array.isArray(args.parameter_rules)
|
|
222
|
+
? args.parameter_rules
|
|
223
|
+
: Array.isArray(args.parameterRules)
|
|
224
|
+
? args.parameterRules
|
|
225
|
+
: undefined;
|
|
226
|
+
if (action === "memory_graph") {
|
|
227
|
+
return engine.getMemoryGraph(ctx, query);
|
|
228
|
+
}
|
|
229
|
+
if (action === "governance_status") {
|
|
230
|
+
return engine.getGovernanceOverview(ctx);
|
|
231
|
+
}
|
|
232
|
+
if (action === "list_workspaces") {
|
|
233
|
+
const workspaces = engine.store.listUserWorkspaces(ctx.user.id, ctx.workspace.id);
|
|
234
|
+
return {
|
|
235
|
+
ok: true,
|
|
236
|
+
action,
|
|
237
|
+
currentWorkspaceId: ctx.workspace.id,
|
|
238
|
+
activeWorkspace: workspaces.find((w) => w.id === ctx.workspace.id) || {
|
|
239
|
+
id: ctx.workspace.id,
|
|
240
|
+
name: ctx.workspace.name,
|
|
241
|
+
slug: ctx.workspace.slug,
|
|
242
|
+
tier: ctx.workspace.tier,
|
|
243
|
+
},
|
|
244
|
+
workspaces,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (action === "switch_workspace") {
|
|
248
|
+
const targetWsId = String(args.workspace_id || query || prompt || "").trim();
|
|
249
|
+
if (!targetWsId) {
|
|
250
|
+
throw new Error("workspace_id is required when action='switch_workspace'");
|
|
251
|
+
}
|
|
252
|
+
const switched = engine.store.switchUserWorkspace(ctx.user.id, targetWsId);
|
|
253
|
+
if (!switched) {
|
|
254
|
+
throw new Error(`Workspace ${targetWsId} not found or not linked to your account. Call get_run_context with action='list_workspaces' to see accessible workspaces.`);
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
ok: true,
|
|
258
|
+
action,
|
|
259
|
+
switched: true,
|
|
260
|
+
workspaceId: switched.workspace.id,
|
|
261
|
+
workspace: switched.workspace,
|
|
262
|
+
workspaces: engine.store.listUserWorkspaces(ctx.user.id, switched.workspace.id),
|
|
263
|
+
message: `Active workspace for your session is now ${switched.workspace.name} (${switched.workspace.id}). API keys stay bound to their own workspace; use a key minted for ${switched.workspace.id} to target it over MCP.`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (action === "onboard_team") {
|
|
267
|
+
return buildOnboardTeamGuide({
|
|
268
|
+
baseUrl: engine.config.baseUrl,
|
|
269
|
+
workspaceId: ctx.workspace.id,
|
|
270
|
+
workspaceName: ctx.workspace.name,
|
|
271
|
+
teamName: String(args.team_name || args.teamName || query || prompt || "").trim(),
|
|
272
|
+
workspaces: engine.store.listUserWorkspaces(ctx.user.id, ctx.workspace.id),
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (action === "set_guardrail" &&
|
|
276
|
+
(prompt || (rawParamRules && rawParamRules.length > 0))) {
|
|
277
|
+
return engine.applyNaturalLanguageGuardrail(ctx, prompt, {
|
|
278
|
+
parameterRules: rawParamRules,
|
|
279
|
+
source: rawParamRules ? "mcp_harness" : "deterministic",
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (action === "reset_guardrails") {
|
|
283
|
+
return engine.resetWorkspaceGuardrails(ctx);
|
|
284
|
+
}
|
|
285
|
+
if (action === "check_policy" || action === "simulate_policy") {
|
|
286
|
+
const toolSlug = String(args.tool_slug || args.slug || args.tool_id || query || prompt || "instant.web.search").trim();
|
|
287
|
+
const input = (args.input || args.arguments) || {};
|
|
288
|
+
return engine.checkToolPolicy(ctx, { toolSlug, input });
|
|
289
|
+
}
|
|
290
|
+
if (action === "kill_switch") {
|
|
291
|
+
const enabled = typeof args.enabled === "boolean"
|
|
292
|
+
? args.enabled
|
|
293
|
+
: typeof args.active === "boolean"
|
|
294
|
+
? args.active
|
|
295
|
+
: !/\b(resume|unpause|disable|off|false)\b/i.test(prompt || query || "");
|
|
296
|
+
const reason = prompt ||
|
|
297
|
+
query ||
|
|
298
|
+
(enabled ? "Paused via MCP get_run_context" : undefined);
|
|
299
|
+
const updated = engine.setKillSwitch(ctx, enabled, reason);
|
|
300
|
+
const govOverview = engine.getGovernanceOverview(ctx);
|
|
301
|
+
return {
|
|
302
|
+
ok: true,
|
|
303
|
+
action: "kill_switch",
|
|
304
|
+
killSwitchActive: Boolean(updated.policy.killSwitchActive),
|
|
305
|
+
killSwitchReason: updated.policy.killSwitchReason || null,
|
|
306
|
+
policy: updated.policy,
|
|
307
|
+
llmPolicyBrief: govOverview.llmPolicyBrief,
|
|
308
|
+
explanation: govOverview.explanation,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (action === "scan_context") {
|
|
312
|
+
const textToScan = String(args.content || prompt || query || "");
|
|
313
|
+
return engine.scanForContextPoisoning(ctx.workspace.id, textToScan);
|
|
314
|
+
}
|
|
315
|
+
if (action === "forget") {
|
|
316
|
+
if (!(query || prompt)) {
|
|
317
|
+
throw new Error("query is required when action='forget'");
|
|
318
|
+
}
|
|
319
|
+
return engine.forgetWorkspaceMemoryMatching(ctx, query || prompt);
|
|
320
|
+
}
|
|
321
|
+
if (action === "recall") {
|
|
322
|
+
return engine.getMemoryOverview(ctx, query);
|
|
323
|
+
}
|
|
324
|
+
if (action === "remember") {
|
|
325
|
+
if (prompt && !args.content) {
|
|
326
|
+
return engine.doNaturalLanguage(ctx, { prompt });
|
|
327
|
+
}
|
|
328
|
+
const record = await engine.addWorkspaceMemory(ctx, {
|
|
329
|
+
title: String(args.title || prompt.slice(0, 60) || "Workspace Fact"),
|
|
330
|
+
content: String(args.content || prompt || query || ""),
|
|
331
|
+
kind: "fact",
|
|
332
|
+
});
|
|
333
|
+
const overview = await engine.getMemoryOverview(ctx);
|
|
334
|
+
return {
|
|
335
|
+
ok: true,
|
|
336
|
+
memory: record,
|
|
337
|
+
activeDefaults: overview.activeDefaults,
|
|
338
|
+
explanation: overview.explanation,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (prompt && !action) {
|
|
342
|
+
return engine.doNaturalLanguage(ctx, { prompt });
|
|
343
|
+
}
|
|
344
|
+
const runCtx = await engine.getRunContext(ctx, query);
|
|
345
|
+
if (args.include_graph === true) {
|
|
346
|
+
const memoryGraph = await engine.getMemoryGraph(ctx, query);
|
|
347
|
+
return { ...runCtx, memoryGraph };
|
|
348
|
+
}
|
|
349
|
+
return runCtx;
|
|
350
|
+
}
|
|
714
351
|
case "execute_read":
|
|
715
352
|
return engine.executePlanForRisk(ctx, String(args.plan_id || ""), "read");
|
|
716
353
|
case "execute_write":
|
|
@@ -726,9 +363,125 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
726
363
|
case "get_run":
|
|
727
364
|
return engine.getRun(ctx, String(args.run_id || ""));
|
|
728
365
|
case "cancel_run":
|
|
729
|
-
return engine.cancelRun(ctx, String(args.run_id || ""));
|
|
730
|
-
case "get_receipt":
|
|
731
|
-
|
|
366
|
+
return engine.cancelRun(ctx, String(args.run_id || ""), args.reason ? String(args.reason) : undefined);
|
|
367
|
+
case "get_receipt": {
|
|
368
|
+
const targetId = String(args.receipt_id || args.run_id || "latest").trim();
|
|
369
|
+
if (targetId === "chain") {
|
|
370
|
+
return engine.verifyReceiptChain(ctx);
|
|
371
|
+
}
|
|
372
|
+
const verified = engine.getReceipt(ctx, targetId);
|
|
373
|
+
if (args.verify_chain === true) {
|
|
374
|
+
const receiptChain = engine.verifyReceiptChain(ctx);
|
|
375
|
+
return { ...verified, receiptChain };
|
|
376
|
+
}
|
|
377
|
+
return verified;
|
|
378
|
+
}
|
|
379
|
+
// Supermemory MCP & Governance direct tool aliases for agent harness interoperability
|
|
380
|
+
case "who_am_i":
|
|
381
|
+
return engine.getProfile(ctx);
|
|
382
|
+
case "list_spaces": {
|
|
383
|
+
const overview = await engine.getMemoryOverview(ctx);
|
|
384
|
+
return {
|
|
385
|
+
activeSpace: overview.namespace,
|
|
386
|
+
spaces: [
|
|
387
|
+
{
|
|
388
|
+
id: overview.namespace,
|
|
389
|
+
containerTag: overview.namespace,
|
|
390
|
+
workspaceId: ctx.workspace.id,
|
|
391
|
+
workspaceName: ctx.workspace.name,
|
|
392
|
+
active: true,
|
|
393
|
+
},
|
|
394
|
+
],
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
case "search_memory":
|
|
398
|
+
case "list_memories":
|
|
399
|
+
return engine.getMemoryOverview(ctx, args.query ? String(args.query) : undefined);
|
|
400
|
+
case "add_memory":
|
|
401
|
+
case "remember": {
|
|
402
|
+
const prompt = String(args.prompt || "").trim();
|
|
403
|
+
if (prompt && !args.content) {
|
|
404
|
+
return engine.doNaturalLanguage(ctx, { prompt });
|
|
405
|
+
}
|
|
406
|
+
const content = String(args.content || args.memory || prompt || "");
|
|
407
|
+
const title = String(args.title || content.slice(0, 60) || "Workspace Memory");
|
|
408
|
+
const record = await engine.addWorkspaceMemory(ctx, {
|
|
409
|
+
title,
|
|
410
|
+
content,
|
|
411
|
+
kind: args.kind || "fact",
|
|
412
|
+
});
|
|
413
|
+
const overview = await engine.getMemoryOverview(ctx);
|
|
414
|
+
return {
|
|
415
|
+
ok: true,
|
|
416
|
+
memory: record,
|
|
417
|
+
activeDefaults: overview.activeDefaults,
|
|
418
|
+
explanation: overview.explanation,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
case "forget_memory": {
|
|
422
|
+
const query = String(args.query || args.id || args.memory || "").trim();
|
|
423
|
+
if (!query)
|
|
424
|
+
throw new Error("query is required to forget a memory");
|
|
425
|
+
return engine.forgetWorkspaceMemoryMatching(ctx, query);
|
|
426
|
+
}
|
|
427
|
+
case "memory_graph":
|
|
428
|
+
return engine.getMemoryGraph(ctx, args.query ? String(args.query) : undefined);
|
|
429
|
+
case "set_guardrail":
|
|
430
|
+
case "configure_guardrails": {
|
|
431
|
+
const rawParamRules = Array.isArray(args.parameter_rules)
|
|
432
|
+
? args.parameter_rules
|
|
433
|
+
: Array.isArray(args.parameterRules)
|
|
434
|
+
? args.parameterRules
|
|
435
|
+
: undefined;
|
|
436
|
+
return engine.applyNaturalLanguageGuardrail(ctx, String(args.prompt || args.rule || args.instruction || ""), {
|
|
437
|
+
parameterRules: rawParamRules,
|
|
438
|
+
source: rawParamRules ? "mcp_harness" : "deterministic",
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
case "reset_guardrails":
|
|
442
|
+
return engine.resetWorkspaceGuardrails(ctx);
|
|
443
|
+
case "check_policy":
|
|
444
|
+
case "simulate_policy":
|
|
445
|
+
return engine.checkToolPolicy(ctx, {
|
|
446
|
+
toolSlug: String(args.tool_slug || args.slug || args.tool_id || args.query || "instant.web.search"),
|
|
447
|
+
input: (args.input || args.arguments) || {},
|
|
448
|
+
});
|
|
449
|
+
case "kill_switch": {
|
|
450
|
+
const enabled = typeof args.enabled === "boolean"
|
|
451
|
+
? args.enabled
|
|
452
|
+
: typeof args.active === "boolean"
|
|
453
|
+
? args.active
|
|
454
|
+
: true;
|
|
455
|
+
const reason = args.reason
|
|
456
|
+
? String(args.reason)
|
|
457
|
+
: args.prompt
|
|
458
|
+
? String(args.prompt)
|
|
459
|
+
: undefined;
|
|
460
|
+
const updated = engine.setKillSwitch(ctx, enabled, reason);
|
|
461
|
+
const govOverview = engine.getGovernanceOverview(ctx);
|
|
462
|
+
return {
|
|
463
|
+
ok: true,
|
|
464
|
+
action: "kill_switch",
|
|
465
|
+
killSwitchActive: Boolean(updated.policy.killSwitchActive),
|
|
466
|
+
killSwitchReason: updated.policy.killSwitchReason || null,
|
|
467
|
+
policy: updated.policy,
|
|
468
|
+
llmPolicyBrief: govOverview.llmPolicyBrief,
|
|
469
|
+
explanation: govOverview.explanation,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
case "scan_context":
|
|
473
|
+
return engine.scanForContextPoisoning(ctx.workspace.id, String(args.content || args.prompt || args.query || ""));
|
|
474
|
+
case "governance_status":
|
|
475
|
+
return engine.getGovernanceOverview(ctx);
|
|
476
|
+
case "verify_receipt_chain":
|
|
477
|
+
return engine.verifyReceiptChain(ctx, args.limit ? Number(args.limit) : 100);
|
|
478
|
+
case "do":
|
|
479
|
+
return engine.doNaturalLanguage(ctx, {
|
|
480
|
+
prompt: String(args.prompt || args.instruction || args.query || ""),
|
|
481
|
+
input: args.input || undefined,
|
|
482
|
+
dryRun: Boolean(args.dry_run || args.dryRun),
|
|
483
|
+
autoApprove: args.auto_approve !== false && args.autoApprove !== false,
|
|
484
|
+
});
|
|
732
485
|
// OpenAI Company Knowledge standard `search` and `fetch` tool support
|
|
733
486
|
case "search": {
|
|
734
487
|
const q = String(args.query || "").trim();
|
|
@@ -739,7 +492,7 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
739
492
|
const toolHits = toolsRes.tools.map((t) => ({
|
|
740
493
|
id: `tool:${t.slug}`,
|
|
741
494
|
title: `${t.name} (${t.slug})`,
|
|
742
|
-
url: t.providerUrl || `https://docs.muxo.ai/
|
|
495
|
+
url: t.providerUrl || `https://docs.muxo.ai/catalogue#${encodeURIComponent(t.providerSlug || t.slug)}`,
|
|
743
496
|
snippet: `${t.description} [lane=${t.lane}, risk=${t.riskLevel}, cost=${t.creditCost}cr]`,
|
|
744
497
|
}));
|
|
745
498
|
const memHits = (memRes.memories || []).slice(0, 5).map((m) => ({
|
|
@@ -779,7 +532,7 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
779
532
|
title: tool.name,
|
|
780
533
|
text: JSON.stringify(tool, null, 2),
|
|
781
534
|
url: tool.providerUrl ||
|
|
782
|
-
`https://docs.muxo.ai/
|
|
535
|
+
`https://docs.muxo.ai/catalogue#${encodeURIComponent(tool.providerSlug || tool.slug)}`,
|
|
783
536
|
metadata: {
|
|
784
537
|
slug: tool.slug,
|
|
785
538
|
lane: tool.lane,
|
|
@@ -789,7 +542,7 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
|
|
|
789
542
|
};
|
|
790
543
|
}
|
|
791
544
|
default:
|
|
792
|
-
throw new
|
|
545
|
+
throw new MuxoToolError(`Unknown MCP tool: '${toolName}'. Call tools/list for the canonical Muxo MCP tools.`, { code: "unknown_mcp_tool", statusCode: 404, payload: { toolName } });
|
|
793
546
|
}
|
|
794
547
|
}
|
|
795
548
|
export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
@@ -800,58 +553,270 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
800
553
|
method.startsWith("notifications/")) {
|
|
801
554
|
return null;
|
|
802
555
|
}
|
|
556
|
+
const headerAndMetaCheck = validateMcpHttpHeadersAndMeta({}, rpc);
|
|
557
|
+
if (!headerAndMetaCheck.ok) {
|
|
558
|
+
return {
|
|
559
|
+
jsonrpc: "2.0",
|
|
560
|
+
id,
|
|
561
|
+
error: headerAndMetaCheck.error,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
803
564
|
try {
|
|
565
|
+
if (method === "server/discover") {
|
|
566
|
+
return {
|
|
567
|
+
jsonrpc: "2.0",
|
|
568
|
+
id,
|
|
569
|
+
result: buildMcpDiscoverResult(MUXO_VERSION),
|
|
570
|
+
};
|
|
571
|
+
}
|
|
804
572
|
if (method === "initialize") {
|
|
805
|
-
const requestedProtocol =
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
: "
|
|
573
|
+
const requestedProtocol = headerAndMetaCheck.protocolVersion;
|
|
574
|
+
const serverInfo = {
|
|
575
|
+
name: "muxo-mcp-server",
|
|
576
|
+
title: "Muxo Unified Agent Runtime & Governance MCP Server",
|
|
577
|
+
version: MUXO_VERSION,
|
|
578
|
+
};
|
|
809
579
|
return {
|
|
810
580
|
jsonrpc: "2.0",
|
|
811
581
|
id,
|
|
812
582
|
result: {
|
|
583
|
+
resultType: "complete",
|
|
813
584
|
protocolVersion: requestedProtocol,
|
|
585
|
+
supportedVersions: [...SUPPORTED_MCP_PROTOCOL_VERSIONS],
|
|
814
586
|
instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
|
|
815
|
-
serverInfo
|
|
816
|
-
name: "muxo-mcp-server",
|
|
817
|
-
version: MUXO_VERSION,
|
|
818
|
-
},
|
|
587
|
+
serverInfo,
|
|
819
588
|
capabilities: {
|
|
820
589
|
tools: { listChanged: false },
|
|
821
|
-
resources: { listChanged: false },
|
|
590
|
+
resources: { listChanged: false, subscribe: false },
|
|
591
|
+
prompts: { listChanged: false },
|
|
592
|
+
completions: {},
|
|
822
593
|
extensions: {
|
|
823
594
|
"io.modelcontextprotocol/skills": {},
|
|
595
|
+
"io.modelcontextprotocol/apps": {},
|
|
824
596
|
},
|
|
825
597
|
},
|
|
598
|
+
_meta: {
|
|
599
|
+
"io.modelcontextprotocol/serverInfo": serverInfo,
|
|
600
|
+
"io.modelcontextprotocol/instructions": MUXO_MCP_SERVER_INSTRUCTIONS,
|
|
601
|
+
},
|
|
826
602
|
},
|
|
827
603
|
};
|
|
828
604
|
}
|
|
829
605
|
if (method === "ping") {
|
|
830
|
-
return { jsonrpc: "2.0", id, result: {} };
|
|
606
|
+
return { jsonrpc: "2.0", id, result: { resultType: "complete" } };
|
|
607
|
+
}
|
|
608
|
+
if (method === "completion/complete") {
|
|
609
|
+
const catalogTools = await engine.searchTools({ lane: "all", limit: 100 });
|
|
610
|
+
const completion = completeMcpArgument(params, catalogTools.tools.map((t) => t.slug));
|
|
611
|
+
return {
|
|
612
|
+
jsonrpc: "2.0",
|
|
613
|
+
id,
|
|
614
|
+
result: {
|
|
615
|
+
resultType: "complete",
|
|
616
|
+
completion,
|
|
617
|
+
},
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
if (method === "subscriptions/listen") {
|
|
621
|
+
return {
|
|
622
|
+
jsonrpc: "2.0",
|
|
623
|
+
id,
|
|
624
|
+
result: {
|
|
625
|
+
resultType: "complete",
|
|
626
|
+
events: [],
|
|
627
|
+
ttlMs: 30_000,
|
|
628
|
+
cacheScope: "private",
|
|
629
|
+
},
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
if (method === "prompts/list") {
|
|
633
|
+
return {
|
|
634
|
+
jsonrpc: "2.0",
|
|
635
|
+
id,
|
|
636
|
+
result: {
|
|
637
|
+
resultType: "complete",
|
|
638
|
+
ttlMs: 300_000,
|
|
639
|
+
cacheScope: "public",
|
|
640
|
+
prompts: [
|
|
641
|
+
{
|
|
642
|
+
name: "context",
|
|
643
|
+
title: "Workspace Memory & Governance Context",
|
|
644
|
+
description: "Ready-to-attach workspace context (Supermemory v5 profile, bi-temporal facts, learned parameter defaults, and active Microsoft Governance guardrails).",
|
|
645
|
+
arguments: [
|
|
646
|
+
{
|
|
647
|
+
name: "query",
|
|
648
|
+
description: "Optional topic or task query to focus memory recall",
|
|
649
|
+
required: false,
|
|
650
|
+
},
|
|
651
|
+
],
|
|
652
|
+
},
|
|
653
|
+
{
|
|
654
|
+
name: "governed_execution",
|
|
655
|
+
title: "Governed Tool Execution Workflow",
|
|
656
|
+
description: "Step-by-step assistant prompt for discovering, planning, approving, executing, and verifying a governed Muxo action.",
|
|
657
|
+
arguments: [
|
|
658
|
+
{
|
|
659
|
+
name: "task",
|
|
660
|
+
description: "Natural-language task to plan and execute",
|
|
661
|
+
required: false,
|
|
662
|
+
},
|
|
663
|
+
],
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: "security_audit",
|
|
667
|
+
title: "Workspace Governance, Memory Graph & Receipt Chain Audit",
|
|
668
|
+
description: "Inspect the workspace's 9-module Microsoft Agent Governance posture, Bi-Temporal Knowledge Graph, and Ed25519 AgenticReceipt hash chain.",
|
|
669
|
+
arguments: [],
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
name: "policy_guardrails",
|
|
673
|
+
title: "Workspace Policy, Parameter Guardrails & Risk Matrix",
|
|
674
|
+
description: "Load the structured LLM Policy & Governance Brief (riskLaneMatrix, conditional parameterRules with compliance guidance, budget caps, kill switch status, and control-plane commands).",
|
|
675
|
+
arguments: [],
|
|
676
|
+
},
|
|
677
|
+
],
|
|
678
|
+
},
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
if (method === "prompts/get") {
|
|
682
|
+
const promptName = String(params.name || "context").trim();
|
|
683
|
+
const promptArgs = (params.arguments || {});
|
|
684
|
+
if (promptName === "context") {
|
|
685
|
+
const query = promptArgs.query ? String(promptArgs.query) : undefined;
|
|
686
|
+
const runCtx = await engine.getRunContext(ctx, query);
|
|
687
|
+
return {
|
|
688
|
+
jsonrpc: "2.0",
|
|
689
|
+
id,
|
|
690
|
+
result: {
|
|
691
|
+
resultType: "complete",
|
|
692
|
+
description: "Ready-to-attach Muxo workspace memory, active defaults, and safety guardrails.",
|
|
693
|
+
messages: [
|
|
694
|
+
{
|
|
695
|
+
role: "user",
|
|
696
|
+
content: {
|
|
697
|
+
type: "text",
|
|
698
|
+
text: String(runCtx.llmSystemPrompt || runCtx.explanation.preferred),
|
|
699
|
+
},
|
|
700
|
+
},
|
|
701
|
+
],
|
|
702
|
+
},
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
if (promptName === "policy_guardrails") {
|
|
706
|
+
const gov = engine.getGovernanceOverview(ctx);
|
|
707
|
+
const sections = [
|
|
708
|
+
gov.llmPolicyBrief.llmSystemDirective,
|
|
709
|
+
`### Structured LLM Policy Brief (JSON)\n\`\`\`json\n${JSON.stringify(gov.llmPolicyBrief, null, 2)}\n\`\`\``,
|
|
710
|
+
];
|
|
711
|
+
if (promptArgs.tool_slug) {
|
|
712
|
+
const sim = await engine.checkToolPolicy(ctx, {
|
|
713
|
+
toolSlug: String(promptArgs.tool_slug),
|
|
714
|
+
});
|
|
715
|
+
sections.push(`### Dry-Run Policy Check for \`${sim.toolSlug}\`\n\`\`\`json\n${JSON.stringify(sim, null, 2)}\n\`\`\``);
|
|
716
|
+
}
|
|
717
|
+
return {
|
|
718
|
+
jsonrpc: "2.0",
|
|
719
|
+
id,
|
|
720
|
+
result: {
|
|
721
|
+
resultType: "complete",
|
|
722
|
+
description: "Workspace policy, conditional parameter guardrails, and risk-lane matrix for AI agents",
|
|
723
|
+
messages: [
|
|
724
|
+
{
|
|
725
|
+
role: "user",
|
|
726
|
+
content: {
|
|
727
|
+
type: "text",
|
|
728
|
+
text: sections.join("\n\n"),
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
],
|
|
732
|
+
},
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
if (promptName === "governed_execution") {
|
|
736
|
+
const task = String(promptArgs.task || "the user's requested operation");
|
|
737
|
+
const runCtx = await engine.getRunContext(ctx);
|
|
738
|
+
return {
|
|
739
|
+
jsonrpc: "2.0",
|
|
740
|
+
id,
|
|
741
|
+
result: {
|
|
742
|
+
resultType: "complete",
|
|
743
|
+
description: "Governed Muxo execution workflow prompt",
|
|
744
|
+
messages: [
|
|
745
|
+
{
|
|
746
|
+
role: "user",
|
|
747
|
+
content: {
|
|
748
|
+
type: "text",
|
|
749
|
+
text: `${runCtx.llmSystemPrompt}\n\n## Task\nExecute "${task}" safely using Muxo:\n1. Call \`search_tools\` and \`inspect_tool\` (or pass a natural-language request to \`plan_action\`).\n2. Call \`plan_action\` and inspect \`plan.approvalStatus\`, \`authHandoff\`, and \`llmGuidance.nextToolCalls\`.\n3. If \`authHandoff.required\` is true, present \`humanHandoff.markdownForUser\` and call \`wait_for_connection\`.\n4. If \`approvalStatus === "pending_approval"\`, present \`humanHandoff.markdownForUser\` and call \`get_plan\` with \`wait_for_approval: true\`.\n5. Execute with \`execute_<riskLevel>\` and verify the cryptographic receipt with \`get_receipt\`.`,
|
|
750
|
+
},
|
|
751
|
+
},
|
|
752
|
+
],
|
|
753
|
+
},
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
if (promptName === "security_audit") {
|
|
757
|
+
const [gov, graph, chain] = await Promise.all([
|
|
758
|
+
Promise.resolve(engine.getGovernanceOverview(ctx)),
|
|
759
|
+
engine.getMemoryGraph(ctx),
|
|
760
|
+
Promise.resolve(engine.verifyReceiptChain(ctx)),
|
|
761
|
+
]);
|
|
762
|
+
return {
|
|
763
|
+
jsonrpc: "2.0",
|
|
764
|
+
id,
|
|
765
|
+
result: {
|
|
766
|
+
resultType: "complete",
|
|
767
|
+
description: "Workspace governance, bi-temporal graph, and receipt chain audit",
|
|
768
|
+
messages: [
|
|
769
|
+
{
|
|
770
|
+
role: "user",
|
|
771
|
+
content: {
|
|
772
|
+
type: "text",
|
|
773
|
+
text: [
|
|
774
|
+
`# Muxo Security, Memory & Cryptographic Audit`,
|
|
775
|
+
`## 1. Microsoft Agent Governance (9 Modules)\n${gov.explanation.preferred}`,
|
|
776
|
+
`## 2. Bi-Temporal Knowledge Graph\n${graph.explanation.preferred}\n\`\`\`mermaid\n${graph.mermaid}\n\`\`\``,
|
|
777
|
+
`## 3. Portable Ed25519 AgenticReceipt Chain\n${chain.explanation.preferred}`,
|
|
778
|
+
].join("\n\n"),
|
|
779
|
+
},
|
|
780
|
+
},
|
|
781
|
+
],
|
|
782
|
+
},
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
return {
|
|
786
|
+
jsonrpc: "2.0",
|
|
787
|
+
id,
|
|
788
|
+
error: {
|
|
789
|
+
code: -32602,
|
|
790
|
+
message: `Prompt not found: ${promptName}`,
|
|
791
|
+
},
|
|
792
|
+
};
|
|
831
793
|
}
|
|
832
794
|
if (method === "tools/list") {
|
|
833
795
|
return {
|
|
834
796
|
jsonrpc: "2.0",
|
|
835
797
|
id,
|
|
836
798
|
result: {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
799
|
+
resultType: "complete",
|
|
800
|
+
ttlMs: 300_000,
|
|
801
|
+
cacheScope: "public",
|
|
802
|
+
tools: MUXO_MCP_TOOLS.map((t) => buildMcpToolDescriptor(t)),
|
|
841
803
|
},
|
|
842
804
|
};
|
|
843
805
|
}
|
|
844
806
|
if (method === "tools/call") {
|
|
845
807
|
const toolName = String(params.name || "");
|
|
846
808
|
const toolArgs = (params.arguments || {});
|
|
847
|
-
const
|
|
809
|
+
const rawOutput = await dispatchMcpToolCall(engine, ctx, toolName, toolArgs);
|
|
810
|
+
const output = attachMcpHarnessGuidance(toolName, toolArgs, rawOutput);
|
|
848
811
|
const structuredContent = output && typeof output === "object" && !Array.isArray(output)
|
|
849
812
|
? output
|
|
850
813
|
: { data: output };
|
|
814
|
+
const resultMeta = buildMcpToolResultMeta(toolName, params);
|
|
851
815
|
return {
|
|
852
816
|
jsonrpc: "2.0",
|
|
853
817
|
id,
|
|
854
818
|
result: {
|
|
819
|
+
resultType: "complete",
|
|
855
820
|
structuredContent,
|
|
856
821
|
content: [
|
|
857
822
|
{
|
|
@@ -859,6 +824,7 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
859
824
|
text: JSON.stringify(output, null, 2),
|
|
860
825
|
},
|
|
861
826
|
],
|
|
827
|
+
...(resultMeta ? { _meta: resultMeta } : {}),
|
|
862
828
|
isError: false,
|
|
863
829
|
},
|
|
864
830
|
};
|
|
@@ -881,20 +847,23 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
881
847
|
return {
|
|
882
848
|
jsonrpc: "2.0",
|
|
883
849
|
id,
|
|
884
|
-
result: {
|
|
850
|
+
result: {
|
|
851
|
+
resultType: "complete",
|
|
852
|
+
ttlMs: 300_000,
|
|
853
|
+
cacheScope: "public",
|
|
854
|
+
skills,
|
|
855
|
+
},
|
|
885
856
|
};
|
|
886
857
|
}
|
|
887
858
|
if (method === "skills/get") {
|
|
888
|
-
const
|
|
889
|
-
const requestedName = String(params.name || "muxo").trim();
|
|
890
|
-
const skill = getMuxoMcpSkills().find((s) => s.uri === requestedUri || s.name === requestedName);
|
|
859
|
+
const { skill, requested } = findMcpSkill(getMuxoMcpSkills(), params);
|
|
891
860
|
if (!skill) {
|
|
892
861
|
return {
|
|
893
862
|
jsonrpc: "2.0",
|
|
894
863
|
id,
|
|
895
864
|
error: {
|
|
896
865
|
code: -32602,
|
|
897
|
-
message: `Skill not found: ${
|
|
866
|
+
message: `Skill not found: ${requested}`,
|
|
898
867
|
},
|
|
899
868
|
};
|
|
900
869
|
}
|
|
@@ -906,6 +875,9 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
906
875
|
jsonrpc: "2.0",
|
|
907
876
|
id,
|
|
908
877
|
result: {
|
|
878
|
+
resultType: "complete",
|
|
879
|
+
ttlMs: 300_000,
|
|
880
|
+
cacheScope: "public",
|
|
909
881
|
skill: {
|
|
910
882
|
uri: skill.uri,
|
|
911
883
|
frontmatter: skill.frontmatter,
|
|
@@ -928,21 +900,401 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
928
900
|
},
|
|
929
901
|
};
|
|
930
902
|
}
|
|
903
|
+
if (method === "resources/templates/list") {
|
|
904
|
+
return {
|
|
905
|
+
jsonrpc: "2.0",
|
|
906
|
+
id,
|
|
907
|
+
result: {
|
|
908
|
+
resultType: "complete",
|
|
909
|
+
ttlMs: 300_000,
|
|
910
|
+
cacheScope: "public",
|
|
911
|
+
resourceTemplates: MUXO_MCP_RESOURCE_TEMPLATES,
|
|
912
|
+
},
|
|
913
|
+
};
|
|
914
|
+
}
|
|
931
915
|
if (method === "resources/list") {
|
|
932
|
-
const
|
|
916
|
+
const skillResources = getMuxoMcpSkills().flatMap((s) => s.files.map((f) => ({
|
|
933
917
|
uri: f.uri,
|
|
934
918
|
name: `${s.name}/${f.path}`,
|
|
935
919
|
description: s.description,
|
|
936
920
|
mimeType: f.mimeType,
|
|
937
921
|
})));
|
|
922
|
+
const dynamicResources = [
|
|
923
|
+
{
|
|
924
|
+
uri: "muxo://profile",
|
|
925
|
+
name: "Workspace Profile & Active Memory Defaults",
|
|
926
|
+
description: "Stable and recent Supermemory v5 profile context, active auto-fill defaults, and Ed25519 Agent DID for the active workspace.",
|
|
927
|
+
mimeType: "application/json",
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
uri: "supermemory://profile",
|
|
931
|
+
name: "Supermemory Active Space Profile",
|
|
932
|
+
description: "Supermemory MCP compatible profile resource (static + dynamic facts and preferences) for the active workspace.",
|
|
933
|
+
mimeType: "application/json",
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
uri: "supermemory://spaces",
|
|
937
|
+
name: "Supermemory Accessible Spaces",
|
|
938
|
+
description: "Compact list of accessible workspace memory spaces with the active containerTag marked.",
|
|
939
|
+
mimeType: "application/json",
|
|
940
|
+
},
|
|
941
|
+
{
|
|
942
|
+
uri: "muxo://context",
|
|
943
|
+
name: "Governed Workspace Run Context",
|
|
944
|
+
description: "Ready-to-inject workspace context including guardrails, learned defaults, provisioned cloud resources, and Supermemory recall.",
|
|
945
|
+
mimeType: "application/json",
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
uri: "muxo://memory/graph",
|
|
949
|
+
name: "Bi-Temporal Knowledge Graph",
|
|
950
|
+
description: "Entity & relationship graph with active facts, superseded historical facts (validFrom/validTo), and Mermaid topology.",
|
|
951
|
+
mimeType: "application/json",
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
uri: "muxo://governance/policy",
|
|
955
|
+
name: "Microsoft Agent Governance & Guardrails",
|
|
956
|
+
description: "9-module Microsoft Agent Governance status, plain-English guardrails, Bayesian trust score, and OWASP ASI-06 scan status.",
|
|
957
|
+
mimeType: "application/json",
|
|
958
|
+
},
|
|
959
|
+
{
|
|
960
|
+
uri: "muxo://policy/brief",
|
|
961
|
+
name: "LLM Policy, Risk Matrix & Parameter Guardrails Brief",
|
|
962
|
+
description: "Structured LLM policy digest with riskLaneMatrix, conditional parameterRules compliance guidance, learned memory defaults, and control-plane commands.",
|
|
963
|
+
mimeType: "application/json",
|
|
964
|
+
},
|
|
965
|
+
{
|
|
966
|
+
uri: "muxo://receipts/chain",
|
|
967
|
+
name: "Cryptographic AgenticReceipt Hash Chain",
|
|
968
|
+
description: "Tamper-evident SHA-256 + portable Ed25519 AgenticReceipt chain verification report.",
|
|
969
|
+
mimeType: "application/json",
|
|
970
|
+
},
|
|
971
|
+
];
|
|
938
972
|
return {
|
|
939
973
|
jsonrpc: "2.0",
|
|
940
974
|
id,
|
|
941
|
-
result: {
|
|
975
|
+
result: {
|
|
976
|
+
resultType: "complete",
|
|
977
|
+
ttlMs: 60_000,
|
|
978
|
+
cacheScope: "private",
|
|
979
|
+
resources: [...MUXO_UI_RESOURCES, ...skillResources, ...dynamicResources],
|
|
980
|
+
},
|
|
942
981
|
};
|
|
943
982
|
}
|
|
944
983
|
if (method === "resources/read") {
|
|
945
984
|
const uri = String(params.uri || "").trim();
|
|
985
|
+
const uiResource = MUXO_UI_RESOURCES.find((r) => r.uri === uri);
|
|
986
|
+
if (uiResource) {
|
|
987
|
+
return {
|
|
988
|
+
jsonrpc: "2.0",
|
|
989
|
+
id,
|
|
990
|
+
result: {
|
|
991
|
+
resultType: "complete",
|
|
992
|
+
ttlMs: 300_000,
|
|
993
|
+
cacheScope: "public",
|
|
994
|
+
contents: [
|
|
995
|
+
{
|
|
996
|
+
uri: uiResource.uri,
|
|
997
|
+
mimeType: uiResource.mimeType,
|
|
998
|
+
text: renderMuxoUiWidgetHtml(),
|
|
999
|
+
_meta: uiResource._meta,
|
|
1000
|
+
},
|
|
1001
|
+
],
|
|
1002
|
+
},
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
if (uri === "muxo://profile" || uri === "supermemory://profile") {
|
|
1006
|
+
const overview = await engine.getMemoryOverview(ctx);
|
|
1007
|
+
const profile = engine.getProfile(ctx);
|
|
1008
|
+
const payload = {
|
|
1009
|
+
uri,
|
|
1010
|
+
workspaceId: ctx.workspace.id,
|
|
1011
|
+
workspaceSlug: ctx.workspace.slug,
|
|
1012
|
+
namespace: overview.namespace,
|
|
1013
|
+
profile: overview.context.profile,
|
|
1014
|
+
activeDefaults: overview.activeDefaults,
|
|
1015
|
+
activeGuardrails: overview.activeGuardrails,
|
|
1016
|
+
actor: profile,
|
|
1017
|
+
explanation: overview.explanation,
|
|
1018
|
+
};
|
|
1019
|
+
return {
|
|
1020
|
+
jsonrpc: "2.0",
|
|
1021
|
+
id,
|
|
1022
|
+
result: {
|
|
1023
|
+
resultType: "complete",
|
|
1024
|
+
ttlMs: 60_000,
|
|
1025
|
+
cacheScope: "private",
|
|
1026
|
+
contents: [
|
|
1027
|
+
{
|
|
1028
|
+
uri,
|
|
1029
|
+
mimeType: "application/json",
|
|
1030
|
+
text: JSON.stringify(payload, null, 2),
|
|
1031
|
+
},
|
|
1032
|
+
],
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
if (uri === "muxo://spaces" || uri === "supermemory://spaces") {
|
|
1037
|
+
const overview = await engine.getMemoryOverview(ctx);
|
|
1038
|
+
const payload = {
|
|
1039
|
+
activeSpace: overview.namespace,
|
|
1040
|
+
spaces: [
|
|
1041
|
+
{
|
|
1042
|
+
id: overview.namespace,
|
|
1043
|
+
containerTag: overview.namespace,
|
|
1044
|
+
workspaceId: ctx.workspace.id,
|
|
1045
|
+
workspaceName: ctx.workspace.name,
|
|
1046
|
+
active: true,
|
|
1047
|
+
},
|
|
1048
|
+
],
|
|
1049
|
+
};
|
|
1050
|
+
return {
|
|
1051
|
+
jsonrpc: "2.0",
|
|
1052
|
+
id,
|
|
1053
|
+
result: {
|
|
1054
|
+
resultType: "complete",
|
|
1055
|
+
ttlMs: 60_000,
|
|
1056
|
+
cacheScope: "private",
|
|
1057
|
+
contents: [
|
|
1058
|
+
{
|
|
1059
|
+
uri,
|
|
1060
|
+
mimeType: "application/json",
|
|
1061
|
+
text: JSON.stringify(payload, null, 2),
|
|
1062
|
+
},
|
|
1063
|
+
],
|
|
1064
|
+
},
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1067
|
+
if (uri === "muxo://context") {
|
|
1068
|
+
const runCtx = await engine.getRunContext(ctx);
|
|
1069
|
+
return {
|
|
1070
|
+
jsonrpc: "2.0",
|
|
1071
|
+
id,
|
|
1072
|
+
result: {
|
|
1073
|
+
resultType: "complete",
|
|
1074
|
+
ttlMs: 60_000,
|
|
1075
|
+
cacheScope: "private",
|
|
1076
|
+
contents: [
|
|
1077
|
+
{
|
|
1078
|
+
uri,
|
|
1079
|
+
mimeType: "application/json",
|
|
1080
|
+
text: JSON.stringify(runCtx, null, 2),
|
|
1081
|
+
},
|
|
1082
|
+
],
|
|
1083
|
+
},
|
|
1084
|
+
};
|
|
1085
|
+
}
|
|
1086
|
+
if (uri === "muxo://memory/graph") {
|
|
1087
|
+
const graph = await engine.getMemoryGraph(ctx);
|
|
1088
|
+
return {
|
|
1089
|
+
jsonrpc: "2.0",
|
|
1090
|
+
id,
|
|
1091
|
+
result: {
|
|
1092
|
+
resultType: "complete",
|
|
1093
|
+
ttlMs: 60_000,
|
|
1094
|
+
cacheScope: "private",
|
|
1095
|
+
contents: [
|
|
1096
|
+
{
|
|
1097
|
+
uri,
|
|
1098
|
+
mimeType: "application/json",
|
|
1099
|
+
text: JSON.stringify(graph, null, 2),
|
|
1100
|
+
},
|
|
1101
|
+
],
|
|
1102
|
+
},
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
if (uri === "muxo://governance/policy") {
|
|
1106
|
+
const gov = engine.getGovernanceOverview(ctx);
|
|
1107
|
+
return {
|
|
1108
|
+
jsonrpc: "2.0",
|
|
1109
|
+
id,
|
|
1110
|
+
result: {
|
|
1111
|
+
resultType: "complete",
|
|
1112
|
+
ttlMs: 60_000,
|
|
1113
|
+
cacheScope: "private",
|
|
1114
|
+
contents: [
|
|
1115
|
+
{
|
|
1116
|
+
uri,
|
|
1117
|
+
mimeType: "application/json",
|
|
1118
|
+
text: JSON.stringify(gov, null, 2),
|
|
1119
|
+
},
|
|
1120
|
+
],
|
|
1121
|
+
},
|
|
1122
|
+
};
|
|
1123
|
+
}
|
|
1124
|
+
if (uri === "muxo://policy/brief") {
|
|
1125
|
+
const gov = engine.getGovernanceOverview(ctx);
|
|
1126
|
+
return {
|
|
1127
|
+
jsonrpc: "2.0",
|
|
1128
|
+
id,
|
|
1129
|
+
result: {
|
|
1130
|
+
resultType: "complete",
|
|
1131
|
+
ttlMs: 60_000,
|
|
1132
|
+
cacheScope: "private",
|
|
1133
|
+
contents: [
|
|
1134
|
+
{
|
|
1135
|
+
uri,
|
|
1136
|
+
mimeType: "application/json",
|
|
1137
|
+
text: JSON.stringify(gov.llmPolicyBrief, null, 2),
|
|
1138
|
+
},
|
|
1139
|
+
],
|
|
1140
|
+
},
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
if (uri === "muxo://receipts/chain") {
|
|
1144
|
+
const chain = engine.verifyReceiptChain(ctx);
|
|
1145
|
+
return {
|
|
1146
|
+
jsonrpc: "2.0",
|
|
1147
|
+
id,
|
|
1148
|
+
result: {
|
|
1149
|
+
resultType: "complete",
|
|
1150
|
+
ttlMs: 60_000,
|
|
1151
|
+
cacheScope: "private",
|
|
1152
|
+
contents: [
|
|
1153
|
+
{
|
|
1154
|
+
uri,
|
|
1155
|
+
mimeType: "application/json",
|
|
1156
|
+
text: JSON.stringify(chain, null, 2),
|
|
1157
|
+
},
|
|
1158
|
+
],
|
|
1159
|
+
},
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
if (uri.startsWith("muxo://tools/")) {
|
|
1163
|
+
const slug = decodeURIComponent(uri.slice("muxo://tools/".length)).trim();
|
|
1164
|
+
try {
|
|
1165
|
+
const inspected = await dispatchMcpToolCall(engine, ctx, "inspect_tool", {
|
|
1166
|
+
tool_slug: slug,
|
|
1167
|
+
});
|
|
1168
|
+
return {
|
|
1169
|
+
jsonrpc: "2.0",
|
|
1170
|
+
id,
|
|
1171
|
+
result: {
|
|
1172
|
+
resultType: "complete",
|
|
1173
|
+
ttlMs: 300_000,
|
|
1174
|
+
cacheScope: "public",
|
|
1175
|
+
contents: [
|
|
1176
|
+
{
|
|
1177
|
+
uri,
|
|
1178
|
+
mimeType: "application/json",
|
|
1179
|
+
text: JSON.stringify(inspected, null, 2),
|
|
1180
|
+
},
|
|
1181
|
+
],
|
|
1182
|
+
},
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
catch {
|
|
1186
|
+
return {
|
|
1187
|
+
jsonrpc: "2.0",
|
|
1188
|
+
id,
|
|
1189
|
+
error: {
|
|
1190
|
+
code: -32602,
|
|
1191
|
+
message: `Resource not found: ${uri}`,
|
|
1192
|
+
},
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
if (uri.startsWith("muxo://plans/")) {
|
|
1197
|
+
const planId = decodeURIComponent(uri.slice("muxo://plans/".length)).trim();
|
|
1198
|
+
try {
|
|
1199
|
+
const planRecord = await dispatchMcpToolCall(engine, ctx, "get_plan", {
|
|
1200
|
+
plan_id: planId,
|
|
1201
|
+
});
|
|
1202
|
+
return {
|
|
1203
|
+
jsonrpc: "2.0",
|
|
1204
|
+
id,
|
|
1205
|
+
result: {
|
|
1206
|
+
resultType: "complete",
|
|
1207
|
+
ttlMs: 30_000,
|
|
1208
|
+
cacheScope: "private",
|
|
1209
|
+
contents: [
|
|
1210
|
+
{
|
|
1211
|
+
uri,
|
|
1212
|
+
mimeType: "application/json",
|
|
1213
|
+
text: JSON.stringify(planRecord, null, 2),
|
|
1214
|
+
},
|
|
1215
|
+
],
|
|
1216
|
+
},
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
catch {
|
|
1220
|
+
return {
|
|
1221
|
+
jsonrpc: "2.0",
|
|
1222
|
+
id,
|
|
1223
|
+
error: {
|
|
1224
|
+
code: -32602,
|
|
1225
|
+
message: `Resource not found: ${uri}`,
|
|
1226
|
+
},
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
if (uri.startsWith("muxo://runs/")) {
|
|
1231
|
+
const runId = decodeURIComponent(uri.slice("muxo://runs/".length)).trim();
|
|
1232
|
+
try {
|
|
1233
|
+
const runRecord = await dispatchMcpToolCall(engine, ctx, "get_run", {
|
|
1234
|
+
run_id: runId,
|
|
1235
|
+
});
|
|
1236
|
+
return {
|
|
1237
|
+
jsonrpc: "2.0",
|
|
1238
|
+
id,
|
|
1239
|
+
result: {
|
|
1240
|
+
resultType: "complete",
|
|
1241
|
+
ttlMs: 30_000,
|
|
1242
|
+
cacheScope: "private",
|
|
1243
|
+
contents: [
|
|
1244
|
+
{
|
|
1245
|
+
uri,
|
|
1246
|
+
mimeType: "application/json",
|
|
1247
|
+
text: JSON.stringify(runRecord, null, 2),
|
|
1248
|
+
},
|
|
1249
|
+
],
|
|
1250
|
+
},
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
catch {
|
|
1254
|
+
return {
|
|
1255
|
+
jsonrpc: "2.0",
|
|
1256
|
+
id,
|
|
1257
|
+
error: {
|
|
1258
|
+
code: -32602,
|
|
1259
|
+
message: `Resource not found: ${uri}`,
|
|
1260
|
+
},
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
if (uri.startsWith("muxo://receipts/")) {
|
|
1265
|
+
const receiptId = decodeURIComponent(uri.slice("muxo://receipts/".length)).trim();
|
|
1266
|
+
try {
|
|
1267
|
+
const receiptRecord = await dispatchMcpToolCall(engine, ctx, "get_receipt", {
|
|
1268
|
+
receipt_id: receiptId,
|
|
1269
|
+
});
|
|
1270
|
+
return {
|
|
1271
|
+
jsonrpc: "2.0",
|
|
1272
|
+
id,
|
|
1273
|
+
result: {
|
|
1274
|
+
resultType: "complete",
|
|
1275
|
+
ttlMs: 60_000,
|
|
1276
|
+
cacheScope: "private",
|
|
1277
|
+
contents: [
|
|
1278
|
+
{
|
|
1279
|
+
uri,
|
|
1280
|
+
mimeType: "application/json",
|
|
1281
|
+
text: JSON.stringify(receiptRecord, null, 2),
|
|
1282
|
+
},
|
|
1283
|
+
],
|
|
1284
|
+
},
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
catch {
|
|
1288
|
+
return {
|
|
1289
|
+
jsonrpc: "2.0",
|
|
1290
|
+
id,
|
|
1291
|
+
error: {
|
|
1292
|
+
code: -32602,
|
|
1293
|
+
message: `Resource not found: ${uri}`,
|
|
1294
|
+
},
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
946
1298
|
const allFiles = getMuxoMcpSkills().flatMap((s) => s.files);
|
|
947
1299
|
const found = allFiles.find((f) => f.uri === uri);
|
|
948
1300
|
if (!found) {
|
|
@@ -959,6 +1311,9 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
959
1311
|
jsonrpc: "2.0",
|
|
960
1312
|
id,
|
|
961
1313
|
result: {
|
|
1314
|
+
resultType: "complete",
|
|
1315
|
+
ttlMs: 300_000,
|
|
1316
|
+
cacheScope: "public",
|
|
962
1317
|
contents: [
|
|
963
1318
|
{
|
|
964
1319
|
uri: found.uri,
|
|
@@ -979,14 +1334,13 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
979
1334
|
};
|
|
980
1335
|
}
|
|
981
1336
|
catch (err) {
|
|
982
|
-
const errPayload =
|
|
983
|
-
|
|
984
|
-
error: String(err?.message || err || "MCP tool execution failed"),
|
|
985
|
-
};
|
|
1337
|
+
const errPayload = errorPayloadFrom(err, "MCP tool execution failed");
|
|
1338
|
+
const errMeta = buildMcpErrorResultMeta(err, engine?.config?.baseUrl || "https://api.muxo.ai");
|
|
986
1339
|
return {
|
|
987
1340
|
jsonrpc: "2.0",
|
|
988
1341
|
id,
|
|
989
1342
|
result: {
|
|
1343
|
+
resultType: "complete",
|
|
990
1344
|
structuredContent: errPayload,
|
|
991
1345
|
content: [
|
|
992
1346
|
{
|
|
@@ -994,6 +1348,7 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
|
|
|
994
1348
|
text: JSON.stringify(errPayload, null, 2),
|
|
995
1349
|
},
|
|
996
1350
|
],
|
|
1351
|
+
...(errMeta ? { _meta: errMeta } : {}),
|
|
997
1352
|
isError: true,
|
|
998
1353
|
},
|
|
999
1354
|
};
|