@mixrpay/agent-sdk 0.8.8 → 0.8.9

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.cjs CHANGED
@@ -2723,6 +2723,248 @@ Timestamp: ${timestamp}`;
2723
2723
  return this.parseJitInstance(data.instance);
2724
2724
  }
2725
2725
  // ===========================================================================
2726
+ // Skills Methods
2727
+ // ===========================================================================
2728
+ /**
2729
+ * Use a configured skill by deploying a JIT MCP server with your saved API keys.
2730
+ *
2731
+ * Skills are configured on the MixrPay dashboard with your API keys stored securely.
2732
+ * When you call useSkill(), MixrPay deploys an ephemeral MCP server with your keys
2733
+ * injected server-side - your keys are never exposed to the agent.
2734
+ *
2735
+ * @param skillId - The skill ID (e.g., 'github', 'notion', 'spotify')
2736
+ * @param options - Optional configuration
2737
+ * @returns Skill endpoint and available tools
2738
+ *
2739
+ * @example
2740
+ * ```typescript
2741
+ * // Use the GitHub skill
2742
+ * const github = await wallet.useSkill('github');
2743
+ *
2744
+ * console.log('Endpoint:', github.endpoint);
2745
+ * console.log('Tools:', github.tools);
2746
+ * console.log('Expires:', github.expiresAt);
2747
+ *
2748
+ * // Connect to the MCP endpoint and call tools
2749
+ * // The exact method depends on your MCP client
2750
+ * ```
2751
+ *
2752
+ * @example
2753
+ * ```typescript
2754
+ * // Use Notion with custom TTL
2755
+ * const notion = await wallet.useSkill('notion', { ttlHours: 48 });
2756
+ * ```
2757
+ *
2758
+ * @throws {MixrPayError} If skill is not configured or deployment fails
2759
+ */
2760
+ async useSkill(skillId, options) {
2761
+ this.logger.debug("useSkill", { skillId, options });
2762
+ const authHeaders = await this.getSessionAuthHeaders();
2763
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/use`, {
2764
+ method: "POST",
2765
+ headers: {
2766
+ "Content-Type": "application/json",
2767
+ ...authHeaders
2768
+ },
2769
+ body: JSON.stringify({
2770
+ ttl_hours: options?.ttlHours || 24
2771
+ })
2772
+ });
2773
+ if (!response.ok) {
2774
+ const error = await response.json().catch(() => ({}));
2775
+ if (error.configure_url) {
2776
+ throw new MixrPayError(
2777
+ `${error.error || "Skill not configured"}. Configure at: ${this.baseUrl}${error.configure_url}`,
2778
+ "SKILL_NOT_CONFIGURED"
2779
+ );
2780
+ }
2781
+ throw new MixrPayError(error.error || `Failed to use skill: ${response.status}`);
2782
+ }
2783
+ const data = await response.json();
2784
+ return {
2785
+ skillId: data.skill_id,
2786
+ endpoint: data.endpoint,
2787
+ tools: data.tools || [],
2788
+ expiresAt: new Date(data.expires_at),
2789
+ instanceId: data.instance_id
2790
+ };
2791
+ }
2792
+ /**
2793
+ * List all available skills and their configuration status.
2794
+ *
2795
+ * @returns Array of skills with status
2796
+ *
2797
+ * @example
2798
+ * ```typescript
2799
+ * const skills = await wallet.listSkills();
2800
+ *
2801
+ * // Find configured skills
2802
+ * const configured = skills.filter(s => s.status === 'configured');
2803
+ * console.log(`${configured.length} skills ready to use`);
2804
+ *
2805
+ * // Find skills that need configuration
2806
+ * const needsConfig = skills.filter(s => s.status === 'not_configured' && s.envVars.length > 0);
2807
+ * for (const skill of needsConfig) {
2808
+ * console.log(`${skill.name} needs: ${skill.envVars.map(v => v.label).join(', ')}`);
2809
+ * }
2810
+ * ```
2811
+ */
2812
+ async listSkills() {
2813
+ this.logger.debug("listSkills");
2814
+ const authHeaders = await this.getSessionAuthHeaders();
2815
+ const response = await fetch(`${this.baseUrl}/api/v2/skills`, {
2816
+ headers: authHeaders
2817
+ });
2818
+ if (!response.ok) {
2819
+ const error = await response.json().catch(() => ({}));
2820
+ throw new MixrPayError(error.error || `Failed to list skills: ${response.status}`);
2821
+ }
2822
+ const data = await response.json();
2823
+ return data.skills || [];
2824
+ }
2825
+ /**
2826
+ * Get apps connected via Composio (Gmail, Slack, GitHub, etc.).
2827
+ *
2828
+ * Use this to discover which apps the owner has connected before
2829
+ * attempting to use them via `wallet.useSkill('composio')`.
2830
+ *
2831
+ * @returns Object with connected app names and connection details
2832
+ *
2833
+ * @example
2834
+ * ```typescript
2835
+ * const apps = await wallet.getConnectedApps();
2836
+ *
2837
+ * if (apps.connected.length === 0) {
2838
+ * console.log('No apps connected. Ask your owner to connect apps at the dashboard.');
2839
+ * } else {
2840
+ * console.log('Connected apps:', apps.connected.join(', '));
2841
+ *
2842
+ * if (apps.connected.includes('gmail')) {
2843
+ * // Safe to use Composio for Gmail
2844
+ * const { endpoint, tools } = await wallet.useSkill('composio');
2845
+ * // tools will include 'gmail_read_emails', 'gmail_send_email', etc.
2846
+ * }
2847
+ * }
2848
+ * ```
2849
+ */
2850
+ async getConnectedApps() {
2851
+ this.logger.debug("getConnectedApps");
2852
+ const authHeaders = await this.getSessionAuthHeaders();
2853
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/composio/connections`, {
2854
+ headers: authHeaders
2855
+ });
2856
+ if (!response.ok) {
2857
+ const error = await response.json().catch(() => ({}));
2858
+ throw new MixrPayError(
2859
+ error.error || `Failed to get connected apps: ${response.status}`,
2860
+ "CONNECTED_APPS_FAILED"
2861
+ );
2862
+ }
2863
+ const data = await response.json();
2864
+ const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
2865
+ return {
2866
+ connected: connectedAppNames,
2867
+ connections: data.connections || [],
2868
+ oauthConnections: data.oauth_connections || [],
2869
+ apiKeyConnections: data.api_key_connections || []
2870
+ };
2871
+ }
2872
+ /**
2873
+ * Get configuration status for a specific skill.
2874
+ *
2875
+ * @param skillId - The skill ID
2876
+ * @returns Skill configuration status
2877
+ *
2878
+ * @example
2879
+ * ```typescript
2880
+ * const status = await wallet.getSkillStatus('github');
2881
+ *
2882
+ * if (status.status === 'configured') {
2883
+ * console.log('GitHub is ready!');
2884
+ * console.log('Configured vars:', status.configuredVars);
2885
+ * } else {
2886
+ * console.log('Please configure GitHub at the MixrPay dashboard');
2887
+ * }
2888
+ * ```
2889
+ */
2890
+ async getSkillStatus(skillId) {
2891
+ this.logger.debug("getSkillStatus", { skillId });
2892
+ const authHeaders = await this.getSessionAuthHeaders();
2893
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/configure`, {
2894
+ headers: authHeaders
2895
+ });
2896
+ if (!response.ok) {
2897
+ const error = await response.json().catch(() => ({}));
2898
+ throw new MixrPayError(error.error || `Failed to get skill status: ${response.status}`);
2899
+ }
2900
+ const data = await response.json();
2901
+ return {
2902
+ skillId: data.skill_id,
2903
+ status: data.status,
2904
+ configuredVars: data.configured_vars || [],
2905
+ lastUsedAt: data.last_used_at ? new Date(data.last_used_at) : void 0,
2906
+ errorMessage: data.error_message
2907
+ };
2908
+ }
2909
+ /**
2910
+ * Configure a skill with API keys.
2911
+ *
2912
+ * This allows agents to save API keys received via chat to the MixrPay platform.
2913
+ * Keys are encrypted at rest and will be available for use on subsequent deploy/redeploy.
2914
+ *
2915
+ * @param skillId - The skill ID (e.g., 'web-search', 'github', 'notion') or custom skill with 'custom-' prefix
2916
+ * @param envVars - Environment variables with API keys (e.g., { BRAVE_API_KEY: 'xxx' })
2917
+ * @returns Configuration result with list of configured variables
2918
+ *
2919
+ * @example Predefined skill
2920
+ * ```typescript
2921
+ * // User provides API key in chat, agent saves it
2922
+ * const result = await wallet.configureSkill('web-search', {
2923
+ * BRAVE_API_KEY: 'BSA_abc123xyz',
2924
+ * });
2925
+ *
2926
+ * console.log('Configured:', result.configuredVars);
2927
+ * // After next redeploy, the skill will be enabled with this key
2928
+ * ```
2929
+ *
2930
+ * @example Custom API key
2931
+ * ```typescript
2932
+ * // For APIs not in predefined skills, use custom- prefix
2933
+ * // User: "Here's my Polymarket API key: pk_abc123"
2934
+ * const result = await wallet.configureSkill('custom-polymarket', {
2935
+ * POLYMARKET_API_KEY: 'pk_abc123',
2936
+ * });
2937
+ *
2938
+ * // The key is now available in the agent's environment
2939
+ * // Access via: process.env.POLYMARKET_API_KEY
2940
+ * ```
2941
+ */
2942
+ async configureSkill(skillId, envVars) {
2943
+ this.logger.debug("configureSkill", { skillId, varNames: Object.keys(envVars) });
2944
+ const authHeaders = await this.getSessionAuthHeaders();
2945
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/configure`, {
2946
+ method: "POST",
2947
+ headers: {
2948
+ "Content-Type": "application/json",
2949
+ ...authHeaders
2950
+ },
2951
+ body: JSON.stringify({ env_vars: envVars })
2952
+ });
2953
+ if (!response.ok) {
2954
+ const error = await response.json().catch(() => ({}));
2955
+ throw new MixrPayError(
2956
+ error.error || `Failed to configure skill: ${response.status}`,
2957
+ error.error_code
2958
+ );
2959
+ }
2960
+ const data = await response.json();
2961
+ return {
2962
+ success: true,
2963
+ skillId: data.skill_id,
2964
+ configuredVars: data.configured_vars || []
2965
+ };
2966
+ }
2967
+ // ===========================================================================
2726
2968
  // Glama MCP Directory Methods
2727
2969
  // ===========================================================================
2728
2970
  /**
package/dist/index.d.cts CHANGED
@@ -1459,6 +1459,143 @@ declare class AgentWallet {
1459
1459
  * ```
1460
1460
  */
1461
1461
  getJitInstance(instanceId: string): Promise<JitInstance>;
1462
+ /**
1463
+ * Use a configured skill by deploying a JIT MCP server with your saved API keys.
1464
+ *
1465
+ * Skills are configured on the MixrPay dashboard with your API keys stored securely.
1466
+ * When you call useSkill(), MixrPay deploys an ephemeral MCP server with your keys
1467
+ * injected server-side - your keys are never exposed to the agent.
1468
+ *
1469
+ * @param skillId - The skill ID (e.g., 'github', 'notion', 'spotify')
1470
+ * @param options - Optional configuration
1471
+ * @returns Skill endpoint and available tools
1472
+ *
1473
+ * @example
1474
+ * ```typescript
1475
+ * // Use the GitHub skill
1476
+ * const github = await wallet.useSkill('github');
1477
+ *
1478
+ * console.log('Endpoint:', github.endpoint);
1479
+ * console.log('Tools:', github.tools);
1480
+ * console.log('Expires:', github.expiresAt);
1481
+ *
1482
+ * // Connect to the MCP endpoint and call tools
1483
+ * // The exact method depends on your MCP client
1484
+ * ```
1485
+ *
1486
+ * @example
1487
+ * ```typescript
1488
+ * // Use Notion with custom TTL
1489
+ * const notion = await wallet.useSkill('notion', { ttlHours: 48 });
1490
+ * ```
1491
+ *
1492
+ * @throws {MixrPayError} If skill is not configured or deployment fails
1493
+ */
1494
+ useSkill(skillId: string, options?: UseSkillOptions): Promise<UseSkillResult>;
1495
+ /**
1496
+ * List all available skills and their configuration status.
1497
+ *
1498
+ * @returns Array of skills with status
1499
+ *
1500
+ * @example
1501
+ * ```typescript
1502
+ * const skills = await wallet.listSkills();
1503
+ *
1504
+ * // Find configured skills
1505
+ * const configured = skills.filter(s => s.status === 'configured');
1506
+ * console.log(`${configured.length} skills ready to use`);
1507
+ *
1508
+ * // Find skills that need configuration
1509
+ * const needsConfig = skills.filter(s => s.status === 'not_configured' && s.envVars.length > 0);
1510
+ * for (const skill of needsConfig) {
1511
+ * console.log(`${skill.name} needs: ${skill.envVars.map(v => v.label).join(', ')}`);
1512
+ * }
1513
+ * ```
1514
+ */
1515
+ listSkills(): Promise<SkillInfo[]>;
1516
+ /**
1517
+ * Get apps connected via Composio (Gmail, Slack, GitHub, etc.).
1518
+ *
1519
+ * Use this to discover which apps the owner has connected before
1520
+ * attempting to use them via `wallet.useSkill('composio')`.
1521
+ *
1522
+ * @returns Object with connected app names and connection details
1523
+ *
1524
+ * @example
1525
+ * ```typescript
1526
+ * const apps = await wallet.getConnectedApps();
1527
+ *
1528
+ * if (apps.connected.length === 0) {
1529
+ * console.log('No apps connected. Ask your owner to connect apps at the dashboard.');
1530
+ * } else {
1531
+ * console.log('Connected apps:', apps.connected.join(', '));
1532
+ *
1533
+ * if (apps.connected.includes('gmail')) {
1534
+ * // Safe to use Composio for Gmail
1535
+ * const { endpoint, tools } = await wallet.useSkill('composio');
1536
+ * // tools will include 'gmail_read_emails', 'gmail_send_email', etc.
1537
+ * }
1538
+ * }
1539
+ * ```
1540
+ */
1541
+ getConnectedApps(): Promise<ConnectedAppsResult>;
1542
+ /**
1543
+ * Get configuration status for a specific skill.
1544
+ *
1545
+ * @param skillId - The skill ID
1546
+ * @returns Skill configuration status
1547
+ *
1548
+ * @example
1549
+ * ```typescript
1550
+ * const status = await wallet.getSkillStatus('github');
1551
+ *
1552
+ * if (status.status === 'configured') {
1553
+ * console.log('GitHub is ready!');
1554
+ * console.log('Configured vars:', status.configuredVars);
1555
+ * } else {
1556
+ * console.log('Please configure GitHub at the MixrPay dashboard');
1557
+ * }
1558
+ * ```
1559
+ */
1560
+ getSkillStatus(skillId: string): Promise<SkillStatus>;
1561
+ /**
1562
+ * Configure a skill with API keys.
1563
+ *
1564
+ * This allows agents to save API keys received via chat to the MixrPay platform.
1565
+ * Keys are encrypted at rest and will be available for use on subsequent deploy/redeploy.
1566
+ *
1567
+ * @param skillId - The skill ID (e.g., 'web-search', 'github', 'notion') or custom skill with 'custom-' prefix
1568
+ * @param envVars - Environment variables with API keys (e.g., { BRAVE_API_KEY: 'xxx' })
1569
+ * @returns Configuration result with list of configured variables
1570
+ *
1571
+ * @example Predefined skill
1572
+ * ```typescript
1573
+ * // User provides API key in chat, agent saves it
1574
+ * const result = await wallet.configureSkill('web-search', {
1575
+ * BRAVE_API_KEY: 'BSA_abc123xyz',
1576
+ * });
1577
+ *
1578
+ * console.log('Configured:', result.configuredVars);
1579
+ * // After next redeploy, the skill will be enabled with this key
1580
+ * ```
1581
+ *
1582
+ * @example Custom API key
1583
+ * ```typescript
1584
+ * // For APIs not in predefined skills, use custom- prefix
1585
+ * // User: "Here's my Polymarket API key: pk_abc123"
1586
+ * const result = await wallet.configureSkill('custom-polymarket', {
1587
+ * POLYMARKET_API_KEY: 'pk_abc123',
1588
+ * });
1589
+ *
1590
+ * // The key is now available in the agent's environment
1591
+ * // Access via: process.env.POLYMARKET_API_KEY
1592
+ * ```
1593
+ */
1594
+ configureSkill(skillId: string, envVars: Record<string, string>): Promise<{
1595
+ success: boolean;
1596
+ skillId: string;
1597
+ configuredVars: string[];
1598
+ }>;
1462
1599
  /**
1463
1600
  * Search the Glama MCP server directory.
1464
1601
  *
@@ -2468,6 +2605,115 @@ interface JitInstance {
2468
2605
  /** Creation time */
2469
2606
  createdAt: Date;
2470
2607
  }
