@muxoai/platform 1.4.3 → 1.4.5

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.
@@ -202,6 +202,20 @@ export interface ApprovalGatePlan {
202
202
  toolSlug: string;
203
203
  riskLevel: string;
204
204
  approvalStatus: string;
205
+ creditCost?: number;
206
+ estimatedCostUsd?: number;
207
+ changePreview?: {
208
+ whatChanges: string;
209
+ whoIsAffected: string;
210
+ targetEntity: string;
211
+ estimatedCostUsd: number;
212
+ creditCost: number;
213
+ fundingMode: "muxo_funded" | "byok";
214
+ costDisplay: string;
215
+ triggeredRule: string;
216
+ reversibility: string;
217
+ recoveryBehavior: string;
218
+ };
205
219
  }
206
220
  export declare function buildApprovalUrl(baseUrl: string, planId: string): string;
207
221
  export declare function buildApprovalHumanHandoff(baseUrl: string, plan: ApprovalGatePlan): HumanHandoff;
@@ -266,9 +266,16 @@ export const MUXO_MCP_RESOURCE_TEMPLATES = [
266
266
  uriTemplate: "skill://muxo/{skillName}/SKILL.md",
267
267
  name: "Muxo Agent Skill Markdown (SEP-2640)",
268
268
  title: "Muxo Agent Skill Markdown (SEP-2640)",
269
- description: "Read the SKILL.md entry point for a published Muxo Agent Skill ('muxo' or 'setup').",
269
+ description: "Read the SKILL.md entry point for a published Muxo Agent Skill ('muxo', 'setup', or domain automation/provisioning skills such as 'github-automation', 'supabase-provisioning').",
270
270
  mimeType: "text/markdown",
271
271
  },
272
+ {
273
+ uriTemplate: "muxo://skills/{skillSlug}",
274
+ name: "Muxo Governed Domain & Workflow Skill (SKILL.md + Metadata)",
275
+ title: "Muxo Governed Domain & Workflow Skill (SKILL.md + Metadata)",
276
+ description: "Read a transpiled Muxo Governed Skill (e.g. muxo://skills/github-automation, muxo://skills/supabase-provisioning, muxo://skills/changelog-generator) with tool sequences, pitfalls, and zero-OAuth Stripe Projects overrides.",
277
+ mimeType: "application/json",
278
+ },
272
279
  ];
