Skip to main content

Examples

Practical examples for common use cases using fetch().
These examples use the JSON-RPC endpoint (/mcp). For the simpler REST endpoint (/v1/mcp/tools/call), see the Python SDK.

Basic Inference

const ASG = 'https://agent.asgcompute.com/mcp';
const API_KEY = process.env.ASG_API_KEY!;

// Simple completion (returns 402 with quote first)
const response = await fetch(ASG, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${API_KEY}`
  },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'tools/call',
    params: {
      name: 'inference_chat',
      arguments: {
        model: 'openai/gpt-4o-mini',
        messages: [
          { role: 'system', content: 'You are a helpful assistant.' },
          { role: 'user', content: 'What is the capital of France?' }
        ]
      }
    }
  })
});

const data = await response.json();
// If 402: data.payment_instructions has { pay_to, usdc_mint, network }
// If 200: data.result.content = "The capital of France is Paris."

Multi-turn Conversation

const messages: Array<{ role: string; content: string }> = [];

async function chat(userMessage: string, paymentProof?: string) {
  messages.push({ role: 'user', content: userMessage });

  const headers: Record<string, string> = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${API_KEY}`
  };
  if (paymentProof) {
    headers['X-Payment'] = paymentProof;
  }

  const response = await fetch(ASG, {
    method: 'POST',
    headers,
    body: JSON.stringify({
      jsonrpc: '2.0', id: 1,
      method: 'tools/call',
      params: {
        name: 'inference_chat',
        arguments: {
          model: 'anthropic/claude-sonnet-4',
          messages
        }
      }
    })
  });

  const data = await response.json();
  if (response.status === 200) {
    messages.push({ role: 'assistant', content: data.result.content });
    return data.result.content;
  }
  return data; // 402 quote
}

Code Execution (Sandbox)

const response = await fetch(ASG, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${API_KEY}`,
    'X-Payment': paymentProof
  },
  body: JSON.stringify({
    jsonrpc: '2.0', id: 1,
    method: 'tools/call',
    params: {
      name: 'sandbox_execute',
      arguments: {
        language: 'python',
        code: `
import json
data = {"users": 100, "active": 85}
print(json.dumps(data, indent=2))
        `
      }
    }
  })
});

const result = await response.json();
console.log(result.result.stdout);

Batch Processing

// Process items with concurrency control
async function processBatch(items: string[], paymentProofs: string[]) {
  const results = [];
  const concurrency = 3;

  for (let i = 0; i < items.length; i += concurrency) {
    const batch = items.slice(i, i + concurrency);
    const proofs = paymentProofs.slice(i, i + concurrency);

    const promises = batch.map((item, j) =>
      fetch(ASG, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${API_KEY}`,
          'X-Payment': proofs[j]
        },
        body: JSON.stringify({
          jsonrpc: '2.0', id: i + j + 1,
          method: 'tools/call',
          params: {
            name: 'inference_chat',
            arguments: {
              model: 'openai/gpt-4o-mini',
              messages: [{ role: 'user', content: `Summarize: ${item}` }]
            }
          }
        })
      }).then(r => r.json())
    );
    results.push(...await Promise.all(promises));
  }

  return results;
}

Budget Protection

// Track spending within a budget
let totalSpent = 0;
const budget = 5_000_000; // $5 in microusd

async function safeCall(name: string, args: Record<string, unknown>) {
  // Step 1: Get quote (402 response)
  const quoteRes = await fetch(ASG, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${API_KEY}`
    },
    body: JSON.stringify({
      jsonrpc: '2.0', id: 1,
      method: 'tools/call',
      params: { name, arguments: args }
    })
  });

  const quote = await quoteRes.json();
  const price = quote.quote.price_usdc_microusd;

  if (totalSpent + price > budget) {
    throw new Error(`Budget exceeded: spent ${totalSpent}, quote ${price}, limit ${budget}`);
  }

  // Step 2: Pay on Solana, then retry with proof
  // ... build and submit payment ...

  // Step 3: Track spending from receipt
  totalSpent += price;
  return quote;
}

Error Recovery

async function reliableCall(name: string, args: Record<string, unknown>, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      const response = await fetch(ASG, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${API_KEY}`
        },
        body: JSON.stringify({
          jsonrpc: '2.0', id: 1,
          method: 'tools/call',
          params: { name, arguments: args }
        })
      });

      const data = await response.json();

      if (data.error?.code === 'QUOTE_EXPIRED') {
        continue; // Retry to get fresh quote
      }
      if (data.error?.code === 'RATE_LIMITED') {
        await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
        continue;
      }

      return data;
    } catch (err) {
      if (attempt === maxRetries - 1) throw err;
    }
  }
  throw new Error('Max retries exceeded');
}