Register once, meter calls, and let Bazaar proxy handle agent billing.
Estimated time: 5 minutes ~ Uses only the SDK and two HTTP endpoints
Install @forthebots/bazaar-sdk, then register with your server endpoint. The SDK's registerProvider helper sends POST /api/bazaar/register-provider.
npm install @forthebots/bazaar-sdk
import { registerProvider } from '@forthebots/bazaar-sdk';
const provider = await registerProvider({
name: 'Example MCP',
email: 'you@example.com',
endpoint_url: 'https://mcp.example.com',
});
// Response: { api_key: 'bz_provider_...', provider_id: '...' }
// Save once, then store the key in BAZAAR_API_KEY in your server environment.
console.log(provider.provider_id);The key is shown once. Put the returned value in your deployment's environment settings; never commit it.
Create a client with the provider key, then call tools.register. The route accepts categories weather, search, code, data, comms, finance, utility, and other.
import { Bazaar } from '@forthebots/bazaar-sdk';
const client = new Bazaar({ apiKey: 'bz_provider_...' });
await client.tools.register([{
tool_name: 'weather.current',
description: 'Get current weather for a city',
category: 'weather',
price_cents_override: 2,
}]); // POST /api/bazaar/toolsmeter.record posts to /api/v1/bazaar/meter. The route reads status, input_tokens, and output_tokens, but the current SDK MeterPayload still types older success and tokens_used fields. Cast this route-shaped payload until that type is corrected.
const meterPayload = {
tool_name: 'weather.current',
duration_ms: 120,
status: 'success',
input_tokens: 24,
output_tokens: 80,
};
const result = await client.meter.record(meterPayload as any) as any;
// HTTP 201 response shape:
// { metered: true, tool_id: '...', agent_id: '...', cost_microcents: 20000,
// cost_cents: 2, status: 'success', timestamp: '...',
// receipt: { receipt_id: 'rcpt_...', signature: '...', verify_url: 'https://noui.bot/api/v1/bazaar/receipts/<receipt_id>' } }
console.log(result.receipt.receipt_id, result.receipt.signature, result.receipt.verify_url);Use the SDK helper or send the README's proxy request directly. The consumer key belongs to the agent caller; the JSON-RPC envelope is what Bazaar forwards to your MCP endpoint.
const response = await client.tools.call('weather.current', { city: 'Oakland' });
console.log(response.meta.cost_cents);
curl -X POST https://noui.bot/api/bazaar/proxy -H "Authorization: Bearer bz_consumer_..." -H "Content-Type: application/json" -d '{"tool_name":"weather.current","input":{"city":"Oakland"}}'
# Forwarded to your MCP server per SPEC.md SS1:
# {"jsonrpc":"2.0","method":"tools/call","params":{"name":"weather.current","arguments":{"city":"Oakland"}},"id":"..."}Fetch the stored receipt by ID, or paste the signed JSON envelope into the public verifier. Check verification.valid is true.
curl https://noui.bot/api/v1/bazaar/receipts/<receipt_id>
# Or POST the complete signed receipt JSON to /api/v1/verify:
curl -X POST https://noui.bot/api/v1/verify -H "Content-Type: application/json" -d '{"receipt":{"receipt_id":"<receipt_id>","tool_id":"<tool_id>","agent_id":"<agent_id>","provider_id":"<provider_id>","timestamp":"<timestamp>","cost_microcents":20000,"status":"success","signature":"<signature>"}}'
# Confirm the response contains verification.valid: true.