2608
+ /**
2609
+ * Options for using a skill
2610
+ */
2611
+ interface UseSkillOptions {
2612
+ /** Time-to-live in hours for the MCP server (default: 24, max: 48) */
2613
+ ttlHours?: number;
2614
+ }
2615
+ /**
2616
+ * Result from using a skill
2617
+ */
2618
+ interface UseSkillResult {
2619
+ /** Skill ID */
2620
+ skillId: string;
2621
+ /** MCP server endpoint URL */
2622
+ endpoint: string;
2623
+ /** Available tool names */
2624
+ tools: string[];
2625
+ /** When the MCP server expires */
2626
+ expiresAt: Date;
2627
+ /** JIT instance ID for reference */
2628
+ instanceId: string;
2629
+ }
2630
+ /**
2631
+ * Skill information from the skills list
2632
+ */
2633
+ interface SkillInfo {
2634
+ /** Skill ID */
2635
+ id: string;
2636
+ /** Display name */
2637
+ name: string;
2638
+ /** Short description */
2639
+ description: string;
2640
+ /** Category */
2641
+ category: string;
2642
+ /** Category display name */
2643
+ categoryName: string;
2644
+ /** Icon name */
2645
+ icon: string;
2646
+ /** Whether this is a built-in skill */
2647
+ builtIn: boolean;
2648
+ /** Whether this skill requires MCP deployment */
2649
+ requiresMcp: boolean;
2650
+ /** Whether this skill is available */
2651
+ available: boolean;
2652
+ /** Configuration status */
2653
+ status: 'not_configured' | 'configured' | 'error';
2654
+ /** Last used timestamp */
2655
+ lastUsedAt?: string;
2656
+ /** Error message if status is 'error' */
2657
+ errorMessage?: string;
2658
+ /** Environment variables required */
2659
+ envVars: Array<{
2660
+ name: string;
2661
+ label: string;
2662
+ description: string;
2663
+ required: boolean;
2664
+ isSecret: boolean;
2665
+ configured: boolean;
2666
+ }>;
2667
+ }
2668
+ /**
2669
+ * Skill configuration status
2670
+ */
2671
+ interface SkillStatus {
2672
+ /** Skill ID */
2673
+ skillId: string;
2674
+ /** Configuration status */
2675
+ status: 'not_configured' | 'configured' | 'error';
2676
+ /** Names of configured environment variables */
2677
+ configuredVars: string[];
2678
+ /** Last used timestamp */
2679
+ lastUsedAt?: Date;
2680
+ /** Error message if status is 'error' */
2681
+ errorMessage?: string;
2682
+ }
2683
+ /**
2684
+ * Connected apps information from Composio
2685
+ */
2686
+ interface ConnectedAppsResult {
2687
+ /** Array of connected app IDs (e.g., ['gmail', 'slack', 'github']) */
2688
+ connected: string[];
2689
+ /** Full connection details */
2690
+ connections: Array<{
2691
+ id: string;
2692
+ app: string;
2693
+ app_name: string;
2694
+ type: 'oauth' | 'api_key';
2695
+ status: string;
2696
+ account_name: string | null;
2697
+ connected_at: string;
2698
+ }>;
2699
+ /** OAuth connections only */
2700
+ oauthConnections: Array<{
2701
+ id: string;
2702
+ app: string;
2703
+ app_name: string;
2704
+ status: string;
2705
+ account_name: string | null;
2706
+ connected_at: string;
2707
+ }>;
2708
+ /** API key connections only */
2709
+ apiKeyConnections: Array<{
2710
+ id: string;
2711
+ app: string;
2712
+ app_name: string;
2713
+ status: string;
2714
+ connected_at: string;
2715
+ }>;
2716
+ }
2471
2717
  /**
2472
2718
  * MCP server from the Glama directory
2473
2719
  */
