@mixrpay/agent-sdk 0.8.4 → 0.8.6

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/index.js CHANGED
@@ -63,7 +63,7 @@ var InsufficientBalanceError = class extends MixrPayError {
63
63
  this.name = "InsufficientBalanceError";
64
64
  this.required = required;
65
65
  this.available = available;
66
- this.topUpUrl = "/wallet";
66
+ this.topUpUrl = "https://mixrpay.com/manage/wallet";
67
67
  }
68
68
  };
69
69
  var SessionKeyExpiredError = class extends MixrPayError {
@@ -71,7 +71,7 @@ var SessionKeyExpiredError = class extends MixrPayError {
71
71
  expiredAt;
72
72
  constructor(expiredAt) {
73
73
  super(
74
- `Session key expired at ${expiredAt}. Request a new session key from the wallet owner or create one at your MixrPay server /wallet/sessions`,
74
+ `Session key expired at ${expiredAt}. Request a new session key from the wallet owner at https://mixrpay.com/manage/invites`,
75
75
  "SESSION_KEY_EXPIRED"
76
76
  );
77
77
  this.name = "SessionKeyExpiredError";
@@ -140,7 +140,7 @@ var InvalidSessionKeyError = class extends MixrPayError {
140
140
  reason;
141
141
  constructor(reason = "Invalid session key format") {
142
142
  super(
143
- `${reason}. Session keys should be in format: sk_live_<64 hex chars> or sk_test_<64 hex chars>. Get one from your MixrPay server /wallet/sessions`,
143
+ `${reason}. Session keys should be in format: sk_live_<64 hex chars> or sk_test_<64 hex chars>. Get one from https://mixrpay.com/manage/invites`,
144
144
  "INVALID_SESSION_KEY"
145
145
  );
146
146
  this.name = "InvalidSessionKeyError";
@@ -495,7 +495,7 @@ function getAmountUsd(requirements) {
495
495
  }
496
496
 
497
497
  // src/agent-wallet.ts
498
- var SDK_VERSION = "0.8.3";
498
+ var SDK_VERSION = "0.8.5";
499
499
  var DEFAULT_BASE_URL = process.env.MIXRPAY_BASE_URL || "https://www.mixrpay.com";
500
500
  var DEFAULT_TIMEOUT = 3e4;
501
501
  var NETWORKS = {
@@ -611,7 +611,7 @@ var AgentWallet = class {
611
611
  validateConfig(config) {
612
612
  if (!config.sessionKey) {
613
613
  throw new InvalidSessionKeyError(
614
- "Session key is required. Get one from the wallet owner or create one at your MixrPay server /wallet/sessions"
614
+ "Session key is required. Get one from the wallet owner at https://mixrpay.com/manage/invites"
615
615
  );
616
616
  }
617
617
  const key = config.sessionKey.trim();
@@ -1124,7 +1124,7 @@ var AgentWallet = class {
1124
1124
  *
1125
1125
  * @example
1126
1126
  * ```typescript
1127
- * // Human creates invite at their dashboard, shares code "mixr-abc123"
1127
+ * // Human creates invite at https://mixrpay.com/manage/invites, shares code "mixr-abc123"
1128
1128
  *
1129
1129
  * const result = await AgentWallet.claimInvite({
1130
1130
  * inviteCode: 'mixr-abc123',
@@ -1350,6 +1350,16 @@ var AgentWallet = class {
1350
1350
  const data = await response.json();
1351
1351
  return data.children || [];
1352
1352
  }
1353
+ /**
1354
+ * List child sessions spawned by this agent.
1355
+ *
1356
+ * Alias for `getChildSessions()` for naming consistency.
1357
+ *
1358
+ * @returns Array of child session info
1359
+ */
1360
+ async listChildSessions() {
1361
+ return this.getChildSessions();
1362
+ }
1353
1363
  // ===========================================================================
1354
1364
  // Core Methods
1355
1365
  // ===========================================================================
@@ -1803,7 +1813,7 @@ var AgentWallet = class {
1803
1813
  checks.sessionKeyValid = info.isValid;
1804
1814
  if (!info.isValid) {
1805
1815
  issues.push("Session key is invalid or has been revoked.");
1806
- recommendations.push("Request a new session key from the wallet owner or create one at /wallet/sessions.");
1816
+ recommendations.push("Request a new session key from the wallet owner at https://mixrpay.com/manage/invites");
1807
1817
  }
1808
1818
  const now = /* @__PURE__ */ new Date();
1809
1819
  let expiresInHours = null;
@@ -1843,7 +1853,7 @@ var AgentWallet = class {
1843
1853
  balance = await this.getBalance();
1844
1854
  checks.hasBalance = balance > 0;
1845
1855
  if (balance <= 0) {
1846
- issues.push("Wallet has no USDC balance. Top up at your MixrPay server /wallet");
1856
+ issues.push("Wallet has no USDC balance. Top up at https://mixrpay.com/manage/wallet");
1847
1857
  recommendations.push("Deposit USDC to your wallet address to enable payments.");
1848
1858
  } else if (balance < 1) {
1849
1859
  issues.push(`Low balance: $${balance.toFixed(2)}. Consider topping up.`);
@@ -2495,6 +2505,341 @@ Timestamp: ${timestamp}`;
2495
2505
  };
2496
2506
  }
2497
2507
  // ===========================================================================
2508
+ // JIT MCP Server Methods
2509
+ // ===========================================================================
2510
+ /**
2511
+ * Deploy a JIT MCP server from the Glama directory.
2512
+ *
2513
+ * Deploys any remote-capable MCP server to Cloudflare Workers.
2514
+ * Charges $1 from your session budget.
2515
+ *
2516
+ * @param options - Deployment options including Glama server details and env vars
2517
+ * @returns Deployed instance with private endpoint URL
2518
+ *
2519
+ * @example
2520
+ * ```typescript
2521
+ * const result = await wallet.deployJitMcp({
2522
+ * glamaId: 'notion-mcp',
2523
+ * glamaNamespace: 'notion',
2524
+ * glamaSlug: 'notion-mcp',
2525
+ * toolName: 'My Notion Server',
2526
+ * envVars: { NOTION_API_KEY: 'secret_...' },
2527
+ * ttlHours: 24,
2528
+ * });
2529
+ *
2530
+ * console.log('Endpoint:', result.instance.endpointUrl);
2531
+ * console.log('Expires:', result.instance.expiresAt);
2532
+ * ```
2533
+ */
2534
+ async deployJitMcp(options) {
2535
+ this.logger.debug("deployJitMcp", { glamaId: options.glamaId, toolName: options.toolName });
2536
+ const authHeaders = await this.getSessionAuthHeaders();
2537
+ const response = await fetch(`${this.baseUrl}/api/v2/jit/deploy`, {
2538
+ method: "POST",
2539
+ headers: {
2540
+ "Content-Type": "application/json",
2541
+ ...authHeaders
2542
+ },
2543
+ body: JSON.stringify({
2544
+ glama_id: options.glamaId,
2545
+ glama_namespace: options.glamaNamespace,
2546
+ glama_slug: options.glamaSlug,
2547
+ tool_name: options.toolName,
2548
+ tool_description: options.toolDescription,
2549
+ env_vars: options.envVars,
2550
+ ttl_hours: options.ttlHours || 24
2551
+ // session_id not needed - derived from X-Session-Auth
2552
+ })
2553
+ });
2554
+ if (!response.ok) {
2555
+ const error = await response.json().catch(() => ({}));
2556
+ throw new MixrPayError(error.error || `JIT deploy failed: ${response.status}`);
2557
+ }
2558
+ const data = await response.json();
2559
+ if (data.payment?.amount_usd > 0) {
2560
+ const payment = {
2561
+ amountUsd: data.payment.amount_usd,
2562
+ recipient: "mixrpay-jit-deploy",
2563
+ txHash: data.payment.tx_hash,
2564
+ timestamp: /* @__PURE__ */ new Date(),
2565
+ description: `JIT Deploy: ${options.toolName}`,
2566
+ url: `${this.baseUrl}/api/v2/jit/deploy`,
2567
+ requestId: data.request_id || crypto.randomUUID()
2568
+ };
2569
+ this.payments.push(payment);
2570
+ this.totalSpentUsd += data.payment.amount_usd;
2571
+ this.logger.payment(data.payment.amount_usd, "jit-deploy", options.toolName);
2572
+ if (this.onPayment) {
2573
+ this.onPayment(payment);
2574
+ }
2575
+ }
2576
+ return {
2577
+ instance: this.parseJitInstance(data.instance),
2578
+ payment: {
2579
+ method: data.payment.method,
2580
+ amountUsd: data.payment.amount_usd,
2581
+ txHash: data.payment.tx_hash
2582
+ }
2583
+ };
2584
+ }
2585
+ /**
2586
+ * List your deployed JIT MCP server instances.
2587
+ *
2588
+ * @param options - Optional filters
2589
+ * @returns Array of JIT instances
2590
+ *
2591
+ * @example
2592
+ * ```typescript
2593
+ * const instances = await wallet.listJitInstances({ status: 'active' });
2594
+ * for (const inst of instances) {
2595
+ * console.log(`${inst.toolName}: ${inst.endpointUrl}`);
2596
+ * }
2597
+ * ```
2598
+ */
2599
+ async listJitInstances(options) {
2600
+ this.logger.debug("listJitInstances", options);
2601
+ const authHeaders = await this.getSessionAuthHeaders();
2602
+ const params = new URLSearchParams();
2603
+ if (options?.status) params.set("status", options.status);
2604
+ const response = await fetch(
2605
+ `${this.baseUrl}/api/v2/jit/instances?${params}`,
2606
+ { headers: authHeaders }
2607
+ );
2608
+ if (!response.ok) {
2609
+ const error = await response.json().catch(() => ({}));
2610
+ throw new MixrPayError(error.error || `Failed to list JIT instances: ${response.status}`);
2611
+ }
2612
+ const data = await response.json();
2613
+ return (data.instances || []).map((i) => this.parseJitInstance(i));
2614
+ }
2615
+ /**
2616
+ * Stop a running JIT MCP server instance.
2617
+ *
2618
+ * Instance will be marked as stopped and Worker cleaned up.
2619
+ * No refund is given - instances are billed at deploy time.
2620
+ *
2621
+ * @param instanceId - The instance ID to stop
2622
+ *
2623
+ * @example
2624
+ * ```typescript
2625
+ * await wallet.stopJitInstance('inst_abc123');
2626
+ * console.log('Instance stopped');
2627
+ * ```
2628
+ */
2629
+ async stopJitInstance(instanceId) {
2630
+ this.logger.debug("stopJitInstance", { instanceId });
2631
+ const authHeaders = await this.getSessionAuthHeaders();
2632
+ const response = await fetch(
2633
+ `${this.baseUrl}/api/v2/jit/instances/${instanceId}`,
2634
+ { method: "DELETE", headers: authHeaders }
2635
+ );
2636
+ if (!response.ok) {
2637
+ const error = await response.json().catch(() => ({}));
2638
+ throw new MixrPayError(error.error || `Failed to stop JIT instance: ${response.status}`);
2639
+ }
2640
+ }
2641
+ /**
2642
+ * Parse JIT instance response data.
2643
+ */
2644
+ parseJitInstance(data) {
2645
+ return {
2646
+ id: data.id,
2647
+ endpointUrl: data.endpoint_url,
2648
+ toolName: data.tool_name,
2649
+ glamaId: data.glama_id,
2650
+ glamaNamespace: data.glama_namespace,
2651
+ glamaSlug: data.glama_slug,
2652
+ status: data.status,
2653
+ mode: data.mode,
2654
+ ttlHours: data.ttl_hours,
2655
+ expiresAt: new Date(data.expires_at),
2656
+ createdAt: new Date(data.created_at)
2657
+ };
2658
+ }
2659
+ /**
2660
+ * Get details of a specific JIT MCP server instance.
2661
+ *
2662
+ * @param instanceId - The instance ID to retrieve
2663
+ * @returns Full instance details including endpoint URL
2664
+ *
2665
+ * @example
2666
+ * ```typescript
2667
+ * const instance = await wallet.getJitInstance('inst_abc123');
2668
+ * console.log('Endpoint:', instance.endpointUrl);
2669
+ * console.log('Expires:', instance.expiresAt);
2670
+ * ```
2671
+ */
2672
+ async getJitInstance(instanceId) {
2673
+ this.logger.debug("getJitInstance", { instanceId });
2674
+ const authHeaders = await this.getSessionAuthHeaders();
2675
+ const response = await fetch(
2676
+ `${this.baseUrl}/api/v2/jit/instances/${instanceId}`,
2677
+ { headers: authHeaders }
2678
+ );
2679
+ if (!response.ok) {
2680
+ const error = await response.json().catch(() => ({}));
2681
+ throw new MixrPayError(error.error || `Failed to get JIT instance: ${response.status}`);
2682
+ }
2683
+ const data = await response.json();
2684
+ return this.parseJitInstance(data.instance);
2685
+ }
2686
+ // ===========================================================================
2687
+ // Glama MCP Directory Methods
2688
+ // ===========================================================================
2689
+ /**
2690
+ * Search the Glama MCP server directory.
2691
+ *
2692
+ * Glama indexes 15,000+ MCP servers. Use this to discover tools
2693
+ * that can be deployed as JIT servers.
2694
+ *
2695
+ * Note: This is a public API and does not require authentication.
2696
+ *
2697
+ * @param query - Search query (e.g., "notion", "github", "database")
2698
+ * @returns Array of matching servers with hosting info
2699
+ *
2700
+ * @example
2701
+ * ```typescript
2702
+ * const results = await wallet.searchGlamaDirectory('notion');
2703
+ *
2704
+ * // Filter to only hostable servers
2705
+ * const hostable = results.servers.filter(s => s.canHost);
2706
+ * console.log(`Found ${hostable.length} deployable servers`);
2707
+ *
2708
+ * // Deploy one
2709
+ * if (hostable.length > 0) {
2710
+ * const server = hostable[0];
2711
+ * await wallet.deployJitMcp({
2712
+ * glamaId: server.id,
2713
+ * glamaNamespace: server.namespace,
2714
+ * glamaSlug: server.slug,
2715
+ * toolName: server.name,
2716
+ * envVars: { API_KEY: '...' },
2717
+ * });
2718
+ * }
2719
+ * ```
2720
+ */
2721
+ async searchGlamaDirectory(query) {
2722
+ this.logger.debug("searchGlamaDirectory", { query });
2723
+ const params = new URLSearchParams({ q: query });
2724
+ const response = await fetch(`${this.baseUrl}/api/mcp/glama?${params}`);
2725
+ if (!response.ok) {
2726
+ const error = await response.json().catch(() => ({}));
2727
+ throw new MixrPayError(error.error || `Glama search failed: ${response.status}`);
2728
+ }
2729
+ const data = await response.json();
2730
+ return {
2731
+ servers: (data.servers || []).map((s) => this.parseGlamaServer(s)),
2732
+ pageInfo: data.pageInfo,
2733
+ query: data.query
2734
+ };
2735
+ }
2736
+ /**
2737
+ * Get featured/popular MCP servers from the Glama directory.
2738
+ *
2739
+ * Returns curated list of popular servers when you don't have
2740
+ * a specific search query.
2741
+ *
2742
+ * Note: This is a public API and does not require authentication.
2743
+ *
2744
+ * @returns Array of featured servers with hosting info
2745
+ *
2746
+ * @example
2747
+ * ```typescript
2748
+ * const { servers } = await wallet.getFeaturedGlamaServers();
2749
+ * console.log('Featured servers:', servers.map(s => s.name));
2750
+ * ```
2751
+ */
2752
+ async getFeaturedGlamaServers() {
2753
+ this.logger.debug("getFeaturedGlamaServers");
2754
+ const response = await fetch(`${this.baseUrl}/api/mcp/glama`);
2755
+ if (!response.ok) {
2756
+ const error = await response.json().catch(() => ({}));
2757
+ throw new MixrPayError(error.error || `Failed to get featured servers: ${response.status}`);
2758
+ }
2759
+ const data = await response.json();
2760
+ return {
2761
+ servers: (data.servers || []).map((s) => this.parseGlamaServer(s)),
2762
+ featured: data.featured
2763
+ };
2764
+ }
2765
+ /**
2766
+ * Parse Glama server response data.
2767
+ */
2768
+ parseGlamaServer(data) {
2769
+ const importData = data.importData;
2770
+ return {
2771
+ id: data.id,
2772
+ name: data.name,
2773
+ namespace: data.namespace,
2774
+ slug: data.slug,
2775
+ description: data.description,
2776
+ url: data.url,
2777
+ attributes: data.attributes,
2778
+ canHost: data.canHost,
2779
+ tools: data.tools || [],
2780
+ repository: data.repository,
2781
+ license: data.spdxLicense?.name,
2782
+ importData: importData ? {
2783
+ glamaId: importData.glamaId,
2784
+ glamaNamespace: importData.glamaNamespace,
2785
+ glamaSlug: importData.glamaSlug,
2786
+ suggestedName: importData.suggestedName,
2787
+ suggestedDescription: importData.suggestedDescription,
2788
+ hostingType: importData.hostingType,
2789
+ requiredEnvVars: importData.requiredEnvVars,
2790
+ optionalEnvVars: importData.optionalEnvVars
2791
+ } : void 0
2792
+ };
2793
+ }
2794
+ // ===========================================================================
2795
+ // LLM Completion Methods
2796
+ // ===========================================================================
2797
+ /**
2798
+ * Simple LLM completion - single-turn, no tools.
2799
+ *
2800
+ * This is a convenience method for agents that just need to call an LLM
2801
+ * without the full agentic loop. Useful when Clawdbot spawns agents
2802
+ * that need to make their own LLM calls through MixrPay.
2803
+ *
2804
+ * @param prompt - The user prompt to send
2805
+ * @param options - Optional configuration
2806
+ * @returns The LLM response text and cost
2807
+ *
2808
+ * @example Basic usage
2809
+ * ```typescript
2810
+ * const result = await wallet.complete('Summarize this text: ...');
2811
+ * console.log(result.text);
2812
+ * console.log(`Cost: $${result.costUsd.toFixed(4)}`);
2813
+ * ```
2814
+ *
2815
+ * @example With custom model
2816
+ * ```typescript
2817
+ * const result = await wallet.complete(
2818
+ * 'Write a haiku about coding',
2819
+ * { model: 'gpt-4o', systemPrompt: 'You are a poet.' }
2820
+ * );
2821
+ * ```
2822
+ */
2823
+ async complete(prompt, options) {
2824
+ this.logger.debug("complete", { promptLength: prompt.length, model: options?.model });
2825
+ const result = await this.runAgent({
2826
+ messages: [{ role: "user", content: prompt }],
2827
+ config: {
2828
+ model: options?.model || "gpt-4o-mini",
2829
+ maxIterations: 1,
2830
+ tools: [],
2831
+ // No tools - pure LLM completion
2832
+ systemPrompt: options?.systemPrompt
2833
+ }
2834
+ });
2835
+ return {
2836
+ text: result.response,
2837
+ costUsd: result.cost.totalUsd,
2838
+ tokens: result.tokens,
2839
+ model: options?.model || "gpt-4o-mini"
2840
+ };
2841
+ }
2842
+ // ===========================================================================
2498
2843
  // Agent Runtime API
2499
2844
  // ===========================================================================
2500
2845
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mixrpay/agent-sdk",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "description": "MixrPay Agent SDK - Enable AI agents to make x402 payments with session keys",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",