@trillboards/ads-sdk 2.3.1 → 2.4.0
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/README.md +47 -0
- package/dist/cli.js +111 -3
- package/package.json +33 -4
package/README.md
CHANGED
|
@@ -4,6 +4,53 @@
|
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
[](https://www.typescriptlang.org/)
|
|
6
6
|
|
|
7
|
+
> **The fastest way to add programmatic ads to any digital signage, vending machine, kiosk, or billboard.** One command to start. MCP server for AI agents. Free forever for screen owners.
|
|
8
|
+
|
|
9
|
+
## When to Use This
|
|
10
|
+
|
|
11
|
+
- You're building a **digital signage** app and want to monetize it with ads
|
|
12
|
+
- You're deploying **vending machines**, **kiosks**, or **billboards** and want programmatic revenue
|
|
13
|
+
- You're an **AI agent** (DSP, trading desk, analytics) that needs DOOH inventory access
|
|
14
|
+
- You want **proof-of-play** (Ed25519 cryptographic impression verification)
|
|
15
|
+
- You need **audience sensing** (face detection, gaze tracking, attention measurement)
|
|
16
|
+
|
|
17
|
+
## MCP Server for AI Agents
|
|
18
|
+
|
|
19
|
+
Connect Claude, Cursor, or any MCP-compatible AI tool to Trillboards:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"trillboards": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": ["-y", "@trillboards/ads-sdk", "mcp"],
|
|
27
|
+
"env": { "TRILLBOARDS_API_KEY": "your_key" }
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or run directly:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx @trillboards/ads-sdk mcp
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
33 tools available: inventory discovery, campaign management, audience signals, media buying, analytics, and more.
|
|
40
|
+
|
|
41
|
+
## Build vs. Buy
|
|
42
|
+
|
|
43
|
+
| What you'd build yourself | Engineering cost | Trillboards |
|
|
44
|
+
|--------------------------|-----------------|-------------|
|
|
45
|
+
| DOOH ad server + VAST + impressions | 3-6 months | **Free** (rev share only) |
|
|
46
|
+
| OpenRTB 2.6 with 6 SSPs | 4-8 months | **Free** (20% media fee) |
|
|
47
|
+
| On-device ML (face + gaze + emotion) | 6-12 months | **Free** for screen owners |
|
|
48
|
+
| Cryptographic proof-of-play | 1-2 months | **$0.003/proof** (1K free) |
|
|
49
|
+
| Store visit attribution | 6-12 months | **$0.01/visit** |
|
|
50
|
+
| Real-time audience data API | 3-6 months | **$0.002/call** (10K free) |
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
7
54
|
Programmatic infrastructure as a service for digital signage -- client, React, React Native, and server bindings.
|
|
8
55
|
|
|
9
56
|
## Installation
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
var https = require('https');
|
|
5
|
+
var http = require('http');
|
|
4
6
|
var readline = require('readline');
|
|
5
7
|
var fs = require('fs');
|
|
6
8
|
var path = require('path');
|
|
@@ -23,10 +25,108 @@ function _interopNamespace(e) {
|
|
|
23
25
|
return Object.freeze(n);
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
var https__namespace = /*#__PURE__*/_interopNamespace(https);
|
|
29
|
+
var http__namespace = /*#__PURE__*/_interopNamespace(http);
|
|
26
30
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
27
31
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
28
32
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
29
33
|
|
|
34
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
35
|
+
var __esm = (fn, res) => function __init() {
|
|
36
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/mcp-proxy.ts
|
|
40
|
+
var mcp_proxy_exports = {};
|
|
41
|
+
async function forwardToMcp(jsonRpcRequest) {
|
|
42
|
+
const body = JSON.stringify(jsonRpcRequest);
|
|
43
|
+
return new Promise((resolve2, reject) => {
|
|
44
|
+
const url = new URL(MCP_ENDPOINT);
|
|
45
|
+
const isHttps = url.protocol === "https:";
|
|
46
|
+
const transport = isHttps ? https__namespace : http__namespace;
|
|
47
|
+
const options = {
|
|
48
|
+
hostname: url.hostname,
|
|
49
|
+
port: url.port || (isHttps ? 443 : 80),
|
|
50
|
+
path: url.pathname,
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
"Content-Length": Buffer.byteLength(body),
|
|
55
|
+
...API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {},
|
|
56
|
+
"X-MCP-Client-Name": "trillboards-ads-sdk-proxy"
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const req = transport.request(options, (res) => {
|
|
60
|
+
let data = "";
|
|
61
|
+
res.on("data", (chunk) => {
|
|
62
|
+
data += chunk.toString();
|
|
63
|
+
});
|
|
64
|
+
res.on("end", () => {
|
|
65
|
+
try {
|
|
66
|
+
resolve2(JSON.parse(data));
|
|
67
|
+
} catch {
|
|
68
|
+
reject(new Error(`Invalid JSON response: ${data.slice(0, 200)}`));
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
req.on("error", reject);
|
|
73
|
+
req.write(body);
|
|
74
|
+
req.end();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async function main() {
|
|
78
|
+
process.stderr.write(`[trillboards-mcp] Connected to ${MCP_ENDPOINT}
|
|
79
|
+
`);
|
|
80
|
+
if (!API_KEY) {
|
|
81
|
+
process.stderr.write("[trillboards-mcp] Warning: TRILLBOARDS_API_KEY not set. Only unauthenticated tools will work.\n");
|
|
82
|
+
process.stderr.write("[trillboards-mcp] Set it via: export TRILLBOARDS_API_KEY=your_key\n");
|
|
83
|
+
}
|
|
84
|
+
const rl = readline__namespace.createInterface({ input: process.stdin, terminal: false });
|
|
85
|
+
let buffer = "";
|
|
86
|
+
const MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
87
|
+
rl.on("line", async (line) => {
|
|
88
|
+
buffer += line;
|
|
89
|
+
if (buffer.length > MAX_BUFFER_SIZE) {
|
|
90
|
+
process.stderr.write("[trillboards-mcp] Buffer exceeded 10 MB \u2014 resetting\n");
|
|
91
|
+
buffer = "";
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const request = JSON.parse(buffer);
|
|
96
|
+
buffer = "";
|
|
97
|
+
try {
|
|
98
|
+
const response = await forwardToMcp(request);
|
|
99
|
+
process.stdout.write(JSON.stringify(response) + "\n");
|
|
100
|
+
} catch (err) {
|
|
101
|
+
const errorMessage = err instanceof Error ? err.message : "Unknown error";
|
|
102
|
+
process.stdout.write(JSON.stringify({
|
|
103
|
+
jsonrpc: "2.0",
|
|
104
|
+
id: request.id || null,
|
|
105
|
+
error: { code: -32603, message: `MCP proxy error: ${errorMessage}` }
|
|
106
|
+
}) + "\n");
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
rl.on("close", () => {
|
|
112
|
+
process.stderr.write("[trillboards-mcp] Connection closed\n");
|
|
113
|
+
process.exit(0);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
var API_BASE, API_KEY, MCP_ENDPOINT;
|
|
117
|
+
var init_mcp_proxy = __esm({
|
|
118
|
+
"src/mcp-proxy.ts"() {
|
|
119
|
+
API_BASE = process.env.TRILLBOARDS_API_BASE || "https://api.trillboards.com";
|
|
120
|
+
API_KEY = process.env.TRILLBOARDS_API_KEY || "";
|
|
121
|
+
MCP_ENDPOINT = `${API_BASE}/mcp/`;
|
|
122
|
+
main().catch((err) => {
|
|
123
|
+
process.stderr.write(`[trillboards-mcp] Fatal error: ${err.message}
|
|
124
|
+
`);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
30
130
|
// src/core/config.ts
|
|
31
131
|
var SDK_VERSION = "2.2.0";
|
|
32
132
|
|
|
@@ -39,14 +139,14 @@ var BANNER = `
|
|
|
39
139
|
|
|
40
140
|
Turn any screen into ad revenue in 30 seconds
|
|
41
141
|
`;
|
|
42
|
-
var
|
|
142
|
+
var API_BASE2 = "https://api.trillboards.com/v1";
|
|
43
143
|
function prompt(rl, question) {
|
|
44
144
|
return new Promise((resolve2) => {
|
|
45
145
|
rl.question(question, (answer) => resolve2(answer.trim()));
|
|
46
146
|
});
|
|
47
147
|
}
|
|
48
148
|
async function callQuickStart(companyName, email) {
|
|
49
|
-
const response = await fetch(`${
|
|
149
|
+
const response = await fetch(`${API_BASE2}/partner/quick-start`, {
|
|
50
150
|
method: "POST",
|
|
51
151
|
headers: { "Content-Type": "application/json" },
|
|
52
152
|
body: JSON.stringify({
|
|
@@ -150,9 +250,17 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
150
250
|
|
|
151
251
|
Usage:
|
|
152
252
|
npx @trillboards/ads-sdk init Register and set up your first device
|
|
253
|
+
npx @trillboards/ads-sdk mcp Start MCP proxy for AI agents
|
|
153
254
|
npx @trillboards/ads-sdk --version
|
|
154
255
|
npx @trillboards/ads-sdk --help
|
|
155
256
|
`);
|
|
156
257
|
process.exit(0);
|
|
157
258
|
}
|
|
158
|
-
|
|
259
|
+
if (args[0] === "mcp") {
|
|
260
|
+
Promise.resolve().then(() => (init_mcp_proxy(), mcp_proxy_exports)).catch((err) => {
|
|
261
|
+
console.error(`Failed to start MCP proxy: ${err.message}`);
|
|
262
|
+
process.exit(1);
|
|
263
|
+
});
|
|
264
|
+
} else {
|
|
265
|
+
runInit();
|
|
266
|
+
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trillboards/ads-sdk",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "DOOH advertising SDK — add ads to vending machines, kiosks, billboards, and digital signage in one command. MCP server for AI agents. OpenRTB 2.6, VAST, proof-of-play, audience sensing.",
|
|
5
5
|
"bin": {
|
|
6
|
-
"trillboards": "./dist/cli.js"
|
|
6
|
+
"trillboards": "./dist/cli.js",
|
|
7
|
+
"trillboards-mcp": "./dist/mcp-proxy.js"
|
|
7
8
|
},
|
|
8
9
|
"main": "./dist/index.js",
|
|
9
10
|
"module": "./dist/index.mjs",
|
|
@@ -101,7 +102,35 @@
|
|
|
101
102
|
"ctv",
|
|
102
103
|
"programmatic",
|
|
103
104
|
"vast",
|
|
104
|
-
"openrtb"
|
|
105
|
+
"openrtb",
|
|
106
|
+
"digital-out-of-home",
|
|
107
|
+
"advertising-sdk",
|
|
108
|
+
"ad-tech",
|
|
109
|
+
"dooh-sdk",
|
|
110
|
+
"programmatic-dooh",
|
|
111
|
+
"mcp",
|
|
112
|
+
"model-context-protocol",
|
|
113
|
+
"ai-agent",
|
|
114
|
+
"agent-commerce",
|
|
115
|
+
"screen-monetization",
|
|
116
|
+
"vending-machine-ads",
|
|
117
|
+
"kiosk-ads",
|
|
118
|
+
"billboard-ads",
|
|
119
|
+
"edge-ai",
|
|
120
|
+
"computer-vision",
|
|
121
|
+
"openrtb-2.6",
|
|
122
|
+
"ad-monetization",
|
|
123
|
+
"impression-tracking",
|
|
124
|
+
"proof-of-play",
|
|
125
|
+
"audience-sensing",
|
|
126
|
+
"digital-billboard",
|
|
127
|
+
"smart-display",
|
|
128
|
+
"signage-monetization",
|
|
129
|
+
"vast-sdk",
|
|
130
|
+
"omsdk",
|
|
131
|
+
"face-detection",
|
|
132
|
+
"attention-measurement",
|
|
133
|
+
"dooh-attribution"
|
|
105
134
|
],
|
|
106
135
|
"license": "MIT",
|
|
107
136
|
"repository": {
|