-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcp-agent.js
More file actions
133 lines (116 loc) · 5.02 KB
/
Copy pathmcp-agent.js
File metadata and controls
133 lines (116 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env node
/**
* DOOH Agent Example — MCP Client
*
* Demonstrates the complete lifecycle of a DOOH advertising agent:
* 1. Discover pricing (no auth needed)
* 2. Register as an agent (no auth needed)
* 3. Discover available inventory
* 4. Check audience data for a screen
* 5. Get billing status
*
* Usage:
* node mcp-agent.js # Run with API key from .env
* node mcp-agent.js --demo # Run discovery steps only (no API key needed)
*/
const { Client } = require('@modelcontextprotocol/sdk/client/index.js');
const { StreamableHTTPClientTransport } = require('@modelcontextprotocol/sdk/client/streamableHttp.js');
const MCP_ENDPOINT = 'https://api.trillboards.com/mcp/';
async function main() {
const isDemo = process.argv.includes('--demo');
console.log('=== Trillboards DOOH Agent (MCP) ===\n');
// ── Step 1: Connect to MCP server ──
console.log('1. Connecting to MCP server...');
const transport = new StreamableHTTPClientTransport(new URL(MCP_ENDPOINT));
const client = new Client({ name: 'dooh-agent-example', version: '1.0.0' });
await client.connect(transport);
const { tools } = await client.listTools();
console.log(` Connected. ${tools.length} tools available.\n`);
// ── Step 2: Discover pricing (no auth required) ──
console.log('2. Discovering pricing...');
const pricingResult = await client.callTool({
name: 'get_pricing',
arguments: { product: 'data_api' }
});
const pricing = JSON.parse(pricingResult.content[0].text);
console.log(` Product: ${pricing.details.name}`);
console.log(` Free tier: ${JSON.stringify(pricing.free_tiers)}`);
console.log(` Tiers: ${pricing.details.tiers.map(t => `$${t.unit_price_usd}/call${t.up_to ? ` (up to ${t.up_to})` : ' (unlimited)'}`).join(', ')}\n`);
if (isDemo) {
console.log('Demo mode — skipping authenticated steps.');
console.log('Set TRILLBOARDS_API_KEY in .env and run without --demo for the full flow.\n');
await client.close();
return;
}
// ── Step 3: Use API key for authenticated calls ──
const apiKey = process.env.TRILLBOARDS_API_KEY;
if (!apiKey) {
console.log('No TRILLBOARDS_API_KEY set. Register first:');
console.log(' curl -X POST https://api.trillboards.com/v1/partner/agent/register \\');
console.log(' -H "Content-Type: application/json" \\');
console.log(' -d \'{"agent_type":"developer","name":"My Agent","email":"you@example.com"}\'');
await client.close();
return;
}
// Reconnect with auth header
await client.close();
const authTransport = new StreamableHTTPClientTransport(new URL(MCP_ENDPOINT), {
requestInit: {
headers: { 'Authorization': `Bearer ${apiKey}` }
}
});
const authClient = new Client({ name: 'dooh-agent-example', version: '1.0.0' });
await authClient.connect(authTransport);
// ── Step 4: Discover inventory ──
console.log('3. Discovering inventory...');
const inventoryResult = await authClient.callTool({
name: 'discover_inventory',
arguments: { limit: 5 }
});
const inventory = JSON.parse(inventoryResult.content[0].text);
console.log(` Found ${inventory.total || inventory.screens?.length || 0} screens\n`);
if (inventory.screens && inventory.screens.length > 0) {
const screen = inventory.screens[0];
console.log(` First screen: ${screen.name || screen.device_id} (${screen.venue_type || 'unknown'})`);
// ── Step 5: Get live audience for first screen ──
console.log('\n4. Checking live audience...');
try {
const audienceResult = await authClient.callTool({
name: 'get_live_audience',
arguments: { screen_id: screen.device_id || screen.screen_id }
});
const audience = JSON.parse(audienceResult.content[0].text);
console.log(` Status: ${audience.status}`);
if (audience.audience) {
console.log(` Face count: ${audience.audience.face_count}`);
console.log(` Attention: ${audience.audience.attention_score}`);
}
} catch (err) {
console.log(` Could not fetch audience: ${err.message}`);
}
}
// ── Step 6: Check billing status ──
console.log('\n5. Checking billing status...');
const billingResult = await authClient.callTool({
name: 'get_billing_status',
arguments: {}
});
const billing = JSON.parse(billingResult.content[0].text);
console.log(` Billing active: ${billing.billing_active}`);
console.log(` Credit balance: $${(billing.credit_balance_cents / 100).toFixed(2)}`);
// ── Step 7: Usage summary ──
console.log('\n6. Usage this period...');
const usageResult = await authClient.callTool({
name: 'get_usage_summary',
arguments: {}
});
const usage = JSON.parse(usageResult.content[0].text);
console.log(` Billing status: ${usage.billing_status}`);
console.log(` Total cost: $${((usage.total_cost_cents || 0) / 100).toFixed(2)}`);
console.log('\n=== Done ===');
await authClient.close();
}
main().catch(err => {
console.error('Error:', err.message);
process.exit(1);
});