273
280
  /**
274
281
  * Evaluates MCP `completion/complete` requests for prompt arguments and resource templates.
@@ -280,8 +287,27 @@ export function completeMcpArgument(params, toolSlugs = []) {
280
287
  const argName = String(argObj.name || "").trim();
281
288
  const prefix = String(argObj.value || "").trim().toLowerCase();
282
289
  let candidates = [];
283
- if (argName === "skillName" || argName === "name") {
284
- candidates = ["muxo", "setup"];
290
+ if (argName === "skillName" || argName === "name" || argName === "skillSlug") {
291
+ candidates = [
292
+ "muxo",
293
+ "setup",
294
+ "github-automation",
295
+ "gmail-automation",
296
+ "slack-automation",
297
+ "notion-automation",
298
+ "linear-automation",
299
+ "hubspot-automation",
300
+ "salesforce-automation",
301
+ "shopify-automation",
302
+ "metaads-automation",
303
+ "stripe-automation",
304
+ "supabase-provisioning",
305
+ "vercel-provisioning",
306
+ "turso-provisioning",
307
+ "changelog-generator",
308
+ "lead-research-assistant",
309
+ "security-audit",
310
+ ];
285
311
  }
286
312
  else if (argName === "focus") {
287
313
  candidates = ["full", "pending_approvals", "billing", "receipts", "memory"];
@@ -631,8 +657,17 @@ export function buildApprovalHumanHandoff(baseUrl, plan) {
631
657
  const approvalUrl = buildApprovalUrl(baseUrl, plan.id);
632
658
  const ctaLabel = "Review & approve";
633
659
  const headline = `Muxo needs your approval to run ${plan.toolSlug}`;
634
- const instructions = `Open ${approvalUrl} to review and approve this ${plan.riskLevel}-risk action with one click (or run \`muxo approve ${plan.id}\`). Nothing runs until you approve.`;
635
- const markdownForUser = `### Muxo Approval Required\n**[${ctaLabel} in Muxo](${approvalUrl})**\n\nPlan \`${plan.id}\` (\`${plan.toolSlug}\` · **${plan.riskLevel} risk**) is held by your Muxo workspace guardrails. Open the link above to review and approve it in one click (or run \`muxo approve ${plan.id}\`). Nothing executes until you approve.`;
660
+ const preview = plan.changePreview;
661
+ const costSnippet = preview?.costDisplay
662
+ ? ` · Est. cost: ${preview.costDisplay}`
663
+ : typeof plan.creditCost === "number"
664
+ ? ` · Est. cost: $${((plan.creditCost || 0) * 0.01).toFixed(2)} USD (${plan.creditCost} cr)`
665
+ : "";
666
+ const instructions = `Open ${approvalUrl} to review and approve this ${plan.riskLevel}-risk action with one click (or run \`muxo approve ${plan.id}\`).${costSnippet} Nothing runs until you approve.`;
667
+ const previewMarkdown = preview
668
+ ? `\n\n- **What changes:** ${preview.whatChanges}\n- **Affected target:** ${preview.whoIsAffected}\n- **Estimated cost:** ${preview.costDisplay}\n- **Triggered guardrail:** ${preview.triggeredRule}`
669
+ : "";
670
+ const markdownForUser = `### Muxo Approval Required\n**[${ctaLabel} in Muxo](${approvalUrl})**\n\nPlan \`${plan.id}\` (\`${plan.toolSlug}\` · **${plan.riskLevel} risk**) is held by your Muxo workspace guardrails.${previewMarkdown}\n\nOpen the link above to review and approve it in one click (or run \`muxo approve ${plan.id}\`). Nothing executes until you approve.`;
636
671
  return {
637
672
  kind: "approval",
638
673
  brand: "Muxo",
@@ -1061,7 +1096,16 @@ export const MUXO_MCP_TOOLS = [
1061
1096
  "otel_traces",
1062
1097
  "roi_analytics",
1063
1098
  "playbooks",
1099
+ "create_playbook",
1064
1100
  "run_playbook",
1101
+ "rollback_workflow",
1102
+ "signal_workflow",
1103
+ "workflow_history",
1104
+ "configure_harness",
1105
+ "harness_presets",
1106
+ "reconcile_run",
1107
+ "skills",
1108
+ "get_skill",
1065
1109
  "kill_switch",
1066
1110
  "governance_status",
1067
1111
  "scan_context",
@@ -1069,11 +1113,11 @@ export const MUXO_MCP_TOOLS = [
1069
1113
  "switch_workspace",
1070
1114
  "onboard_team",
1071
1115
  ],
1072
- description: "Control-plane operation: 'inspect' (default), 'remember' (save fact/preference), 'recall' (list memories), 'forget' (delete matching memories), 'memory_graph' (Graphiti bi-temporal entity/relationship lineage with optional as_of time-travel & focal_entity 2-hop BFS), 'set_guardrail' (apply plain-English or structured parameter_rules guardrail), 'reset_guardrails' (restore default safe guardrails), 'check_policy' (dry-run evaluate tool_slug + input against policy and parameter guardrails before planning), 'cedar_policy' (compile/evaluate AWS Cedar & OPA Rego policy-as-code), 'otel_traces' (export W3C OpenTelemetry GenAI/MCP spans & Langfuse batch), 'roi_analytics' (FinOps & BYOK unit-economics ROI report), 'playbooks' / 'run_playbook' (list or execute turnkey multi-step Temporal Saga playbooks), 'kill_switch' (pause/resume agent execution), 'governance_status' (Microsoft 9-module status + LLM policy brief), 'scan_context' (OWASP ASI-06 check), 'list_workspaces', 'switch_workspace', or 'onboard_team'",
1116
+ description: "Control-plane operation (or omit action and pass any plain-English prompt): 'inspect' (default), 'remember' (save fact/preference), 'recall' (list memories), 'forget' (delete matching memories), 'memory_graph' (Graphiti bi-temporal entity/relationship lineage with optional as_of time-travel & focal_entity 2-hop BFS), 'set_guardrail' (apply plain-English or structured parameter_rules guardrail), 'reset_guardrails' (restore default safe guardrails), 'check_policy' (dry-run evaluate tool_slug + input against policy and parameter guardrails before planning), 'cedar_policy' (compile/evaluate AWS Cedar & OPA Rego policy-as-code), 'otel_traces' (export W3C OpenTelemetry GenAI/MCP spans & Langfuse batch), 'roi_analytics' (FinOps & BYOK unit-economics ROI report), 'playbooks' / 'create_playbook' / 'run_playbook' (list, author custom, or execute multi-step Temporal Saga playbooks), 'rollback_workflow' / 'signal_workflow' / 'workflow_history' (Temporal workflow lifecycle; accepts workflow_id='latest'), 'configure_harness' / 'harness_presets' (apply turnkey harness presets like startup-builder, strict-production, read-only-auditor, finops-byok-zero-cost and generate ready-to-paste harness config blocks), 'reconcile_run' (verify run state, receipt signature, and upstream side-effect alignment), 'skills' / 'get_skill' (list or fetch governed domain & workflow SKILL.md playbooks), 'kill_switch' (pause/resume agent execution), 'governance_status' (Microsoft 9-module status + LLM policy brief), 'scan_context' (OWASP ASI-06 check), 'list_workspaces', 'switch_workspace', or 'onboard_team'",
1073
1117
  },
1074
1118
  prompt: {
1075
1119
  type: "string",
1076
- description: "Natural-language instruction when action is 'remember', 'set_guardrail', 'kill_switch', or 'scan_context' (e.g. 'Only allow sending emails to @muxo.ai' or 'Require approval for Stripe refunds over $50, auto-approve under $50')",
1120
+ description: "Plain-English instruction for any control-plane or OSS operation (e.g. 'Run the fullstack cloud bootstrap playbook for acme', 'Rollback the latest workflow because staging failed', 'Show my knowledge graph as of yesterday within 2 hops of workspace', 'Configure harness preset strict-production', or 'Only allow sending emails to @muxo.ai')",
1077
1121
  },
1078
1122
  tool_slug: {
1079
1123
  type: "string",
@@ -1180,7 +1224,32 @@ export const MUXO_MCP_TOOLS = [
1180
1224
  },
1181
1225
  slug: {
1182
1226
  type: "string",
1183
- description: "Optional playbook slug when action='run_playbook' (e.g. 'fullstack-cloud-bootstrap', 'competitor-seo-growth-brief', 'incident-containment-audit', 'customer-release-readiness')",
1227
+ description: "Playbook slug when action='run_playbook', or domain/workflow skill slug when action='get_skill' (e.g. 'github-automation', 'supabase-provisioning')",
1228
+ },
1229
+ provider: {
1230
+ type: "string",
1231
+ description: "Provider slug to filter action='skills' or select a provider's skill with action='get_skill'",
1232
+ },
1233
+ category: {
1234
+ type: "string",
1235
+ enum: ["governance", "app_automation", "cloud_infrastructure", "workflow"],
1236
+ description: "Category filter when action='skills'",
1237
+ },
1238
+ workflow_id: {
1239
+ type: "string",
1240
+ description: "Workflow ID or 'latest' when action is 'rollback_workflow', 'signal_workflow', or 'workflow_history'",
1241
+ },
1242
+ signal_name: {
1243
+ type: "string",
1244
+ description: "Temporal signal name when action='signal_workflow' (default: 'human.approval.granted')",
1245
+ },
1246
+ preset: {
1247
+ type: "string",
1248
+ description: "Turnkey harness preset slug when action='configure_harness' ('startup-builder', 'strict-production', 'read-only-auditor', 'finops-byok-zero-cost')",
1249
+ },
1250
+ harness: {
1251
+ type: "string",
1252
+ description: "Target agent harness when action='configure_harness' ('claude-code', 'cursor', 'codex', 'chatgpt', 'claude-desktop', 'factory-droid', or 'all')",
1184
1253
  },
1185
1254
  plan_id: {
1186
1255
  type: "string",
package/dist/mcp.js CHANGED
@@ -3,6 +3,7 @@ import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { ROOT_DIR } from "./config.js";
5
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";
6
+ import { buildMuxoMcpSkillBundles, getMuxoSkill, listMuxoSkills, renderMuxoSkillMarkdown, } from "./skills-catalog.js";
6
7
  import { MUXO_VERSION } from "./version.js";
7
8
  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, };
8
9
  function sha256Digest(content) {
@@ -123,6 +124,24 @@ Call \`get_profile\` and \`get_organization\` to verify your workspace connectio
123
124
  const setupName = setupFm.name || "setup";
124
125
  const setupDesc = setupFm.description ||
125
126
  "Guided onboarding skill for setting up the Muxo plugin in OpenAI ChatGPT and Codex.";
127
+ const catalogBundles = buildMuxoMcpSkillBundles().map((bundle) => {
128
+ const fileEntries = bundle.files.map((f) => ({
129
+ path: f.path,
130
+ uri: f.uri,
131
+ size: Buffer.byteLength(f.content, "utf8"),
132
+ digest: sha256Digest(f.content),
133
+ mimeType: f.mimeType,
134
+ content: f.content,
135
+ }));
136
+ return {
137
+ name: bundle.name,
138
+ description: bundle.description,
139
+ uri: bundle.uri,
140
+ version: fileEntries[0].digest,
141
+ frontmatter: bundle.frontmatter,
142
+ files: fileEntries,
143
+ };
144
+ });
126
145
  return [
127
146
  {
128
147
  name: muxoName,
@@ -146,6 +165,7 @@ Call \`get_profile\` and \`get_organization\` to verify your workspace connectio
146
165
  },
147
166
  files: setupFiles,
148
167
  },
168
+ ...catalogBundles,
149
169
  ];
150
170
  }
151
171
  export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
@@ -257,9 +277,15 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
257
277
  if (action === "playbooks") {
258
278
  return {
259
279
  ok: true,
260
- playbooks: engine.listCommercialPlaybooks(),
280
+ playbooks: engine.listCommercialPlaybooks(ctx),
261
281
  };
262
282
  }
283
+ if (action === "create_playbook") {
284
+ return engine.createCustomPlaybook(ctx, {
285
+ prompt: prompt || query || String(args.slug || ""),
286
+ input: (args.input || args.arguments) || {},
287
+ });
288
+ }
263
289
  if (action === "run_playbook") {
264
290
  const slug = String(args.slug ||
265
291
  args.playbook ||
@@ -271,6 +297,85 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
271
297
  input: (args.input || args.arguments) || {},
272
298
  });
273
299
  }
300
+ if (action === "rollback_workflow") {
301
+ const wfId = String(args.workflow_id || args.workflowId || args.slug || query || "latest").trim();
302
+ const rolledBack = engine.rollbackDurableWorkflow(ctx, wfId, {
303
+ reason: prompt || query || undefined,
304
+ });
305
+ return {
306
+ ok: true,
307
+ action: "rollback_workflow",
308
+ workflow: rolledBack,
309
+ };
310
+ }
311
+ if (action === "signal_workflow") {
312
+ const wfId = String(args.workflow_id || args.workflowId || args.slug || "latest").trim();
313
+ const signalName = String(args.signal_name ||
314
+ args.signalName ||
315
+ query ||
316
+ "human.approval.granted").trim();
317
+ const signaled = engine.signalDurableWorkflow(ctx, wfId, {
318
+ signalName,
319
+ payload: (args.input || args.arguments) || {},
320
+ });
321
+ return {
322
+ ok: true,
323
+ action: "signal_workflow",
324
+ workflow: signaled,
325
+ };
326
+ }
327
+ if (action === "workflow_history") {
328
+ const wfId = String(args.workflow_id || args.workflowId || args.slug || query || "latest").trim();
329
+ return {
330
+ ok: true,
331
+ action: "workflow_history",
332
+ workflow: engine.getDurableWorkflow(ctx, wfId),
333
+ history: engine.getDurableWorkflowHistory(ctx, wfId),
334
+ };
335
+ }
336
+ if (action === "configure_harness" || action === "harness_presets") {
337
+ return engine.configureHarness(ctx, {
338
+ preset: args.preset ? String(args.preset) : query || null,
339
+ harness: args.harness ? String(args.harness) : null,
340
+ prompt: prompt || null,
341
+ });
342
+ }
343
+ if (action === "reconcile_run") {
344
+ const runId = String(args.run_id || args.runId || args.slug || query || prompt || "latest").trim();
345
+ return engine.reconcileRun(ctx, runId);
346
+ }
347
+ if (action === "skills") {
348
+ const skills = listMuxoSkills({
349
+ category: args.category ? String(args.category) : undefined,
350
+ provider: args.provider ? String(args.provider) : undefined,
351
+ query: query || prompt || undefined,
352
+ }, engine.config.baseUrl);
353
+ return {
354
+ ok: true,
355
+ action: "skills",
356
+ count: skills.length,
357
+ skills,
358
+ };
359
+ }
360
+ if (action === "get_skill" || action === "skill") {
361
+ const skillSlug = String(args.slug ||
362
+ args.skill_slug ||
363
+ args.skillSlug ||
364
+ args.provider ||
365
+ query ||
366
+ prompt ||
367
+ "github-automation").trim();
368
+ const skill = getMuxoSkill(skillSlug, engine.config.baseUrl);
369
+ if (!skill) {
370
+ throw new Error(`Skill '${skillSlug}' not found in Muxo catalog.`);
371
+ }
372
+ return {
373
+ ok: true,
374
+ action: "get_skill",
375
+ skill,
376
+ markdown: renderMuxoSkillMarkdown(skill.slug, engine.config.baseUrl),
377
+ };
378
+ }
274
379
  if (action === "governance_status") {
275
380
  return engine.getGovernanceOverview(ctx);
276
381
  }
@@ -383,8 +488,12 @@ export async function dispatchMcpToolCall(engine, ctx, toolName, args = {}) {
383
488
  explanation: overview.explanation,
384
489
  };
385
490
  }
386
- if (prompt && !action) {
387
- return engine.doNaturalLanguage(ctx, { prompt });
491
+ if (prompt && (!action || action === "inspect")) {
492
+ return engine.doNaturalLanguage(ctx, {
493
+ prompt,
494
+ input: (args.input || args.arguments) ||
495
+ undefined,
496
+ });
388
497
  }
389
498
  const runCtx = await engine.getRunContext(ctx, query);
390
499
  if (args.include_graph === true) {
@@ -733,6 +842,35 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
733
842
  description: "Load the structured LLM Policy & Governance Brief (riskLaneMatrix, conditional parameterRules with compliance guidance, budget caps, kill switch status, and control-plane commands).",
734
843
  arguments: [],
735
844
  },
845
+ {
846
+ name: "harness_setup",
847
+ title: "Turnkey Agent Harness Configuration & Natural-Language Cheatsheet",
848
+ description: "Generate ready-to-paste MCP configuration snippets, system prompt directives, turnkey governance presets (startup-builder, strict-production, read-only-auditor, finops-byok-zero-cost), and natural-language cheatsheets for Claude Code, Cursor, Codex, ChatGPT, Claude Desktop, and Factory Droid.",
849
+ arguments: [
850
+ {
851
+ name: "preset",
852
+ description: "Optional preset slug ('startup-builder', 'strict-production', 'read-only-auditor', 'finops-byok-zero-cost')",
853
+ required: false,
854
+ },
855
+ {
856
+ name: "harness",
857
+ description: "Optional target harness ('claude-code', 'cursor', 'codex', 'chatgpt', 'claude-desktop', 'factory-droid')",
858
+ required: false,
859
+ },
860
+ ],
861
+ },
862
+ {
863
+ name: "commercial_playbook",
864
+ title: "Multi-Step Temporal Saga Playbook Runner & Author",
865
+ description: "List, create, or execute multi-step Temporal-compatible Saga playbooks with automatic LIFO rollback compensations.",
866
+ arguments: [
867
+ {
868
+ name: "playbook",
869
+ description: "Playbook slug or plain-English description (e.g. 'fullstack-cloud-bootstrap', 'competitor-seo-growth-brief', 'incident-containment-audit', 'customer-release-readiness')",
870
+ required: false,
871
+ },
872
+ ],
873
+ },
736
874
  ],
737
875
  },
738
876
  };
@@ -841,6 +979,59 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
841
979
  },
842
980
  };
843
981
  }
982
+ if (promptName === "harness_setup") {
983
+ const bundle = await engine.configureHarness(ctx, {
984
+ preset: promptArgs.preset ? String(promptArgs.preset) : null,
985
+ harness: promptArgs.harness ? String(promptArgs.harness) : null,
986
+ });
987
+ return {
988
+ jsonrpc: "2.0",
989
+ id,
990
+ result: {
991
+ resultType: "complete",
992
+ description: "Turnkey Agent Harness Configuration, Presets, and Natural-Language Cheatsheet",
993
+ messages: [
994
+ {
995
+ role: "user",
996
+ content: {
997
+ type: "text",
998
+ text: [
999
+ bundle.systemPromptDirective,
1000
+ `### Harness Configuration Bundle (JSON)\n\`\`\`json\n${JSON.stringify(bundle, null, 2)}\n\`\`\``,
1001
+ ].join("\n\n"),
1002
+ },
1003
+ },
1004
+ ],
1005
+ },
1006
+ };
1007
+ }
1008
+ if (promptName === "commercial_playbook") {
1009
+ const playbooks = engine.listCommercialPlaybooks(ctx);
1010
+ const requested = promptArgs.playbook ? String(promptArgs.playbook) : "";
1011
+ return {
1012
+ jsonrpc: "2.0",
1013
+ id,
1014
+ result: {
1015
+ resultType: "complete",
1016
+ description: "Multi-Step Temporal Saga Playbook Runner & Author",
1017
+ messages: [
1018
+ {
1019
+ role: "user",
1020
+ content: {
1021
+ type: "text",
1022
+ text: [
1023
+ `# Muxo Multi-Step Temporal Saga Playbooks`,
1024
+ requested
1025
+ ? `Requested Playbook: **${requested}** — call \`get_run_context({ prompt: "Run the ${requested} playbook" })\` or \`get_run_context({ action: "run_playbook", slug: "${requested}" })\`.`
1026
+ : `Call \`get_run_context({ prompt: "Run the fullstack cloud bootstrap playbook" })\` or create a custom playbook in plain English with \`get_run_context({ prompt: "Create playbook daily-seo-slack that runs instant.seo.audit and app.slack.send_message" })\`.`,
1027
+ `### Available Playbooks (${playbooks.length})\n\`\`\`json\n${JSON.stringify(playbooks, null, 2)}\n\`\`\``,
1028
+ ].join("\n\n"),
1029
+ },
1030
+ },
1031
+ ],
1032
+ },
1033
+ };
1034
+ }
844
1035
  return {
845
1036
  jsonrpc: "2.0",
846
1037
  id,
@@ -1027,6 +1218,24 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
1027
1218
  description: "Tamper-evident SHA-256 + portable Ed25519 AgenticReceipt chain verification report.",
1028
1219
  mimeType: "application/json",
1029
1220
  },
1221
+ {
1222
+ uri: "muxo://harness/config",
1223
+ name: "Turnkey Agent Harness Configuration & Presets",
1224
+ description: "Ready-to-paste MCP config snippets, system prompt directives, turnkey governance presets, and natural-language cheatsheet for Claude Code, Cursor, Codex, ChatGPT, Claude Desktop, and Factory Droid.",
1225
+ mimeType: "application/json",
1226
+ },
1227
+ {
1228
+ uri: "muxo://playbooks",
1229
+ name: "Multi-Step Temporal Saga Playbooks",
1230
+ description: "Turnkey and custom workspace Temporal-compatible Saga playbooks with LIFO rollback compensation actions.",
1231
+ mimeType: "application/json",
1232
+ },
1233
+ {
1234
+ uri: "muxo://skills",
1235
+ name: "Muxo Governed Domain & Workflow Skills Catalog",
1236
+ description: "Catalog of transpiled domain automation, zero-OAuth cloud infrastructure (Stripe Projects), and multi-app workflow skills with pitfalls and tool sequences.",
1237
+ mimeType: "application/json",
1238
+ },
1030
1239
  ];
1031
1240
  return {
1032
1241
  jsonrpc: "2.0",
@@ -1218,6 +1427,94 @@ export async function handleJsonRpcMcpRequest(engine, ctx, rpc) {
1218
1427
  },
1219
1428
  };
1220
1429
  }
1430
+ if (uri === "muxo://harness/config") {
1431
+ const bundle = await engine.configureHarness(ctx);
1432
+ return {
1433
+ jsonrpc: "2.0",
1434
+ id,
1435
+ result: {
1436
+ resultType: "complete",
1437
+ ttlMs: 60_000,
1438
+ cacheScope: "private",
1439
+ contents: [
1440
+ {
1441
+ uri,
1442
+ mimeType: "application/json",
1443
+ text: JSON.stringify(bundle, null, 2),
1444
+ },
1445
+ ],
1446
+ },
1447
+ };
1448
+ }
1449
+ if (uri === "muxo://playbooks") {
1450
+ const playbooks = engine.listCommercialPlaybooks(ctx);
1451
+ return {
1452
+ jsonrpc: "2.0",
1453
+ id,
1454
+ result: {
1455
+ resultType: "complete",
1456
+ ttlMs: 60_000,
1457
+ cacheScope: "private",
1458
+ contents: [
1459
+ {
1460
+ uri,
1461
+ mimeType: "application/json",
1462
+ text: JSON.stringify({ ok: true, playbooks }, null, 2),
1463
+ },
1464
+ ],
1465
+ },
1466
+ };
1467
+ }
1468
+ if (uri === "muxo://skills") {
1469
+ const skills = listMuxoSkills();
1470
+ return {
1471
+ jsonrpc: "2.0",
1472
+ id,
1473
+ result: {
1474
+ resultType: "complete",
1475
+ ttlMs: 60_000,
1476
+ cacheScope: "private",
1477
+ contents: [
1478
+ {
1479
+ uri,
1480
+ mimeType: "application/json",
1481
+ text: JSON.stringify({ ok: true, count: skills.length, skills }, null, 2),
1482
+ },
1483
+ ],
1484
+ },
1485
+ };
1486
+ }
1487
+ if (uri.startsWith("muxo://skills/")) {
1488
+ const skillSlug = decodeURIComponent(uri.slice("muxo://skills/".length)).trim();
1489
+ const skillDef = getMuxoSkill(skillSlug);
1490
+ const markdown = renderMuxoSkillMarkdown(skillSlug);
1491
+ if (!skillDef || !markdown) {
1492
+ return {
1493
+ jsonrpc: "2.0",
1494
+ id,
1495
+ error: {
1496
+ code: -32602,
1497
+ message: `Resource not found: ${uri}`,
1498
+ },
1499
+ };
1500
+ }
1501
+ return {
1502
+ jsonrpc: "2.0",
1503
+ id,
1504
+ result: {
1505
+ resultType: "complete",
1506
+ ttlMs: 300_000,
1507
+ cacheScope: "public",
1508
+ contents: [
1509
+ {
1510
+ uri,
1511
+ mimeType: "application/json",
1512
+ text: JSON.stringify({ ok: true, skill: skillDef, markdown }, null, 2),
1513
+ },
1514
+ ],
1515
+ },
1516
+ };
1517
+ }
1221
1518
  if (uri.startsWith("muxo://tools/")) {
1222
1519
  const slug = decodeURIComponent(uri.slice("muxo://tools/".length)).trim();
1223
1520
  try {