@@ -3403,4 +3649,4 @@ declare function isMixrPayError(error: unknown): error is MixrPayError;
3403
3649
  */
3404
3650
  declare function getErrorMessage(error: unknown): string;
3405
3651
 
3406
- export { type AgentClaimInviteOptions, type AgentClaimInviteResult, type AgentMessage, type AgentRunConfig, type AgentRunEvent, type AgentRunOptions, type AgentRunResult, type AgentRunStatusResult, AgentWallet, type AgentWalletConfig, type AvailableBudget, type CallMerchantApiOptions, type ChargeResult, type ChildSession, type CompleteOptions, type CompleteResult, type DeployJitMcpOptions, type DeployJitMcpResult, type DiagnosticsResult, type GlamaImportData, type GlamaSearchResult, type GlamaServer, InsufficientBalanceError, InvalidSessionKeyError, type JitInstance, MerchantNotAllowedError, MixrPayError, type PaymentEvent, PaymentFailedError, SDK_VERSION, type SessionAuthorization, SessionExpiredError, SessionKeyExpiredError, type SessionKeyInfo, SessionLimitExceededError, SessionNotFoundError, SessionRevokedError, type SessionStats, type SpawnChildOptions, type SpawnChildResult, SpendingLimitExceededError, type SpendingStats, X402ProtocolError, getErrorMessage, isMixrPayError };
3652
+ export { type AgentClaimInviteOptions, type AgentClaimInviteResult, type AgentMessage, type AgentRunConfig, type AgentRunEvent, type AgentRunOptions, type AgentRunResult, type AgentRunStatusResult, AgentWallet, type AgentWalletConfig, type AvailableBudget, type CallMerchantApiOptions, type ChargeResult, type ChildSession, type CompleteOptions, type CompleteResult, type DeployJitMcpOptions, type DeployJitMcpResult, type DiagnosticsResult, type GlamaImportData, type GlamaSearchResult, type GlamaServer, InsufficientBalanceError, InvalidSessionKeyError, type JitInstance, MerchantNotAllowedError, MixrPayError, type PaymentEvent, PaymentFailedError, SDK_VERSION, type SessionAuthorization, SessionExpiredError, SessionKeyExpiredError, type SessionKeyInfo, SessionLimitExceededError, SessionNotFoundError, SessionRevokedError, type SessionStats, type SkillInfo, type SkillStatus, type SpawnChildOptions, type SpawnChildResult, SpendingLimitExceededError, type SpendingStats, type UseSkillOptions, type UseSkillResult, X402ProtocolError, getErrorMessage, isMixrPayError };
package/dist/index.d.ts CHANGED
@@ -1459,6 +1459,143 @@ declare class AgentWallet {
1459
1459
  * ```
1460
1460
  */
1461
1461
  getJitInstance(instanceId: string): Promise<JitInstance>;
1462
+ /**
1463
+ * Use a configured skill by deploying a JIT MCP server with your saved API keys.
1464
+ *
1465
+ * Skills are configured on the MixrPay dashboard with your API keys stored securely.
1466
+ * When you call useSkill(), MixrPay deploys an ephemeral MCP server with your keys
1467
+ * injected server-side - your keys are never exposed to the agent.
1468
+ *
1469
+ * @param skillId - The skill ID (e.g., 'github', 'notion', 'spotify')
1470
+ * @param options - Optional configuration
1471
+ * @returns Skill endpoint and available tools
1472
+ *
1473
+ * @example
1474
+ * ```typescript
1475
+ * // Use the GitHub skill
1476
+ * const github = await wallet.useSkill('github');
1477
+ *
1478
+ * console.log('Endpoint:', github.endpoint);
1479
+ * console.log('Tools:', github.tools);
1480
+ * console.log('Expires:', github.expiresAt);
1481
+ *
1482
+ * // Connect to the MCP endpoint and call tools
1483
+ * // The exact method depends on your MCP client
1484
+ * ```
1485
+ *
1486
+ * @example
1487
+ * ```typescript
1488
+ * // Use Notion with custom TTL
1489
+ * const notion = await wallet.useSkill('notion', { ttlHours: 48 });
1490
+ * ```
1491
+ *
1492
+ * @throws {MixrPayError} If skill is not configured or deployment fails
1493
+ */
1494
+ useSkill(skillId: string, options?: UseSkillOptions): Promise<UseSkillResult>;
1495
+ /**
1496
+ * List all available skills and their configuration status.
1497
+ *
1498
+ * @returns Array of skills with status
1499
+ *
1500
+ * @example
1501
+ * ```typescript
1502
+ * const skills = await wallet.listSkills();
1503
+ *
1504
+ * // Find configured skills
1505
+ * const configured = skills.filter(s => s.status === 'configured');
1506
+ * console.log(`${configured.length} skills ready to use`);
1507
+ *
1508
+ * // Find skills that need configuration
1509
+ * const needsConfig = skills.filter(s => s.status === 'not_configured' && s.envVars.length > 0);
1510
+ * for (const skill of needsConfig) {
1511
+ * console.log(`${skill.name} needs: ${skill.envVars.map(v => v.label).join(', ')}`);
1512
+ * }
1513
+ * ```
1514
+ */
1515
+ listSkills(): Promise<SkillInfo[]>;
1516
+ /**
1517
+ * Get apps connected via Composio (Gmail, Slack, GitHub, etc.).
1518
+ *
1519
+ * Use this to discover which apps the owner has connected before
1520
+ * attempting to use them via `wallet.useSkill('composio')`.
1521
+ *
1522
+ * @returns Object with connected app names and connection details
1523
+ *
1524
+ * @example
1525
+ * ```typescript
1526
+ * const apps = await wallet.getConnectedApps();
1527
+ *
1528
+ * if (apps.connected.length === 0) {
1529
+ * console.log('No apps connected. Ask your owner to connect apps at the dashboard.');
1530
+ * } else {
1531
+ * console.log('Connected apps:', apps.connected.join(', '));
1532
+ *
1533
+ * if (apps.connected.includes('gmail')) {
1534
+ * // Safe to use Composio for Gmail
1535
+ * const { endpoint, tools } = await wallet.useSkill('composio');
1536
+ * // tools will include 'gmail_read_emails', 'gmail_send_email', etc.
1537
+ * }
1538
+ * }
1539
+ * ```
1540
+ */
1541
+ getConnectedApps(): Promise<ConnectedAppsResult>;
1542
+ /**
1543
+ * Get configuration status for a specific skill.
1544
+ *
1545
+ * @param skillId - The skill ID
1546
+ * @returns Skill configuration status
1547
+ *
1548
+ * @example
1549
+ * ```typescript
1550
+ * const status = await wallet.getSkillStatus('github');
1551
+ *
1552
+ * if (status.status === 'configured') {
1553
+ * console.log('GitHub is ready!');
1554
+ * console.log('Configured vars:', status.configuredVars);
1555
+ * } else {
1556
+ * console.log('Please configure GitHub at the MixrPay dashboard');
1557
+ * }
1558
+ * ```
1559
+ */
1560
+ getSkillStatus(skillId: string): Promise<SkillStatus>;
1561
+ /**
1562
+ * Configure a skill with API keys.
1563
+ *
1564
+ * This allows agents to save API keys received via chat to the MixrPay platform.
1565
+ * Keys are encrypted at rest and will be available for use on subsequent deploy/redeploy.
1566
+ *
1567
+ * @param skillId - The skill ID (e.g., 'web-search', 'github', 'notion') or custom skill with 'custom-' prefix
1568
+ * @param envVars - Environment variables with API keys (e.g., { BRAVE_API_KEY: 'xxx' })
1569
+ * @returns Configuration result with list of configured variables
1570
+ *
1571
+ * @example Predefined skill
1572
+ * ```typescript
1573
+ * // User provides API key in chat, agent saves it
1574
+ * const result = await wallet.configureSkill('web-search', {
1575
+ * BRAVE_API_KEY: 'BSA_abc123xyz',
1576
+ * });
1577
+ *
1578
+ * console.log('Configured:', result.configuredVars);
1579
+ * // After next redeploy, the skill will be enabled with this key
1580
+ * ```
1581
+ *
1582
+ * @example Custom API key
1583
+ * ```typescript
1584
+ * // For APIs not in predefined skills, use custom- prefix
1585
+ * // User: "Here's my Polymarket API key: pk_abc123"
1586
+ * const result = await wallet.configureSkill('custom-polymarket', {
1587
+ * POLYMARKET_API_KEY: 'pk_abc123',
1588
+ * });
1589
+ *
1590
+ * // The key is now available in the agent's environment
1591
+ * // Access via: process.env.POLYMARKET_API_KEY
1592
+ * ```
1593
+ */
1594
+ configureSkill(skillId: string, envVars: Record<string, string>): Promise<{
1595
+ success: boolean;
1596
+ skillId: string;
1597
+ configuredVars: string[];
1598
+ }>;
1462
1599
  /**
1463
1600
  * Search the Glama MCP server directory.
1464
1601
  *
@@ -2468,6 +2605,115 @@ interface JitInstance {
2468
2605
  /** Creation time */
2469
2606
  createdAt: Date;
2470
2607
  }
2608
+ /**
2609
+ * Options for using a skill
2610
+ */
2611
+ interface UseSkillOptions {
2612
+ /** Time-to-live in hours for the MCP server (default: 24, max: 48) */
2613
+ ttlHours?: number;
2614
+ }
2615
+ /**
2616
+ * Result from using a skill
2617
+ */
2618
+ interface UseSkillResult {
2619
+ /** Skill ID */
2620
+ skillId: string;
2621
+ /** MCP server endpoint URL */
2622
+ endpoint: string;
2623
+ /** Available tool names */
2624
+ tools: string[];
2625
+ /** When the MCP server expires */
2626
+ expiresAt: Date;
2627
+ /** JIT instance ID for reference */
2628
+ instanceId: string;
2629
+ }
2630
+ /**
2631
+ * Skill information from the skills list
2632
+ */
2633
+ interface SkillInfo {
2634
+ /** Skill ID */
2635
+ id: string;
2636
+ /** Display name */
2637
+ name: string;
2638
+ /** Short description */
2639
+ description: string;
2640
+ /** Category */
2641
+ category: string;
2642
+ /** Category display name */
2643
+ categoryName: string;
2644
+ /** Icon name */
2645
+ icon: string;
2646
+ /** Whether this is a built-in skill */
2647
+ builtIn: boolean;
2648
+ /** Whether this skill requires MCP deployment */
2649
+ requiresMcp: boolean;
2650
+ /** Whether this skill is available */
2651
+ available: boolean;
2652
+ /** Configuration status */
2653
+ status: 'not_configured' | 'configured' | 'error';
2654
+ /** Last used timestamp */
2655
+ lastUsedAt?: string;
2656
+ /** Error message if status is 'error' */
2657
+ errorMessage?: string;
2658
+ /** Environment variables required */
2659
+ envVars: Array<{
2660
+ name: string;
2661
+ label: string;
2662
+ description: string;
2663
+ required: boolean;
2664
+ isSecret: boolean;
2665
+ configured: boolean;
2666
+ }>;
2667
+ }
2668
+ /**
2669
+ * Skill configuration status
2670
+ */
2671
+ interface SkillStatus {
2672
+ /** Skill ID */
2673
+ skillId: string;
2674
+ /** Configuration status */
2675
+ status: 'not_configured' | 'configured' | 'error';
2676
+ /** Names of configured environment variables */
2677
+ configuredVars: string[];
2678
+ /** Last used timestamp */
2679
+ lastUsedAt?: Date;
2680
+ /** Error message if status is 'error' */
2681
+ errorMessage?: string;
2682
+ }
2683
+ /**
2684
+ * Connected apps information from Composio
2685
+ */
2686
+ interface ConnectedAppsResult {
2687
+ /** Array of connected app IDs (e.g., ['gmail', 'slack', 'github']) */
2688
+ connected: string[];
2689
+ /** Full connection details */
2690
+ connections: Array<{
2691
+ id: string;
2692
+ app: string;
2693
+ app_name: string;
2694
+ type: 'oauth' | 'api_key';
2695
+ status: string;
2696
+ account_name: string | null;
2697
+ connected_at: string;
2698
+ }>;
2699
+ /** OAuth connections only */
2700
+ oauthConnections: Array<{
2701
+ id: string;
2702
+ app: string;
2703
+ app_name: string;
2704
+ status: string;
2705
+ account_name: string | null;
2706
+ connected_at: string;
2707
+ }>;
2708
+ /** API key connections only */
2709
+ apiKeyConnections: Array<{
2710
+ id: string;
2711
+ app: string;
2712
+ app_name: string;
2713
+ status: string;
2714
+ connected_at: string;
2715
+ }>;
2716
+ }
2471
2717
  /**
2472
2718
  * MCP server from the Glama directory
2473
2719
  */
@@ -3403,4 +3649,4 @@ declare function isMixrPayError(error: unknown): error is MixrPayError;
3403
3649
  */
3404
3650
  declare function getErrorMessage(error: unknown): string;
3405
3651
 
3406
- export { type AgentClaimInviteOptions, type AgentClaimInviteResult, type AgentMessage, type AgentRunConfig, type AgentRunEvent, type AgentRunOptions, type AgentRunResult, type AgentRunStatusResult, AgentWallet, type AgentWalletConfig, type AvailableBudget, type CallMerchantApiOptions, type ChargeResult, type ChildSession, type CompleteOptions, type CompleteResult, type DeployJitMcpOptions, type DeployJitMcpResult, type DiagnosticsResult, type GlamaImportData, type GlamaSearchResult, type GlamaServer, InsufficientBalanceError, InvalidSessionKeyError, type JitInstance, MerchantNotAllowedError, MixrPayError, type PaymentEvent, PaymentFailedError, SDK_VERSION, type SessionAuthorization, SessionExpiredError, SessionKeyExpiredError, type SessionKeyInfo, SessionLimitExceededError, SessionNotFoundError, SessionRevokedError, type SessionStats, type SpawnChildOptions, type SpawnChildResult, SpendingLimitExceededError, type SpendingStats, X402ProtocolError, getErrorMessage, isMixrPayError };
3652
+ export { type AgentClaimInviteOptions, type AgentClaimInviteResult, type AgentMessage, type AgentRunConfig, type AgentRunEvent, type AgentRunOptions, type AgentRunResult, type AgentRunStatusResult, AgentWallet, type AgentWalletConfig, type AvailableBudget, type CallMerchantApiOptions, type ChargeResult, type ChildSession, type CompleteOptions, type CompleteResult, type DeployJitMcpOptions, type DeployJitMcpResult, type DiagnosticsResult, type GlamaImportData, type GlamaSearchResult, type GlamaServer, InsufficientBalanceError, InvalidSessionKeyError, type JitInstance, MerchantNotAllowedError, MixrPayError, type PaymentEvent, PaymentFailedError, SDK_VERSION, type SessionAuthorization, SessionExpiredError, SessionKeyExpiredError, type SessionKeyInfo, SessionLimitExceededError, SessionNotFoundError, SessionRevokedError, type SessionStats, type SkillInfo, type SkillStatus, type SpawnChildOptions, type SpawnChildResult, SpendingLimitExceededError, type SpendingStats, type UseSkillOptions, type UseSkillResult, X402ProtocolError, getErrorMessage, isMixrPayError };
package/dist/index.js CHANGED
@@ -2686,6 +2686,248 @@ Timestamp: ${timestamp}`;
2686
2686
  return this.parseJitInstance(data.instance);
2687
2687
  }
