@muxoai/platform 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk.d.ts CHANGED
@@ -156,6 +156,13 @@ export declare class MuxoClient {
156
156
  totalCustomerChargedCredits?: number;
157
157
  };
158
158
  }>;
159
+ settlements(): Promise<{
160
+ ok: true;
161
+ settlementSummary: SupplierSettlementSummary & {
162
+ totalCustomerChargedCredits?: number;
163
+ };
164
+ summary?: SupplierSettlementSummary;
165
+ }>;
159
166
  getSettlements(): Promise<{
160
167
  ok: true;
161
168
  settlementSummary: SupplierSettlementSummary & {
package/dist/sdk.js CHANGED
@@ -201,6 +201,13 @@ export class MuxoClient {
201
201
  async getBillingStatus() {
202
202
  return this.getSettlements();
203
203
  }
204
+ async settlements() {
205
+ const res = await this.getSettlements();
206
+ return {
207
+ ...res,
208
+ summary: res.settlementSummary,
209
+ };
210
+ }
204
211
  async getSettlements() {
205
212
  const res = await this.request("/api/v1/billing/settlements");
206
213
  if (res.settlementSummary &&
package/dist/server.js CHANGED
@@ -1,9 +1,10 @@
1
+ import crypto from "node:crypto";
1
2
  import fs from "node:fs";
2
3
  import http from "node:http";
3
4
  import path from "node:path";
4
5
  import { getConfig, ROOT_DIR } from "./config.js";
5
6
  import { MuxoEngine } from "./engine.js";
6
- import { handleJsonRpcMcpRequest, MUXO_MCP_TOOLS } from "./mcp.js";
7
+ import { getMuxoMcpSkills, handleJsonRpcMcpRequest, MUXO_MCP_SERVER_INSTRUCTIONS, MUXO_MCP_TOOLS, } from "./mcp.js";
7
8
  import { MuxoStore } from "./store.js";
8
9
  import { renderConsoleHtml, renderLandingHtml } from "./ui/console-html.js";
9
10
  function renderSkillMarkdown(baseUrl) {
@@ -82,13 +83,15 @@ async function readBody(req) {
82
83
  }
83
84
  return Buffer.concat(chunks).toString("utf8");
84
85
  }
85
- function sendJson(res, status, payload) {
86
+ function sendJson(res, status, payload, extraHeaders) {
86
87
  const body = JSON.stringify(payload, null, 2);
87
88
  res.writeHead(status, {
88
89
  "Content-Type": "application/json; charset=utf-8",
89
90
  "Access-Control-Allow-Origin": "*",
90
- "Access-Control-Allow-Headers": "Content-Type, Authorization",
91
+ "Access-Control-Allow-Headers": "Content-Type, Authorization, Mcp-Session-Id",
92
+ "Access-Control-Expose-Headers": "Mcp-Session-Id, WWW-Authenticate",
91
93
  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
94
+ ...(extraHeaders || {}),
92
95
  });
93
96
  res.end(body);
94
97
  }
@@ -97,6 +100,23 @@ export function createMuxoServer(customConfig) {
97
100
  const store = new MuxoStore(config.dbPath, config.vaultMasterKey);
98
101
  const engine = new MuxoEngine(config, store);
99
102
  const bootstrap = store.ensureDefaultWorkspace();
103
+ // OAuth 2.1 DCR + PKCE Authorization Code store for OpenAI Plugin / MCP clients
104
+ const oauthClients = new Map();
105
+ oauthClients.set("muxo-openai-plugin", {
106
+ client_id: "muxo-openai-plugin",
107
+ client_name: "Muxo Official OpenAI Plugin",
108
+ redirect_uris: [
109
+ "https://chatgpt.com/connector_platform_oauth_redirect",
110
+ "https://platform.openai.com/apps-manage/oauth",
111
+ "http://127.0.0.1:3118/oauth/callback",
112
+ "http://localhost:3118/oauth/callback",
113
+ ],
114
+ grant_types: ["authorization_code", "refresh_token"],
115
+ response_types: ["code"],
116
+ token_endpoint_auth_method: "none",
117
+ client_id_issued_at: Math.floor(Date.now() / 1000),
118
+ });
119
+ const oauthCodes = new Map();
100
120
  const resolveContext = (req) => {
101
121
  const authHeader = String(req.headers.authorization || "").trim();
102
122
  if (authHeader.toLowerCase().startsWith("bearer ")) {
@@ -134,7 +154,7 @@ export function createMuxoServer(customConfig) {
134
154
  ok: true,
135
155
  status: "ready",
136
156
  service: "muxo-platform",
137
- version: "1.2.0",
157
+ version: "1.2.3",
138
158
  environment: "production",
139
159
  live_execution: true,
140
160
  customer_billing: true,
@@ -167,8 +187,9 @@ export function createMuxoServer(customConfig) {
167
187
  if ((pathname === "/.well-known/oauth-protected-resource" ||
168
188
  pathname === "/.well-known/oauth-protected-resource/mcp") &&
169
189
  req.method === "GET") {
190
+ const proto = String(req.headers["x-forwarded-proto"] || "http").split(",")[0].trim();
170
191
  const requestOrigin = req.headers.host
171
- ? `http://${req.headers.host}`
192
+ ? `${proto}://${req.headers.host}`
172
193
  : config.baseUrl;
173
194
  const resource = pathname === "/.well-known/oauth-protected-resource/mcp"
174
195
  ? `${requestOrigin}/mcp`
@@ -183,13 +204,229 @@ export function createMuxoServer(customConfig) {
183
204
  });
184
205
  return;
185
206
  }
207
+ if ((pathname === "/.well-known/oauth-authorization-server" ||
208
+ pathname === "/.well-known/openid-configuration" ||
209
+ pathname === "/.well-known/oauth-authorization-server/mcp") &&
210
+ req.method === "GET") {
211
+ const proto = String(req.headers["x-forwarded-proto"] || "http").split(",")[0].trim();
212
+ const requestOrigin = req.headers.host
213
+ ? `${proto}://${req.headers.host}`
214
+ : config.baseUrl;
215
+ sendJson(res, 200, {
216
+ issuer: requestOrigin,
217
+ authorization_endpoint: `${requestOrigin}/oauth/authorize`,
218
+ token_endpoint: `${requestOrigin}/oauth/token`,
219
+ registration_endpoint: `${requestOrigin}/oauth/register`,
220
+ userinfo_endpoint: `${requestOrigin}/oauth/userinfo`,
221
+ jwks_uri: `${requestOrigin}/.well-known/jwks.json`,
222
+ scopes_supported: [
223
+ "muxo:mcp",
224
+ "muxo:read",
225
+ "muxo:execute",
226
+ "muxo:provision",
227
+ "openid",
228
+ "profile",
229
+ "email",
230
+ ],
231
+ response_types_supported: ["code"],
232
+ grant_types_supported: [
233
+ "authorization_code",
234
+ "refresh_token",
235
+ "client_credentials",
236
+ ],
237
+ token_endpoint_auth_methods_supported: [
238
+ "none",
239
+ "client_secret_post",
240
+ "client_secret_basic",
241
+ ],
242
+ code_challenge_methods_supported: ["S256", "plain"],
243
+ client_id_metadata_document_supported: true,
244
+ service_documentation: `${config.docsUrl}/quickstart`,
245
+ });
246
+ return;
247
+ }
248
+ if (pathname === "/oauth/register" && req.method === "POST") {
249
+ const body = JSON.parse((await readBody(req)) || "{}");
250
+ const clientId = typeof body.client_id === "string" && body.client_id.trim()
251
+ ? body.client_id.trim()
252
+ : `muxo_client_${crypto.randomBytes(8).toString("hex")}`;
253
+ const clientRecord = {
254
+ client_id: clientId,
255
+ client_name: String(body.client_name || "OpenAI Plugin MCP Client"),
256
+ redirect_uris: Array.isArray(body.redirect_uris)
257
+ ? body.redirect_uris.map(String)
258
+ : [
259
+ "https://chatgpt.com/connector_platform_oauth_redirect",
260
+ "http://127.0.0.1:3118/oauth/callback",
261
+ ],
262
+ grant_types: Array.isArray(body.grant_types)
263
+ ? body.grant_types.map(String)
264
+ : ["authorization_code", "refresh_token"],
265
+ response_types: Array.isArray(body.response_types)
266
+ ? body.response_types.map(String)
267
+ : ["code"],
268
+ token_endpoint_auth_method: String(body.token_endpoint_auth_method || "none"),
269
+ client_id_issued_at: Math.floor(Date.now() / 1000),
270
+ };
271
+ oauthClients.set(clientId, clientRecord);
272
+ sendJson(res, 201, clientRecord);
273
+ return;
274
+ }
275
+ if (pathname === "/oauth/authorize" &&
276
+ (req.method === "GET" || req.method === "POST")) {
277
+ const bodyParams = req.method === "POST"
278
+ ? new URLSearchParams(await readBody(req))
279
+ : url.searchParams;
280
+ const clientId = bodyParams.get("client_id") ||
281
+ url.searchParams.get("client_id") ||
282
+ "muxo-openai-plugin";
283
+ const redirectUri = bodyParams.get("redirect_uri") ||
284
+ url.searchParams.get("redirect_uri") ||
285
+ "http://127.0.0.1:3118/oauth/callback";
286
+ const stateParam = bodyParams.get("state") || url.searchParams.get("state") || "";
287
+ const scope = bodyParams.get("scope") ||
288
+ url.searchParams.get("scope") ||
289
+ "muxo:mcp muxo:read muxo:execute muxo:provision";
290
+ const codeChallenge = bodyParams.get("code_challenge") ||
291
+ url.searchParams.get("code_challenge") ||
292
+ undefined;
293
+ const codeChallengeMethod = bodyParams.get("code_challenge_method") ||
294
+ url.searchParams.get("code_challenge_method") ||
295
+ "S256";
296
+ const code = `muxo_auth_code_${crypto.randomBytes(16).toString("hex")}`;
297
+ const issuedKey = bootstrap.defaultApiKey ||
298
+ store.createApiKey({
299
+ workspaceId: bootstrap.workspace.id,
300
+ name: `OAuth Client (${clientId})`,
301
+ environment: "live",
302
+ }).secretKey;
303
+ oauthCodes.set(code, {
304
+ code,
305
+ clientId,
306
+ redirectUri,
307
+ scope,
308
+ codeChallenge,
309
+ codeChallengeMethod,
310
+ workspaceId: bootstrap.workspace.id,
311
+ apiKey: issuedKey,
312
+ expiresAt: Date.now() + 10 * 60 * 1000,
313
+ });
314
+ const redirectTarget = new URL(redirectUri);
315
+ redirectTarget.searchParams.set("code", code);
316
+ if (stateParam)
317
+ redirectTarget.searchParams.set("state", stateParam);
318
+ if (url.searchParams.get("format") === "json" ||
319
+ String(req.headers.accept || "").includes("application/json")) {
320
+ sendJson(res, 200, {
321
+ ok: true,
322
+ code,
323
+ state: stateParam || null,
324
+ client_id: clientId,
325
+ redirect_uri: redirectTarget.toString(),
326
+ });
327
+ return;
328
+ }
329
+ res.writeHead(302, {
330
+ Location: redirectTarget.toString(),
331
+ "Access-Control-Allow-Origin": "*",
332
+ });
333
+ res.end();
334
+ return;
335
+ }
336
+ if (pathname === "/oauth/token" && req.method === "POST") {
337
+ const rawBody = await readBody(req);
338
+ const contentType = String(req.headers["content-type"] || "");
339
+ const params = {};
340
+ if (contentType.includes("application/json")) {
341
+ const parsed = JSON.parse(rawBody || "{}");
342
+ for (const [k, v] of Object.entries(parsed)) {
343
+ if (v !== undefined && v !== null)
344
+ params[k] = String(v);
345
+ }
346
+ }
347
+ else {
348
+ const sp = new URLSearchParams(rawBody);
349
+ for (const [k, v] of sp.entries()) {
350
+ params[k] = v;
351
+ }
352
+ }
353
+ const grantType = params.grant_type || "authorization_code";
354
+ const code = params.code || "";
355
+ const codeVerifier = params.code_verifier || "";
356
+ let accessToken = bootstrap.defaultApiKey || "";
357
+ let scope = params.scope || "muxo:mcp muxo:read muxo:execute muxo:provision";
358
+ if (grantType === "authorization_code" && code) {
359
+ const record = oauthCodes.get(code);
360
+ if (!record || record.expiresAt < Date.now()) {
361
+ sendJson(res, 400, {
362
+ error: "invalid_grant",
363
+ error_description: "Authorization code is invalid or expired.",
364
+ });
365
+ return;
366
+ }
367
+ if (record.codeChallenge) {
368
+ if (!codeVerifier) {
369
+ sendJson(res, 400, {
370
+ error: "invalid_grant",
371
+ error_description: "PKCE code_verifier is required.",
372
+ });
373
+ return;
374
+ }
375
+ const method = (record.codeChallengeMethod || "S256").toUpperCase();
376
+ const computed = method === "S256"
377
+ ? crypto
378
+ .createHash("sha256")
379
+ .update(codeVerifier)
380
+ .digest("base64url")
381
+ : codeVerifier;
382
+ if (computed !== record.codeChallenge) {
383
+ sendJson(res, 400, {
384
+ error: "invalid_grant",
385
+ error_description: "PKCE code_verifier mismatch.",
386
+ });
387
+ return;
388
+ }
389
+ }
390
+ accessToken = record.apiKey;
391
+ scope = record.scope;
392
+ oauthCodes.delete(code);
393
+ }
394
+ else if (!accessToken) {
395
+ accessToken = store.createApiKey({
396
+ workspaceId: bootstrap.workspace.id,
397
+ name: "OAuth Token Key",
398
+ environment: "live",
399
+ }).secretKey;
400
+ }
401
+ sendJson(res, 200, {
402
+ access_token: accessToken,
403
+ token_type: "Bearer",
404
+ expires_in: 3600,
405
+ refresh_token: `muxo_rt_${crypto.randomBytes(16).toString("hex")}`,
406
+ scope,
407
+ });
408
+ return;
409
+ }
410
+ if (pathname === "/oauth/userinfo" && req.method === "GET") {
411
+ const ctx = resolveContext(req);
412
+ sendJson(res, 200, {
413
+ sub: ctx.user.id,
414
+ id: ctx.user.id,
415
+ name: ctx.user.name,
416
+ email: ctx.user.email,
417
+ workspace_id: ctx.workspace.id,
418
+ workspace_name: ctx.workspace.name,
419
+ tier: ctx.workspace.tier,
420
+ });
421
+ return;
422
+ }
186
423
  if ((pathname === "/api/openapi.json" || pathname === "/openapi.json") &&
187
424
  req.method === "GET") {
188
425
  sendJson(res, 200, {
189
426
  openapi: "3.1.0",
190
427
  info: {
191
428
  title: "Muxo Unified Agent Execution, Infrastructure, Memory & Governance API",
192
- version: "1.2.0",
429
+ version: "1.2.3",
193
430
  description: "One governed boundary over Connected Apps (Composio SDK), Instant Tools (Composio Instant), Cloud Infrastructure (Stripe Projects), Supermemory v5 Brain, and Microsoft Agent Governance Toolkit.",
194
431
  },
195
432
  servers: [{ url: config.baseUrl }],
@@ -273,10 +510,12 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
273
510
  res.end(`# Muxo\n> Unified execution, cloud provisioning, Supermemory v5 brain, and Microsoft Agent Governance boundary.\n\n- Skill Document: ${config.baseUrl}/skill.md\n- Auth Guide: ${config.baseUrl}/auth.md\n- OpenAPI 3.1 Spec: ${config.baseUrl}/api/openapi.json\n- MCP Endpoint: ${config.baseUrl}/mcp\n- OAuth Callback Handoff: ${config.baseUrl}/oauth/callback\n- Plugin Marketplace (Codex/OpenAI): ${config.baseUrl}/.agents/plugins/marketplace.json\n- Plugin Marketplace (Claude/Droid): ${config.baseUrl}/.claude-plugin/marketplace.json\n- Console (app.muxo.ai): ${config.baseUrl}/\n- Landing & Provider Canvas (muxo.ai): ${config.baseUrl}/landing\n- Documentation (docs.muxo.ai): ${config.docsUrl}\n`);
274
511
  return;
275
512
  }
276
- // Serve Installable Muxo Plugin Manifests & Metadata
513
+ // Serve Installable Muxo Plugin Manifests & Metadata (Portable OpenAI Agent Plugins + Codex + Claude)
277
514
  const pluginJsonRoutes = {
278
515
  "/.agents/plugins/marketplace.json": path.join(ROOT_DIR, ".agents", "plugins", "marketplace.json"),
279
516
  "/.claude-plugin/marketplace.json": path.join(ROOT_DIR, ".claude-plugin", "marketplace.json"),
517
+ "/plugins/muxo/plugin.json": path.join(ROOT_DIR, "plugins", "muxo", "plugin.json"),
518
+ "/plugins/muxo/mcp.json": path.join(ROOT_DIR, "plugins", "muxo", "mcp.json"),
280
519
  "/plugins/muxo/.codex-plugin/plugin.json": path.join(ROOT_DIR, "plugins", "muxo", ".codex-plugin", "plugin.json"),
281
520
  "/plugins/muxo/.claude-plugin/plugin.json": path.join(ROOT_DIR, "plugins", "muxo", ".claude-plugin", "plugin.json"),
282
521
  "/plugins/muxo/.app.json": path.join(ROOT_DIR, "plugins", "muxo", ".app.json"),
@@ -289,15 +528,66 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
289
528
  return;
290
529
  }
291
530
  }
531
+ const pluginTextRoutes = {
532
+ "/plugins/muxo/skills/muxo/SKILL.md": {
533
+ file: path.join(ROOT_DIR, "plugins", "muxo", "skills", "muxo", "SKILL.md"),
534
+ contentType: "text/markdown; charset=utf-8",
535
+ },
536
+ "/plugins/muxo/skills/muxo/references/cli.md": {
537
+ file: path.join(ROOT_DIR, "plugins", "muxo", "skills", "muxo", "references", "cli.md"),
538
+ contentType: "text/markdown; charset=utf-8",
539
+ },
540
+ "/plugins/muxo/skills/muxo/references/mcp.md": {
541
+ file: path.join(ROOT_DIR, "plugins", "muxo", "skills", "muxo", "references", "mcp.md"),
542
+ contentType: "text/markdown; charset=utf-8",
543
+ },
544
+ "/plugins/muxo/skills/setup/SKILL.md": {
545
+ file: path.join(ROOT_DIR, "plugins", "muxo", "skills", "setup", "SKILL.md"),
546
+ contentType: "text/markdown; charset=utf-8",
547
+ },
548
+ "/.codex/config.toml": {
549
+ file: path.join(ROOT_DIR, ".codex", "config.toml"),
550
+ contentType: "text/plain; charset=utf-8",
551
+ },
552
+ };
553
+ if (pluginTextRoutes[pathname] && req.method === "GET") {
554
+ const entry = pluginTextRoutes[pathname];
555
+ if (fs.existsSync(entry.file)) {
556
+ res.writeHead(200, {
557
+ "Content-Type": entry.contentType,
558
+ "Access-Control-Allow-Origin": "*",
559
+ });
560
+ res.end(fs.readFileSync(entry.file, "utf8"));
561
+ return;
562
+ }
563
+ }
292
564
  if (pathname === "/api/v1/plugin" && req.method === "GET") {
565
+ const portableManifest = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, "plugins", "muxo", "plugin.json"), "utf8"));
566
+ const mcpConfig = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, "plugins", "muxo", "mcp.json"), "utf8"));
293
567
  const codexManifest = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, "plugins", "muxo", ".codex-plugin", "plugin.json"), "utf8"));
294
568
  sendJson(res, 200, {
295
569
  ok: true,
296
- plugin: codexManifest,
570
+ plugin: portableManifest,
571
+ codexPlugin: codexManifest,
572
+ mcp: mcpConfig,
573
+ skills: getMuxoMcpSkills().map((s) => ({
574
+ name: s.name,
575
+ description: s.description,
576
+ uri: s.uri,
577
+ version: s.version,
578
+ files: s.files.length,
579
+ })),
297
580
  marketplaces: {
298
581
  openaiCodex: `${config.baseUrl}/.agents/plugins/marketplace.json`,
299
582
  claudeDroid: `${config.baseUrl}/.claude-plugin/marketplace.json`,
300
583
  },
584
+ manifests: {
585
+ portablePluginJson: `${config.baseUrl}/plugins/muxo/plugin.json`,
586
+ portableMcpJson: `${config.baseUrl}/plugins/muxo/mcp.json`,
587
+ onboardingSkill: `${config.baseUrl}/plugins/muxo/skills/setup/SKILL.md`,
588
+ codexPluginJson: `${config.baseUrl}/plugins/muxo/.codex-plugin/plugin.json`,
589
+ codexConfigToml: `${config.baseUrl}/.codex/config.toml`,
590
+ },
301
591
  installCommands: {
302
592
  codex: "codex plugin add muxo@muxo",
303
593
  cliSignup: "muxo login --signup --name my-agent",
@@ -445,18 +735,66 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
445
735
  });
446
736
  return;
447
737
  }
448
- // Streamable HTTP MCP Endpoint (POST /mcp)
738
+ // Streamable HTTP MCP Endpoint (POST /mcp, GET /mcp, DELETE /mcp)
739
+ if (pathname === "/mcp" && req.method === "GET") {
740
+ const accept = String(req.headers.accept || "");
741
+ const sessionId = String(req.headers["mcp-session-id"] || "") ||
742
+ `mcp_sess_${crypto.randomBytes(8).toString("hex")}`;
743
+ if (accept.includes("text/event-stream")) {
744
+ res.writeHead(200, {
745
+ "Content-Type": "text/event-stream; charset=utf-8",
746
+ "Cache-Control": "no-cache",
747
+ Connection: "keep-alive",
748
+ "Mcp-Session-Id": sessionId,
749
+ "Access-Control-Allow-Origin": "*",
750
+ });
751
+ res.write(`event: endpoint\ndata: ${JSON.stringify({ uri: `${config.baseUrl}/mcp`, sessionId })}\n\n`);
752
+ res.end();
753
+ return;
754
+ }
755
+ sendJson(res, 200, {
756
+ ok: true,
757
+ transport: "streamable-http",
758
+ protocolVersion: "2025-06-18",
759
+ serverInfo: {
760
+ name: "muxo-mcp-server",
761
+ version: "1.2.3",
762
+ },
763
+ instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
764
+ toolsCount: MUXO_MCP_TOOLS.length,
765
+ skillsCount: getMuxoMcpSkills().length,
766
+ });
767
+ return;
768
+ }
769
+ if (pathname === "/mcp" && req.method === "DELETE") {
770
+ res.writeHead(204, {
771
+ "Access-Control-Allow-Origin": "*",
772
+ });
773
+ res.end();
774
+ return;
775
+ }
449
776
  if (pathname === "/mcp" && req.method === "POST") {
450
777
  const ctx = resolveContext(req);
778
+ const sessionId = String(req.headers["mcp-session-id"] || "") ||
779
+ `mcp_sess_${ctx.workspace.id}`;
451
780
  const raw = await readBody(req);
452
- const rpc = JSON.parse(raw || "{}");
781
+ const parsed = JSON.parse(raw || "{}");
782
+ if (Array.isArray(parsed)) {
783
+ const responses = (await Promise.all(parsed.map((item) => handleJsonRpcMcpRequest(engine, ctx, (item || {}))))).filter((r) => r !== null);
784
+ sendJson(res, 200, responses, { "Mcp-Session-Id": sessionId });
785
+ return;
786
+ }
787
+ const rpc = parsed;
453
788
  const response = await handleJsonRpcMcpRequest(engine, ctx, rpc);
454
789
  if (!response) {
455
- res.writeHead(202);
790
+ res.writeHead(202, {
791
+ "Access-Control-Allow-Origin": "*",
792
+ "Mcp-Session-Id": sessionId,
793
+ });
456
794
  res.end();
457
795
  return;
458
796
  }
459
- sendJson(res, 200, response);
797
+ sendJson(res, 200, response, { "Mcp-Session-Id": sessionId });
460
798
  return;
461
799
  }
462
800
  // Auth Endpoints
@@ -619,8 +957,16 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
619
957
  }
620
958
  if (pathname === "/api/v1/connections/wait" && req.method === "POST") {
621
959
  const body = JSON.parse((await readBody(req)) || "{}");
960
+ const provider = String(body.provider || "");
961
+ if (body.simulateCallback === true || body.simulate_callback === true) {
962
+ await engine.handleOAuthCallback({
963
+ workspaceId: ctx.workspace.id,
964
+ provider,
965
+ status: "success",
966
+ });
967
+ }
622
968
  const result = await engine.waitForConnection(ctx, {
623
- provider: String(body.provider || ""),
969
+ provider,
624
970
  timeoutSeconds: body.timeoutSeconds !== undefined
625
971
  ? Number(body.timeoutSeconds)
626
972
  : body.timeout_seconds !== undefined
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muxoai/platform",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "Muxo — Unified Execution, Provisioning & Governance Platform over Composio, Stripe Projects, Microsoft Agent Governance & Supermemory",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -45,6 +45,9 @@
45
45
  "vendor/microsoft-governance/package.json",
46
46
  "vendor/microsoft-governance/dist",
47
47
  "plugins",
48
+ ".agents",
49
+ ".claude-plugin",
50
+ ".codex",
48
51
  "README.md",
49
52
  "ARCHITECTURE.md"
50
53
  ],
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muxo",
3
- "version": "1.1.0",
4
- "description": "Governed agent execution across 1,000+ Connected Apps (managed OAuth handoff), Instant Tools, live Cloud Infrastructure provisioning, Supermemory v5 recall, and Microsoft Agent Governance Ed25519 receipts.",
3
+ "version": "1.2.3",
4
+ "description": "Governed agent execution across 1,000+ Connected Apps (managed OAuth handoff), Instant Tools (search, scrape, crawl, SEO audit), live Cloud Infrastructure provisioning, Supermemory v5 recall, and Microsoft Agent Governance Ed25519 receipts.",
5
5
  "author": {
6
6
  "name": "Muxo",
7
7
  "email": "founders@muxo.ai",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "muxo",
3
- "version": "1.1.0",
4
- "description": "Your agent decides what to do — Muxo governs, provisions, remembers, and executes it. Unified access to 1,000+ SaaS apps (managed OAuth handoff), Instant Tools, live Cloud Infrastructure provisioning (Postgres, Redis, SQLite, Storage), Supermemory v5 contextual recall, and Ed25519-signed Microsoft Agent Governance receipts through the hosted app or local CLI.",
3
+ "version": "1.2.3",
4
+ "description": "Your agent decides what to do — Muxo governs, provisions, remembers, and executes it. Unified access to 1,000+ SaaS apps (managed OAuth handoff), Instant Tools (search, scrape, crawl, SEO audit), live Cloud Infrastructure provisioning (Postgres, Redis, SQLite, Storage), Supermemory v5 contextual recall, and Ed25519-signed Microsoft Agent Governance receipts through the hosted app or local CLI.",
5
5
  "author": {
6
6
  "name": "Muxo",
7
7
  "email": "founders@muxo.ai",
@@ -12,10 +12,12 @@
12
12
  "license": "MIT",
13
13
  "keywords": [
14
14
  "muxo",
15
+ "openai",
16
+ "chatgpt",
17
+ "codex",
15
18
  "app",
16
19
  "mcp",
17
20
  "cli",
18
- "codex",
19
21
  "oauth",
20
22
  "infrastructure",
21
23
  "governance",
@@ -25,11 +27,13 @@
25
27
  "productivity"
26
28
  ],
27
29
  "skills": "./skills/",
30
+ "mcpServers": "./.mcp.json",
28
31
  "apps": "./.app.json",
32
+ "onboardingSkill": "./skills/setup/SKILL.md",
29
33
  "interface": {
30
34
  "displayName": "Muxo",
31
- "shortDescription": "Governed SaaS apps, cloud infra & memory",
32
- "longDescription": "Discover, plan, authorize via OAuth handoff, and execute governed actions across 1,000+ Connected Apps (GitHub, Gmail, Slack, Notion, Linear), Instant Tools, and live Cloud Infrastructure (Neon Postgres, Turso SQLite, Supabase, Cloudflare, Vercel) with Supermemory v5 workspace recall and Ed25519 cryptographic receipts.",
35
+ "shortDescription": "Governed SaaS apps, cloud infra, instant web/SEO tools & memory",
36
+ "longDescription": "Discover, plan, authorize via OAuth handoff, and execute governed actions across 1,000+ Connected Apps (GitHub, Gmail, Slack, Notion, Linear), Instant Tools (web search, scrape, multi-page crawl, technical SEO audit), and live Cloud Infrastructure (Neon Postgres, Turso SQLite, Supabase, Cloudflare, Vercel) with Supermemory v5 workspace recall and Ed25519 cryptographic receipts.",
33
37
  "developerName": "Muxo",
34
38
  "category": "Productivity",
35
39
  "capabilities": [
@@ -40,9 +44,9 @@
40
44
  "privacyPolicyURL": "https://muxo.ai/privacy",
41
45
  "termsOfServiceURL": "https://muxo.ai/terms",
42
46
  "defaultPrompt": [
43
- "Connect my GitHub account and open a tracking issue for our next release.",
44
- "Provision a free Turso SQLite database and pull the credentials into .env.muxo.",
45
- "Search recent AI infrastructure news and store a summary in workspace memory."
47
+ "Audit https://muxo.ai for technical SEO and crawl its top pages.",
48
+ "Connect my GitHub or Gmail account and open a tracking issue for our next release.",
49
+ "Provision a free Turso SQLite database and pull the credentials into .env.muxo."
46
50
  ],
47
51
  "composerIcon": "./assets/logo.png",
48
52
  "logo": "./assets/logo.png",
@@ -1,8 +1,40 @@
1
1
  {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
2
3
  "mcpServers": {
3
4
  "muxo": {
5
+ "type": "streamable-http",
6
+ "url": "https://api.muxo.ai/mcp",
4
7
  "command": "npx",
5
- "args": ["-y", "muxo-platform", "mcp"]
8
+ "args": ["-y", "@muxoai/platform@latest", "mcp"],
9
+ "oauth": {
10
+ "clientId": "muxo-openai-plugin",
11
+ "callbackPort": 3118,
12
+ "scopes": [
13
+ "muxo:mcp",
14
+ "muxo:read",
15
+ "muxo:execute",
16
+ "muxo:provision"
17
+ ]
18
+ },
19
+ "extensions": {
20
+ "com.openai": {
21
+ "auth": {
22
+ "type": "mixed",
23
+ "client": {
24
+ "mode": "dcr"
25
+ },
26
+ "authorizationUrl": "https://api.muxo.ai/oauth/authorize",
27
+ "tokenUrl": "https://api.muxo.ai/oauth/token",
28
+ "registrationUrl": "https://api.muxo.ai/oauth/register",
29
+ "baseScopes": [
30
+ "muxo:mcp",
31
+ "muxo:read",
32
+ "muxo:execute",
33
+ "muxo:provision"
34
+ ]
35
+ }
36
+ }
37
+ }
6
38
  }
7
39
  }
8
40
  }