@muxoai/platform 1.4.2 → 1.4.4
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 +1 -1
- package/.claude-plugin/marketplace.json +2 -2
- package/README.md +15 -1
- package/dist/cli.js +217 -0
- package/dist/composio-catalog.d.ts +25 -0
- package/dist/composio-catalog.js +145 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/durable-workflow.d.ts +71 -4
- package/dist/durable-workflow.js +199 -5
- package/dist/engine.d.ts +110 -4
- package/dist/engine.js +603 -24
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/mcp-schema.d.ts +14 -0
- package/dist/mcp-schema.js +85 -7
- package/dist/mcp.js +325 -5
- package/dist/memory-graph.d.ts +26 -2
- package/dist/memory-graph.js +127 -7
- package/dist/oss-suite.d.ts +401 -0
- package/dist/oss-suite.js +2065 -0
- package/dist/policy.js +59 -0
- package/dist/providers/composio-instant.js +54 -36
- package/dist/providers/composio-sdk.d.ts +10 -1
- package/dist/providers/composio-sdk.js +144 -31
- package/dist/sdk.d.ts +43 -1
- package/dist/sdk.js +85 -2
- package/dist/server.js +231 -3
- package/dist/skills-catalog.d.ts +66 -0
- package/dist/skills-catalog.js +801 -0
- package/dist/types.d.ts +51 -1
- package/dist/ui/console-html.js +23 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/plugins/muxo/.claude-plugin/plugin.json +1 -1
- package/plugins/muxo/.codex-plugin/plugin.json +2 -2
- package/plugins/muxo/.cursor-plugin/plugin.json +1 -1
- package/plugins/muxo/plugin.json +2 -2
- package/plugins/muxo/skills/muxo/SKILL.md +13 -3
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"plugins": [
|
|
7
7
|
{
|
|
8
8
|
"name": "muxo",
|
|
9
|
-
"version": "1.4.
|
|
9
|
+
"version": "1.4.4",
|
|
10
10
|
"description": "Governed execution across 1,000+ Connected Apps, Instant Tools (search, scrape, crawl, SEO audit), Cloud Infrastructure provisioning, Workspace Memory recall, and cryptographic execution receipts.",
|
|
11
11
|
"source": {
|
|
12
12
|
"source": "local",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"metadata": {
|
|
10
10
|
"description": "Official Muxo plugin marketplace for governed execution across Connected Apps, Instant Tools, Cloud Infrastructure, and Workspace Memory.",
|
|
11
|
-
"version": "1.4.
|
|
11
|
+
"version": "1.4.4"
|
|
12
12
|
},
|
|
13
13
|
"plugins": [
|
|
14
14
|
{
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"strict": false,
|
|
21
21
|
"description": "Governed execution across 1,000+ Connected Apps, Instant Tools (search, scrape, crawl, SEO audit), Cloud Infrastructure provisioning, Workspace Memory recall, and verifiable audit records.",
|
|
22
|
-
"version": "1.4.
|
|
22
|
+
"version": "1.4.4",
|
|
23
23
|
"category": "Productivity",
|
|
24
24
|
"skills": [
|
|
25
25
|
"./plugins/muxo/skills/muxo",
|
package/README.md
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
# Muxo (`@muxoai/platform` / `@muxoai/cli` / `@muxoai/sdk`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Let your AI agents take action across business apps, with approvals, spending controls, and proof of what happened.**
|
|
4
|
+
|
|
5
|
+
Muxo (`v1.4.4`) is the governed action, workflow automation, cloud provisioning, and business-receipt platform for AI agents and B2B SaaS teams. Before any external write or provisioning action runs, Muxo shows **what changes**, **who is affected**, **the estimated USD cost (`$X.XX` alongside credits or `$0.00` BYOK)**, and **which guardrail triggered approval**. After execution, Muxo issues both a **business-facing receipt** (*what changed, who authorized it, what succeeded, what remains unresolved, and exact USD/credit cost*) and a **cryptographic Ed25519 + SHA-256 audit receipt**.
|
|
6
|
+
|
|
7
|
+
Customers and their agents interact exclusively with **Muxo** — either via tested workflow packs, structured tool slugs, or free-form **Natural Language** (`muxo do`, `POST /api/v1/do`, `client.do()`, and MCP `plan_action`).
|
|
4
8
|
|
|
5
9
|
See [`ARCHITECTURE.md`](./ARCHITECTURE.md) for the complete internal engineering blueprint, open-source ecosystem Keep/Adopt/Drop matrix, and 4-pillar architecture.
|
|
6
10
|
|
|
11
|
+
### Tested Commercial Workflow Packs (`muxo playbooks` / `POST /api/v1/playbooks/:slug/run`)
|
|
12
|
+
Muxo ships **7 tested workflow templates** with explicit required connections, permissions, approval rules, upfront USD/credit cost estimates, failure & compensation behavior, and structured business deliverables:
|
|
13
|
+
1. **`customer-operations-agent`** — *Customer Operations Account Change, Approval & Receipt Saga* (`$0.05 USD` / 5 credits; reads support request, looks up customer context, proposes governed CRM/billing update with approval preview, posts verified receipt).
|
|
14
|
+
2. **`customer-onboarding-automation`** — *Agent-Powered Customer Onboarding & Tenant Provisioning* (`$0.30 USD` / 30 credits; provisions dedicated tenant database, configures workspace tracker, sends onboarding confirmation with rollback protection).
|
|
15
|
+
3. **`agency-workspace-automation`** — *Multi-Client Agency Workspace, Budget & Reporting Pack* (`$0.06 USD` / 6 credits; runs client audit, updates client deliverable board, and dispatches itemized USD/credit usage & receipt digest).
|
|
16
|
+
4. **`fullstack-cloud-bootstrap`** — *Full-Stack Cloud Database, Cache & Edge Bootstrap* (`$0.52 USD` / 52 credits).
|
|
17
|
+
5. **`competitor-seo-growth-brief`** — *Autonomous Competitor & SEO Executive Brief* (`$0.06 USD` / 6 credits).
|
|
18
|
+
6. **`incident-containment-audit`** — *Zero-Trust Incident Containment & WORM Forensic Audit* (`$0.05 USD` / 5 credits).
|
|
19
|
+
7. **`customer-release-readiness`** — *Customer Release Readiness & Security Sign-Off* (`$0.05 USD` / 5 credits).
|
|
20
|
+
|
|
7
21
|
Under the hood, Muxo unifies **four core pillars** plus **Natural Language Routing** and **BYOK (Bring Your Own Key) 0-Credit Execution** behind one **19-operation MCP contract**, OpenAI Plugin (`agent-plugins.org/1.0.0`), REST API, Interactive CLI/TUI (`@muxoai/cli`), TypeScript SDK (`@muxoai/sdk`), and Web Console (`https://app.muxo.ai`):
|
|
8
22
|
|
|
9
23
|
1. **Connected Apps (`app.*`) & Instant Tools (`instant.*`)** — Managed OAuth SaaS integrations (`app.github.*`, `app.gmail.*`, `app.slack.*`, `app.notion.*`, `app.linear.*`) with live browser OAuth handoff (`wait_for_connection`), zero-OAuth instant capabilities (`instant.web.search`, `instant.web.scrape`, `instant.web.crawl`, `instant.seo.audit`, `instant.hackernews.top_stories`, `instant.github.repo_intel`, `instant.dns.lookup`, `instant.composio.workbench`), plus **CLI-first Autonomous 2-Call Agent Signup & Claim** (`POST /api/v1/agents/signup` + `POST /api/v1/agents/claim`).
|
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,7 @@ import { handleJsonRpcMcpRequest, LATEST_MCP_PROTOCOL_VERSION } from "./mcp.js";
|
|
|
9
9
|
import { DEFAULT_WORKSPACE_POLICY, describePolicyInPlainEnglish, sanitizePolicyPatch, } from "./policy.js";
|
|
10
10
|
import { RING_LABELS } from "./providers/microsoft-governance.js";
|
|
11
11
|
import { BYOK_PROVIDER_CATALOG, MuxoStore } from "./store.js";
|
|
12
|
+
import { buildMuxoMcpSkillBundles, getMuxoSkill, listMuxoSkills, renderMuxoSkillMarkdown, } from "./skills-catalog.js";
|
|
12
13
|
import { MUXO_VERSION } from "./version.js";
|
|
13
14
|
function promptUserLine(question) {
|
|
14
15
|
return new Promise((resolve) => {
|
|
@@ -578,6 +579,30 @@ async function runCli() {
|
|
|
578
579
|
return;
|
|
579
580
|
}
|
|
580
581
|
if (cmd === "harness") {
|
|
582
|
+
const sub = positional[1];
|
|
583
|
+
if (sub === "configure" ||
|
|
584
|
+
sub === "config" ||
|
|
585
|
+
sub === "preset" ||
|
|
586
|
+
sub === "presets" ||
|
|
587
|
+
Boolean(flags.preset)) {
|
|
588
|
+
const preset = (typeof flags.preset === "string" ? flags.preset : undefined) ||
|
|
589
|
+
(sub === "preset" || sub === "configure" || sub === "config"
|
|
590
|
+
? positional[2]
|
|
591
|
+
: undefined);
|
|
592
|
+
const harness = typeof flags.harness === "string" ? flags.harness : positional[3];
|
|
593
|
+
const prompt = typeof flags.prompt === "string" ? flags.prompt : undefined;
|
|
594
|
+
if (remoteUrl) {
|
|
595
|
+
const res = await remoteFetch("/api/v1/harness/configure", {
|
|
596
|
+
method: "POST",
|
|
597
|
+
body: { preset, harness, prompt },
|
|
598
|
+
});
|
|
599
|
+
console.log(JSON.stringify(res, null, 2));
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const { engine, ctx } = getLocalContext();
|
|
603
|
+
console.log(JSON.stringify(engine.configureHarness(ctx, { preset, harness, prompt }), null, 2));
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
581
606
|
const checks = [];
|
|
582
607
|
const skip = (reason) => ({ skip: reason });
|
|
583
608
|
const runCheck = async (id, name, fn) => {
|
|
@@ -2285,6 +2310,193 @@ async function runCli() {
|
|
|
2285
2310
|
});
|
|
2286
2311
|
return;
|
|
2287
2312
|
}
|
|
2313
|
+
if (cmd === "playbooks" || cmd === "playbook") {
|
|
2314
|
+
const sub = positional[1];
|
|
2315
|
+
if (sub === "create" || sub === "add" || sub === "define") {
|
|
2316
|
+
const prompt = positional.slice(2).join(" ").trim();
|
|
2317
|
+
const input = flags.input
|
|
2318
|
+
? JSON.parse(String(flags.input))
|
|
2319
|
+
: {};
|
|
2320
|
+
if (remoteUrl) {
|
|
2321
|
+
const res = await remoteFetch("/api/v1/playbooks", {
|
|
2322
|
+
method: "POST",
|
|
2323
|
+
body: { prompt, ...input },
|
|
2324
|
+
});
|
|
2325
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
const { engine, ctx } = getLocalContext();
|
|
2329
|
+
const res = engine.createCustomPlaybook(ctx, { prompt, input });
|
|
2330
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
if (sub === "run") {
|
|
2334
|
+
const slug = positional[2] ||
|
|
2335
|
+
flags.slug ||
|
|
2336
|
+
"fullstack-cloud-bootstrap";
|
|
2337
|
+
const input = flags.input
|
|
2338
|
+
? JSON.parse(String(flags.input))
|
|
2339
|
+
: {};
|
|
2340
|
+
if (remoteUrl) {
|
|
2341
|
+
const res = await remoteFetch(`/api/v1/playbooks/${encodeURIComponent(slug)}/run`, {
|
|
2342
|
+
method: "POST",
|
|
2343
|
+
body: { input },
|
|
2344
|
+
});
|
|
2345
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
const { engine, ctx } = getLocalContext();
|
|
2349
|
+
const res = engine.runCommercialPlaybook(ctx, { slug, input });
|
|
2350
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2351
|
+
return;
|
|
2352
|
+
}
|
|
2353
|
+
if (remoteUrl) {
|
|
2354
|
+
const res = await remoteFetch("/api/v1/playbooks");
|
|
2355
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
const { engine, ctx } = getLocalContext();
|
|
2359
|
+
const playbooks = engine.listCommercialPlaybooks(ctx);
|
|
2360
|
+
console.log(JSON.stringify({ ok: true, count: playbooks.length, playbooks }, null, 2));
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
if (cmd === "roi") {
|
|
2364
|
+
if (remoteUrl) {
|
|
2365
|
+
const res = await remoteFetch("/api/v1/analytics/roi");
|
|
2366
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2367
|
+
return;
|
|
2368
|
+
}
|
|
2369
|
+
const { engine, ctx } = getLocalContext();
|
|
2370
|
+
console.log(JSON.stringify({ ok: true, ...engine.getCommercialRoiReport(ctx) }, null, 2));
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
if (cmd === "cedar") {
|
|
2374
|
+
const sub = positional[1];
|
|
2375
|
+
if (sub === "evaluate" || sub === "eval") {
|
|
2376
|
+
const toolSlug = positional[2] || flags.tool || "instant.web.search";
|
|
2377
|
+
const input = flags.input
|
|
2378
|
+
? JSON.parse(String(flags.input))
|
|
2379
|
+
: {};
|
|
2380
|
+
if (remoteUrl) {
|
|
2381
|
+
const res = await remoteFetch("/api/v1/governance/cedar/evaluate", {
|
|
2382
|
+
method: "POST",
|
|
2383
|
+
body: { toolSlug, input },
|
|
2384
|
+
});
|
|
2385
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
const { engine, ctx } = getLocalContext();
|
|
2389
|
+
console.log(JSON.stringify({
|
|
2390
|
+
ok: true,
|
|
2391
|
+
...engine.evaluatePolicyAsCode(ctx, { toolSlug, input }),
|
|
2392
|
+
}, null, 2));
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
if (remoteUrl) {
|
|
2396
|
+
const res = await remoteFetch("/api/v1/governance/cedar");
|
|
2397
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2398
|
+
return;
|
|
2399
|
+
}
|
|
2400
|
+
const { engine, ctx } = getLocalContext();
|
|
2401
|
+
console.log(JSON.stringify({ ok: true, ...engine.getPolicyAsCodeBundle(ctx) }, null, 2));
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
if (cmd === "telemetry" || cmd === "otel") {
|
|
2405
|
+
const limit = flags.limit ? Number(flags.limit) : 25;
|
|
2406
|
+
if (remoteUrl) {
|
|
2407
|
+
const res = await remoteFetch(`/api/v1/telemetry/otlp?limit=${limit}`);
|
|
2408
|
+
console.log(JSON.stringify(res, null, 2));
|
|
2409
|
+
return;
|
|
2410
|
+
}
|
|
2411
|
+
const { engine, ctx } = getLocalContext();
|
|
2412
|
+
console.log(JSON.stringify({ ok: true, ...engine.exportOtelTraces(ctx, limit) }, null, 2));
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
if (cmd === "skills" || cmd === "skill") {
|
|
2416
|
+
const sub = (positional[1] || "list").toLowerCase();
|
|
2417
|
+
const baseUrlForSkill = remoteUrl || "https://api.muxo.ai";
|
|
2418
|
+
if (sub === "list" || sub === "ls") {
|
|
2419
|
+
const category = typeof flags.category === "string" ? flags.category : undefined;
|
|
2420
|
+
const provider = typeof flags.provider === "string" ? flags.provider : undefined;
|
|
2421
|
+
const query = typeof flags.query === "string"
|
|
2422
|
+
? flags.query
|
|
2423
|
+
: typeof flags.q === "string"
|
|
2424
|
+
? flags.q
|
|
2425
|
+
: positional[2];
|
|
2426
|
+
const skills = listMuxoSkills({ category, provider, query }, baseUrlForSkill);
|
|
2427
|
+
console.log(JSON.stringify({
|
|
2428
|
+
ok: true,
|
|
2429
|
+
count: skills.length,
|
|
2430
|
+
skills: skills.map((s) => ({
|
|
2431
|
+
slug: s.slug,
|
|
2432
|
+
title: s.title,
|
|
2433
|
+
category: s.category,
|
|
2434
|
+
lane: s.lane,
|
|
2435
|
+
providerSlug: s.providerSlug,
|
|
2436
|
+
recommendedTools: s.recommendedTools,
|
|
2437
|
+
skillUrl: `${baseUrlForSkill}/skills/${s.slug}/SKILL.md`,
|
|
2438
|
+
mcpResourceUri: `muxo://skills/${s.slug}`,
|
|
2439
|
+
})),
|
|
2440
|
+
}, null, 2));
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
if (sub === "show" || sub === "get" || sub === "inspect") {
|
|
2444
|
+
const slug = positional[2] || "github-automation";
|
|
2445
|
+
const skill = getMuxoSkill(slug, baseUrlForSkill);
|
|
2446
|
+
const markdown = renderMuxoSkillMarkdown(slug, baseUrlForSkill);
|
|
2447
|
+
if (!skill || !markdown) {
|
|
2448
|
+
console.error(`Skill not found: ${slug}`);
|
|
2449
|
+
process.exitCode = 1;
|
|
2450
|
+
return;
|
|
2451
|
+
}
|
|
2452
|
+
if (flags.json) {
|
|
2453
|
+
console.log(JSON.stringify({ ok: true, skill, markdown }, null, 2));
|
|
2454
|
+
}
|
|
2455
|
+
else {
|
|
2456
|
+
console.log(markdown);
|
|
2457
|
+
}
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
if (sub === "install" || sub === "add") {
|
|
2461
|
+
const targetRoot = typeof flags.dir === "string"
|
|
2462
|
+
? path.resolve(flags.dir)
|
|
2463
|
+
: flags.agents
|
|
2464
|
+
? path.resolve(process.cwd(), ".agents", "skills")
|
|
2465
|
+
: path.resolve(process.cwd(), ".claude", "skills");
|
|
2466
|
+
const slugsToInstall = flags["all-curated"]
|
|
2467
|
+
? buildMuxoMcpSkillBundles(baseUrlForSkill).map((b) => b.name)
|
|
2468
|
+
: [positional[2] || "github-automation"];
|
|
2469
|
+
const installed = [];
|
|
2470
|
+
for (const rawSlug of slugsToInstall) {
|
|
2471
|
+
const skill = getMuxoSkill(rawSlug, baseUrlForSkill);
|
|
2472
|
+
const markdown = renderMuxoSkillMarkdown(rawSlug, baseUrlForSkill);
|
|
2473
|
+
if (!skill || !markdown) {
|
|
2474
|
+
console.error(`Skill not found: ${rawSlug}`);
|
|
2475
|
+
process.exitCode = 1;
|
|
2476
|
+
return;
|
|
2477
|
+
}
|
|
2478
|
+
const skillDir = path.join(targetRoot, skill.slug);
|
|
2479
|
+
fs.mkdirSync(skillDir, { recursive: true });
|
|
2480
|
+
const filePath = path.join(skillDir, "SKILL.md");
|
|
2481
|
+
fs.writeFileSync(filePath, markdown, "utf8");
|
|
2482
|
+
installed.push({ slug: skill.slug, path: filePath });
|
|
2483
|
+
}
|
|
2484
|
+
console.log(JSON.stringify({
|
|
2485
|
+
ok: true,
|
|
2486
|
+
installedCount: installed.length,
|
|
2487
|
+
targetRoot,
|
|
2488
|
+
installed,
|
|
2489
|
+
}, null, 2));
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
// Default: if `muxo skills <slug>` was called directly
|
|
2493
|
+
const directSkill = getMuxoSkill(sub, baseUrlForSkill);
|
|
2494
|
+
const directMd = renderMuxoSkillMarkdown(sub, baseUrlForSkill);
|
|
2495
|
+
if (directSkill && directMd) {
|
|
2496
|
+
console.log(flags.json ? JSON.stringify({ ok: true, skill: directSkill, markdown: directMd }, null, 2) : directMd);
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2288
2500
|
// Natural Language fallback: if user passed plain English directly (`muxo "Audit https://muxo.ai for SEO"`)
|
|
2289
2501
|
if (cmd !== "help" && !flags.help && !flags.h && positional.length > 0) {
|
|
2290
2502
|
const promptText = positional.join(" ").trim();
|
|
@@ -2365,6 +2577,11 @@ Core Commands:
|
|
|
2365
2577
|
muxo governance scan <text> Check text for prompt injection before storing or sending it
|
|
2366
2578
|
muxo governance policy [--mode enforce|monitor] [--ring 0-3] [--require-approval write,admin|none]
|
|
2367
2579
|
[--block-destructive-sql true|false] [--max-credits <n>]
|
|
2580
|
+
muxo cedar [evaluate <tool_slug>] Compile or evaluate AWS Cedar 4.x & OPA Rego v1 policy-as-code
|
|
2581
|
+
muxo telemetry [--limit 25] Export OpenTelemetry GenAI / MCP OTLP & Langfuse trace spans
|
|
2582
|
+
muxo playbooks [run <slug>] List or execute Temporal-compatible commercial Saga playbooks
|
|
2583
|
+
muxo skills [list|show|install] [<slug>] Browse or install governed domain & workflow SKILL.md playbooks
|
|
2584
|
+
muxo roi Compute FinOps unit economics, BYOK savings, and engineering ROI
|
|
2368
2585
|
muxo harness Check API, MCP, auth, governance and catalog; print MCP config
|
|
2369
2586
|
muxo serve [--port 4310] Start unified HTTP Console, Landing, OAuth Callback & MCP server
|
|
2370
2587
|
muxo mcp Run stdio MCP server (19 canonical tools)
|
|
@@ -232,3 +232,28 @@ export declare function renderDefaultHostedSiteHtml(params: {
|
|
|
232
232
|
providerSlug: string;
|
|
233
233
|
liveUrl: string;
|
|
234
234
|
}): string;
|
|
235
|
+
export type ComposioMcpGatewayMetaTool = "COMPOSIO_SEARCH_TOOLS" | "COMPOSIO_GET_TOOL_SCHEMAS" | "COMPOSIO_MANAGE_CONNECTIONS" | "COMPOSIO_MULTI_EXECUTE_TOOL" | "COMPOSIO_REMOTE_WORKBENCH" | "COMPOSIO_WAIT_FOR_CONNECTIONS";
|
|
236
|
+
export interface ComposioMcpGatewayCallOptions {
|
|
237
|
+
apiKey: string;
|
|
238
|
+
gatewayUrl?: string | null;
|
|
239
|
+
workspaceId?: string;
|
|
240
|
+
sessionId?: string;
|
|
241
|
+
usingCustomerByok?: boolean;
|
|
242
|
+
isReadOnly?: boolean;
|
|
243
|
+
timeoutMs?: number;
|
|
244
|
+
fetchImpl?: typeof fetch;
|
|
245
|
+
}
|
|
246
|
+
export interface ComposioMcpGatewayResult {
|
|
247
|
+
ok: boolean;
|
|
248
|
+
gatewayUrl: string;
|
|
249
|
+
metaTool: ComposioMcpGatewayMetaTool | string;
|
|
250
|
+
data: Record<string, unknown> | null;
|
|
251
|
+
error?: string;
|
|
252
|
+
}
|
|
253
|
+
export declare function canUseComposioMcpGatewayForExecution(opts: {
|
|
254
|
+
apiKey?: string | null;
|
|
255
|
+
gatewayUrl?: string | null;
|
|
256
|
+
usingCustomerByok?: boolean;
|
|
257
|
+
isReadOnly?: boolean;
|
|
258
|
+
}): boolean;
|
|
259
|
+
export declare function callComposioMcpGatewayRpc(metaTool: ComposioMcpGatewayMetaTool | string, toolArgs: Record<string, unknown>, options: ComposioMcpGatewayCallOptions): Promise<ComposioMcpGatewayResult>;
|
package/dist/composio-catalog.js
CHANGED
|
@@ -1892,3 +1892,148 @@ export function renderDefaultHostedSiteHtml(params) {
|
|
|
1892
1892
|
</body>
|
|
1893
1893
|
</html>`;
|
|
1894
1894
|
}
|
|
1895
|
+
export function canUseComposioMcpGatewayForExecution(opts) {
|
|
1896
|
+
const key = String(opts.apiKey || "").trim();
|
|
1897
|
+
if (!key)
|
|
1898
|
+
return false;
|
|
1899
|
+
const url = String(opts.gatewayUrl || "").trim();
|
|
1900
|
+
const isCustomTeamGateway = Boolean(url) &&
|
|
1901
|
+
url !== "https://connect.composio.dev/mcp" &&
|
|
1902
|
+
(url.includes("mcp.composio.dev/t/") || !url.includes("connect.composio.dev"));
|
|
1903
|
+
const isConsumerKey = key.startsWith("ck_");
|
|
1904
|
+
if (isCustomTeamGateway || isConsumerKey || opts.usingCustomerByok) {
|
|
1905
|
+
return true;
|
|
1906
|
+
}
|
|
1907
|
+
return Boolean(opts.isReadOnly);
|
|
1908
|
+
}
|
|
1909
|
+
export async function callComposioMcpGatewayRpc(metaTool, toolArgs, options) {
|
|
1910
|
+
const gatewayUrl = (options.gatewayUrl || "").trim() || "https://connect.composio.dev/mcp";
|
|
1911
|
+
const apiKey = (options.apiKey || "").trim();
|
|
1912
|
+
if (!apiKey) {
|
|
1913
|
+
return {
|
|
1914
|
+
ok: false,
|
|
1915
|
+
gatewayUrl,
|
|
1916
|
+
metaTool,
|
|
1917
|
+
data: null,
|
|
1918
|
+
error: "Missing Composio API key for MCP Gateway call",
|
|
1919
|
+
};
|
|
1920
|
+
}
|
|
1921
|
+
const fetchFn = options.fetchImpl || fetch;
|
|
1922
|
+
const timeoutMs = options.timeoutMs ?? 6000;
|
|
1923
|
+
try {
|
|
1924
|
+
const res = await fetchFn(gatewayUrl, {
|
|
1925
|
+
method: "POST",
|
|
1926
|
+
headers: {
|
|
1927
|
+
"Content-Type": "application/json",
|
|
1928
|
+
Accept: "application/json, text/event-stream",
|
|
1929
|
+
"x-consumer-api-key": apiKey,
|
|
1930
|
+
"x-api-key": apiKey,
|
|
1931
|
+
...(options.workspaceId ? { "x-user-id": options.workspaceId } : {}),
|
|
1932
|
+
},
|
|
1933
|
+
body: JSON.stringify({
|
|
1934
|
+
jsonrpc: "2.0",
|
|
1935
|
+
id: `muxo_gw_${Date.now()}`,
|
|
1936
|
+
method: "tools/call",
|
|
1937
|
+
params: {
|
|
1938
|
+
name: metaTool,
|
|
1939
|
+
arguments: toolArgs,
|
|
1940
|
+
},
|
|
1941
|
+
}),
|
|
1942
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
1943
|
+
});
|
|
1944
|
+
if (!res.ok) {
|
|
1945
|
+
return {
|
|
1946
|
+
ok: false,
|
|
1947
|
+
gatewayUrl,
|
|
1948
|
+
metaTool,
|
|
1949
|
+
data: null,
|
|
1950
|
+
error: `Composio MCP Gateway returned HTTP ${res.status}`,
|
|
1951
|
+
};
|
|
1952
|
+
}
|
|
1953
|
+
const rawText = await res.text();
|
|
1954
|
+
let rpcPayload = null;
|
|
1955
|
+
const trimmed = rawText.trim();
|
|
1956
|
+
if (trimmed.startsWith("{")) {
|
|
1957
|
+
rpcPayload = JSON.parse(trimmed);
|
|
1958
|
+
}
|
|
1959
|
+
else {
|
|
1960
|
+
for (const line of trimmed.split(/\r?\n/)) {
|
|
1961
|
+
const clean = line.trim();
|
|
1962
|
+
if (clean.startsWith("data:")) {
|
|
1963
|
+
const dataStr = clean.slice(5).trim();
|
|
1964
|
+
if (dataStr && dataStr.startsWith("{")) {
|
|
1965
|
+
rpcPayload = JSON.parse(dataStr);
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
if (!rpcPayload || rpcPayload.error) {
|
|
1971
|
+
const errObj = rpcPayload?.error;
|
|
1972
|
+
return {
|
|
1973
|
+
ok: false,
|
|
1974
|
+
gatewayUrl,
|
|
1975
|
+
metaTool,
|
|
1976
|
+
data: null,
|
|
1977
|
+
error: String(errObj?.message || "Invalid JSON-RPC response from Composio MCP Gateway"),
|
|
1978
|
+
};
|
|
1979
|
+
}
|
|
1980
|
+
const resultObj = (rpcPayload.result || {});
|
|
1981
|
+
if (resultObj.isError === true) {
|
|
1982
|
+
return {
|
|
1983
|
+
ok: false,
|
|
1984
|
+
gatewayUrl,
|
|
1985
|
+
metaTool,
|
|
1986
|
+
data: null,
|
|
1987
|
+
error: "Composio MCP Gateway tool returned isError=true",
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
if (resultObj.structuredContent && typeof resultObj.structuredContent === "object") {
|
|
1991
|
+
return {
|
|
1992
|
+
ok: true,
|
|
1993
|
+
gatewayUrl,
|
|
1994
|
+
metaTool,
|
|
1995
|
+
data: resultObj.structuredContent,
|
|
1996
|
+
};
|
|
1997
|
+
}
|
|
1998
|
+
const contentArr = Array.isArray(resultObj.content)
|
|
1999
|
+
? resultObj.content
|
|
2000
|
+
: [];
|
|
2001
|
+
const firstText = contentArr.find((c) => typeof c.text === "string")?.text;
|
|
2002
|
+
if (firstText) {
|
|
2003
|
+
try {
|
|
2004
|
+
const parsed = JSON.parse(firstText);
|
|
2005
|
+
if (parsed && typeof parsed === "object") {
|
|
2006
|
+
return {
|
|
2007
|
+
ok: true,
|
|
2008
|
+
gatewayUrl,
|
|
2009
|
+
metaTool,
|
|
2010
|
+
data: parsed,
|
|
2011
|
+
};
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
catch {
|
|
2015
|
+
return {
|
|
2016
|
+
ok: true,
|
|
2017
|
+
gatewayUrl,
|
|
2018
|
+
metaTool,
|
|
2019
|
+
data: { text: firstText },
|
|
2020
|
+
};
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
return {
|
|
2024
|
+
ok: true,
|
|
2025
|
+
gatewayUrl,
|
|
2026
|
+
metaTool,
|
|
2027
|
+
data: resultObj,
|
|
2028
|
+
};
|
|
2029
|
+
}
|
|
2030
|
+
catch (err) {
|
|
2031
|
+
return {
|
|
2032
|
+
ok: false,
|
|
2033
|
+
gatewayUrl,
|
|
2034
|
+
metaTool,
|
|
2035
|
+
data: null,
|
|
2036
|
+
error: String(err?.message || err || "Composio MCP Gateway request failed"),
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
}
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -70,6 +70,7 @@ export function getConfig() {
|
|
|
70
70
|
? ""
|
|
71
71
|
: process.env.COMPOSIO_INSTANT_API_KEY || process.env.COMPOSIO_API_KEY || "",
|
|
72
72
|
composioBaseUrl: process.env.COMPOSIO_BASE_URL || "https://backend.composio.dev/api/v3",
|
|
73
|
+
composioMcpGatewayUrl: process.env.COMPOSIO_MCP_GATEWAY_URL || "https://connect.composio.dev/mcp",
|
|
73
74
|
composioWebhookSecret: process.env.MUXO_EXTERNAL_MODE === "1"
|
|
74
75
|
? ""
|
|
75
76
|
: process.env.COMPOSIO_WEBHOOK_SECRET || "",
|
|
@@ -1,22 +1,54 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Temporal-compatible Durable Workflows, Saga Compensations, Signals, and Cloudflare Workflows primitives,
|
|
3
|
+
* shared by the Node engine (src/engine.ts) and the Cloudflare Edge Worker (worker/index.ts).
|
|
4
|
+
*/
|
|
2
5
|
import { MuxoToolError } from "./mcp-schema.js";
|
|
3
|
-
export type DurableWorkflowStepStatus = "completed" | "waiting" | "pending";
|
|
6
|
+
export type DurableWorkflowStepStatus = "completed" | "waiting" | "pending" | "failed" | "compensated";
|
|
4
7
|
export interface DurableWorkflowStep {
|
|
5
8
|
name: string;
|
|
6
9
|
primitive: "step.do" | "step.waitForEvent" | "step.sleep";
|
|
7
10
|
status: DurableWorkflowStepStatus;
|
|
8
11
|
output?: Record<string, unknown>;
|
|
9
12
|
completedAt?: string;
|
|
13
|
+
compensationAction?: string;
|
|
14
|
+
compensatedAt?: string;
|
|
15
|
+
}
|
|
16
|
+
export type TemporalEventType = "EVENT_TYPE_WORKFLOW_EXECUTION_STARTED" | "EVENT_TYPE_ACTIVITY_TASK_SCHEDULED" | "EVENT_TYPE_ACTIVITY_TASK_COMPLETED" | "EVENT_TYPE_ACTIVITY_TASK_FAILED" | "EVENT_TYPE_WORKFLOW_EXECUTION_SIGNALED" | "EVENT_TYPE_TIMER_STARTED" | "EVENT_TYPE_TIMER_FIRED" | "EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED" | "EVENT_TYPE_WORKFLOW_EXECUTION_CANCELED" | "EVENT_TYPE_WORKFLOW_EXECUTION_FAILED";
|
|
17
|
+
export interface TemporalHistoryEvent {
|
|
18
|
+
eventId: number;
|
|
19
|
+
eventTime: string;
|
|
20
|
+
eventType: TemporalEventType;
|
|
21
|
+
taskQueue: string;
|
|
22
|
+
attributes: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
export interface SagaCompensationRecord {
|
|
25
|
+
stepName: string;
|
|
26
|
+
compensationAction: string;
|
|
27
|
+
status: "registered" | "executed" | "skipped";
|
|
28
|
+
description: string;
|
|
29
|
+
output?: Record<string, unknown>;
|
|
30
|
+
executedAt?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface DurableWorkflowSignalRecord {
|
|
33
|
+
signalName: string;
|
|
34
|
+
payload: Record<string, unknown>;
|
|
35
|
+
receivedAt: string;
|
|
10
36
|
}
|
|
11
37
|
export interface DurableWorkflow {
|
|
12
38
|
id: string;
|
|
39
|
+
runId?: string;
|
|
13
40
|
workspaceId: string;
|
|
14
|
-
workflowType: "cloud_provisioning_pipeline" | "approval_handoff_pipeline";
|
|
15
|
-
|
|
41
|
+
workflowType: "cloud_provisioning_pipeline" | "approval_handoff_pipeline" | "commercial_playbook_saga";
|
|
42
|
+
playbookSlug?: string | null;
|
|
43
|
+
status: "running" | "waiting_for_event" | "completed" | "failed" | "rolled_back";
|
|
16
44
|
provider: string;
|
|
17
45
|
serviceRef: string;
|
|
18
46
|
resourceId: string | null;
|
|
19
47
|
steps: DurableWorkflowStep[];
|
|
48
|
+
compensations?: SagaCompensationRecord[];
|
|
49
|
+
signals?: DurableWorkflowSignalRecord[];
|
|
50
|
+
temporalEventHistory?: TemporalHistoryEvent[];
|
|
51
|
+
rollbackReason?: string | null;
|
|
20
52
|
createdAt: string;
|
|
21
53
|
updatedAt: string;
|
|
22
54
|
}
|
|
@@ -43,3 +75,38 @@ export declare function completeCloudProvisioningWorkflow(wf: DurableWorkflow, p
|
|
|
43
75
|
secretKeys: string[];
|
|
44
76
|
triggerEvent?: unknown;
|
|
45
77
|
}): DurableWorkflow;
|
|
78
|
+
/**
|
|
79
|
+
* Executes LIFO Saga Compensations on a DurableWorkflow, rolling back completed steps in reverse order
|
|
80
|
+
* and recording Temporal compensation activity events.
|
|
81
|
+
*/
|
|
82
|
+
export declare function rollbackDurableWorkflow(wf: DurableWorkflow, params?: {
|
|
83
|
+
reason?: string;
|
|
84
|
+
failedStepName?: string;
|
|
85
|
+
failedStep?: string;
|
|
86
|
+
}): DurableWorkflow;
|
|
87
|
+
/**
|
|
88
|
+
* Sends a named Temporal signal to a DurableWorkflow (`human.approval.granted`, `oauth.connection.active`,
|
|
89
|
+
* `saga.abort`, or `v2.provisioning.resource.completed`).
|
|
90
|
+
*/
|
|
91
|
+
export declare function signalDurableWorkflow(wf: DurableWorkflow, params: {
|
|
92
|
+
signalName: string;
|
|
93
|
+
payload?: Record<string, unknown>;
|
|
94
|
+
secretKeys?: string[];
|
|
95
|
+
}): DurableWorkflow;
|
|
96
|
+
/**
|
|
97
|
+
* Exports a DurableWorkflow in Temporal Web UI / `temporal workflow show` compatible EventHistory JSON format.
|
|
98
|
+
*/
|
|
99
|
+
export declare function exportTemporalEventHistory(wf: DurableWorkflow): {
|
|
100
|
+
namespace: string;
|
|
101
|
+
workflowExecution: {
|
|
102
|
+
workflowId: string;
|
|
103
|
+
runId: string;
|
|
104
|
+
};
|
|
105
|
+
workflowType: {
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
status: DurableWorkflow["status"];
|
|
109
|
+
eventsCount: number;
|
|
110
|
+
compensationsCount: number;
|
|
111
|
+
events: TemporalHistoryEvent[];
|
|
112
|
+
};
|