2688
2688
  // ===========================================================================
2689
+ // Skills Methods
2690
+ // ===========================================================================
2691
+ /**
2692
+ * Use a configured skill by deploying a JIT MCP server with your saved API keys.
2693
+ *
2694
+ * Skills are configured on the MixrPay dashboard with your API keys stored securely.
2695
+ * When you call useSkill(), MixrPay deploys an ephemeral MCP server with your keys
2696
+ * injected server-side - your keys are never exposed to the agent.
2697
+ *
2698
+ * @param skillId - The skill ID (e.g., 'github', 'notion', 'spotify')
2699
+ * @param options - Optional configuration
2700
+ * @returns Skill endpoint and available tools
2701
+ *
2702
+ * @example
2703
+ * ```typescript
2704
+ * // Use the GitHub skill
2705
+ * const github = await wallet.useSkill('github');
2706
+ *
2707
+ * console.log('Endpoint:', github.endpoint);
2708
+ * console.log('Tools:', github.tools);
2709
+ * console.log('Expires:', github.expiresAt);
2710
+ *
2711
+ * // Connect to the MCP endpoint and call tools
2712
+ * // The exact method depends on your MCP client
2713
+ * ```
2714
+ *
2715
+ * @example
2716
+ * ```typescript
2717
+ * // Use Notion with custom TTL
2718
+ * const notion = await wallet.useSkill('notion', { ttlHours: 48 });
2719
+ * ```
2720
+ *
2721
+ * @throws {MixrPayError} If skill is not configured or deployment fails
2722
+ */
2723
+ async useSkill(skillId, options) {
2724
+ this.logger.debug("useSkill", { skillId, options });
2725
+ const authHeaders = await this.getSessionAuthHeaders();
2726
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/use`, {
2727
+ method: "POST",
2728
+ headers: {
2729
+ "Content-Type": "application/json",
2730
+ ...authHeaders
2731
+ },
2732
+ body: JSON.stringify({
2733
+ ttl_hours: options?.ttlHours || 24
2734
+ })
2735
+ });
2736
+ if (!response.ok) {
2737
+ const error = await response.json().catch(() => ({}));
2738
+ if (error.configure_url) {
2739
+ throw new MixrPayError(
2740
+ `${error.error || "Skill not configured"}. Configure at: ${this.baseUrl}${error.configure_url}`,
2741
+ "SKILL_NOT_CONFIGURED"
2742
+ );
2743
+ }
2744
+ throw new MixrPayError(error.error || `Failed to use skill: ${response.status}`);
2745
+ }
2746
+ const data = await response.json();
2747
+ return {
2748
+ skillId: data.skill_id,
2749
+ endpoint: data.endpoint,
2750
+ tools: data.tools || [],
2751
+ expiresAt: new Date(data.expires_at),
2752
+ instanceId: data.instance_id
2753
+ };
2754
+ }
2755
+ /**
2756
+ * List all available skills and their configuration status.
2757
+ *
2758
+ * @returns Array of skills with status
2759
+ *
2760
+ * @example
2761
+ * ```typescript
2762
+ * const skills = await wallet.listSkills();
2763
+ *
2764
+ * // Find configured skills
2765
+ * const configured = skills.filter(s => s.status === 'configured');
2766
+ * console.log(`${configured.length} skills ready to use`);
2767
+ *
2768
+ * // Find skills that need configuration
2769
+ * const needsConfig = skills.filter(s => s.status === 'not_configured' && s.envVars.length > 0);
2770
+ * for (const skill of needsConfig) {
2771
+ * console.log(`${skill.name} needs: ${skill.envVars.map(v => v.label).join(', ')}`);
2772
+ * }
2773
+ * ```
2774
+ */
2775
+ async listSkills() {
2776
+ this.logger.debug("listSkills");
2777
+ const authHeaders = await this.getSessionAuthHeaders();
2778
+ const response = await fetch(`${this.baseUrl}/api/v2/skills`, {
2779
+ headers: authHeaders
2780
+ });
2781
+ if (!response.ok) {
2782
+ const error = await response.json().catch(() => ({}));
2783
+ throw new MixrPayError(error.error || `Failed to list skills: ${response.status}`);
2784
+ }
2785
+ const data = await response.json();
2786
+ return data.skills || [];
2787
+ }
2788
+ /**
2789
+ * Get apps connected via Composio (Gmail, Slack, GitHub, etc.).
2790
+ *
2791
+ * Use this to discover which apps the owner has connected before
2792
+ * attempting to use them via `wallet.useSkill('composio')`.
2793
+ *
2794
+ * @returns Object with connected app names and connection details
2795
+ *
2796
+ * @example
2797
+ * ```typescript
2798
+ * const apps = await wallet.getConnectedApps();
2799
+ *
2800
+ * if (apps.connected.length === 0) {
2801
+ * console.log('No apps connected. Ask your owner to connect apps at the dashboard.');
2802
+ * } else {
2803
+ * console.log('Connected apps:', apps.connected.join(', '));
2804
+ *
2805
+ * if (apps.connected.includes('gmail')) {
2806
+ * // Safe to use Composio for Gmail
2807
+ * const { endpoint, tools } = await wallet.useSkill('composio');
2808
+ * // tools will include 'gmail_read_emails', 'gmail_send_email', etc.
2809
+ * }
2810
+ * }
2811
+ * ```
2812
+ */
2813
+ async getConnectedApps() {
2814
+ this.logger.debug("getConnectedApps");
2815
+ const authHeaders = await this.getSessionAuthHeaders();
2816
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/composio/connections`, {
2817
+ headers: authHeaders
2818
+ });
2819
+ if (!response.ok) {
2820
+ const error = await response.json().catch(() => ({}));
2821
+ throw new MixrPayError(
2822
+ error.error || `Failed to get connected apps: ${response.status}`,
2823
+ "CONNECTED_APPS_FAILED"
2824
+ );
2825
+ }
2826
+ const data = await response.json();
2827
+ const connectedAppNames = (data.connections || []).filter((c) => c.status === "connected").map((c) => c.app);
2828
+ return {
2829
+ connected: connectedAppNames,
2830
+ connections: data.connections || [],
2831
+ oauthConnections: data.oauth_connections || [],
2832
+ apiKeyConnections: data.api_key_connections || []
2833
+ };
2834
+ }
2835
+ /**
2836
+ * Get configuration status for a specific skill.
2837
+ *
2838
+ * @param skillId - The skill ID
2839
+ * @returns Skill configuration status
2840
+ *
2841
+ * @example
2842
+ * ```typescript
2843
+ * const status = await wallet.getSkillStatus('github');
2844
+ *
2845
+ * if (status.status === 'configured') {
2846
+ * console.log('GitHub is ready!');
2847
+ * console.log('Configured vars:', status.configuredVars);
2848
+ * } else {
2849
+ * console.log('Please configure GitHub at the MixrPay dashboard');
2850
+ * }
2851
+ * ```
2852
+ */
2853
+ async getSkillStatus(skillId) {
2854
+ this.logger.debug("getSkillStatus", { skillId });
2855
+ const authHeaders = await this.getSessionAuthHeaders();
2856
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/configure`, {
2857
+ headers: authHeaders
2858
+ });
2859
+ if (!response.ok) {
2860
+ const error = await response.json().catch(() => ({}));
2861
+ throw new MixrPayError(error.error || `Failed to get skill status: ${response.status}`);
2862
+ }
2863
+ const data = await response.json();
2864
+ return {
2865
+ skillId: data.skill_id,
2866
+ status: data.status,
2867
+ configuredVars: data.configured_vars || [],
2868
+ lastUsedAt: data.last_used_at ? new Date(data.last_used_at) : void 0,
2869
+ errorMessage: data.error_message
2870
+ };
2871
+ }
2872
+ /**
2873
+ * Configure a skill with API keys.
2874
+ *
2875
+ * This allows agents to save API keys received via chat to the MixrPay platform.
2876
+ * Keys are encrypted at rest and will be available for use on subsequent deploy/redeploy.
2877
+ *
2878
+ * @param skillId - The skill ID (e.g., 'web-search', 'github', 'notion') or custom skill with 'custom-' prefix
2879
+ * @param envVars - Environment variables with API keys (e.g., { BRAVE_API_KEY: 'xxx' })
2880
+ * @returns Configuration result with list of configured variables
2881
+ *
2882
+ * @example Predefined skill
2883
+ * ```typescript
2884
+ * // User provides API key in chat, agent saves it
2885
+ * const result = await wallet.configureSkill('web-search', {
2886
+ * BRAVE_API_KEY: 'BSA_abc123xyz',
2887
+ * });
2888
+ *
2889
+ * console.log('Configured:', result.configuredVars);
2890
+ * // After next redeploy, the skill will be enabled with this key
2891
+ * ```
2892
+ *
2893
+ * @example Custom API key
2894
+ * ```typescript
2895
+ * // For APIs not in predefined skills, use custom- prefix
2896
+ * // User: "Here's my Polymarket API key: pk_abc123"
2897
+ * const result = await wallet.configureSkill('custom-polymarket', {
2898
+ * POLYMARKET_API_KEY: 'pk_abc123',
2899
+ * });
2900
+ *
2901
+ * // The key is now available in the agent's environment
2902
+ * // Access via: process.env.POLYMARKET_API_KEY
2903
+ * ```
2904
+ */
2905
+ async configureSkill(skillId, envVars) {
2906
+ this.logger.debug("configureSkill", { skillId, varNames: Object.keys(envVars) });
2907
+ const authHeaders = await this.getSessionAuthHeaders();
2908
+ const response = await fetch(`${this.baseUrl}/api/v2/skills/${skillId}/configure`, {
2909
+ method: "POST",
2910
+ headers: {
2911
+ "Content-Type": "application/json",
2912
+ ...authHeaders
2913
+ },
2914
+ body: JSON.stringify({ env_vars: envVars })
2915
+ });
2916
+ if (!response.ok) {
2917
+ const error = await response.json().catch(() => ({}));
2918
+ throw new MixrPayError(
2919
+ error.error || `Failed to configure skill: ${response.status}`,
2920
+ error.error_code
2921
+ );
2922
+ }
2923
+ const data = await response.json();
2924
+ return {
2925
+ success: true,
2926
+ skillId: data.skill_id,
2927
+ configuredVars: data.configured_vars || []
2928
+ };
2929
+ }
2930
+ // ===========================================================================
2689
2931
  // Glama MCP Directory Methods
2690
2932
  // ===========================================================================
2691
2933
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mixrpay/agent-sdk",
3
- "version": "0.8.8",
3
+ "version": "0.8.9",
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",