@voxburst/mcp-server 0.2.3 → 0.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 +87 -26
- package/dist/__tests__/tools.test.js +13 -6
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/client.d.ts +91 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +30 -3
- package/dist/client.js.map +1 -1
- package/dist/index.js +33 -5
- package/dist/index.js.map +1 -1
- package/dist/middleware/auth.d.ts +2 -6
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +4 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/resources/accounts.d.ts.map +1 -1
- package/dist/resources/accounts.js +7 -2
- package/dist/resources/accounts.js.map +1 -1
- package/dist/tools/accounts.js +2 -2
- package/dist/tools/accounts.js.map +1 -1
- package/dist/tools/index.d.ts +59 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/posts.d.ts +105 -3
- package/dist/tools/posts.d.ts.map +1 -1
- package/dist/tools/posts.js +70 -6
- package/dist/tools/posts.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ Model Context Protocol (MCP) server for VoxBurst — enables AI agents to manage
|
|
|
8
8
|
- 👥 **Account Access** — List and inspect connected social media accounts
|
|
9
9
|
- 📊 **Analytics** — Retrieve engagement metrics for posts and accounts
|
|
10
10
|
- 🔍 **Content Validation** — Validate content against platform-specific rules before posting
|
|
11
|
-
- 🤖 **AI-Native** — Designed for Claude,
|
|
11
|
+
- 🤖 **AI-Native** — Designed for Claude, Cursor, Windsurf, and other MCP-compatible clients that support stdio transport (ChatGPT is not currently supported — see [Compatibility](#compatibility))
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
@@ -19,17 +19,26 @@ npm install @voxburst/mcp-server
|
|
|
19
19
|
Or run directly with npx:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npx @voxburst/mcp-server
|
|
22
|
+
npx -y @voxburst/mcp-server
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
Installing globally also exposes a `voxburst-mcp` binary on your `PATH`, which you can reference directly in a client config instead of `npx`.
|
|
26
|
+
|
|
27
|
+
## Compatibility
|
|
28
|
+
|
|
29
|
+
This server runs in **stdio mode only** — there is no HTTP/SSE transport. It works with any MCP client that can launch a local stdio server, including Claude Desktop, Claude Code, Cursor, Windsurf, VS Code (with an MCP-compatible extension), and Codex CLI. ChatGPT (web and desktop) does not support local stdio MCP servers and cannot connect to this server today.
|
|
30
|
+
|
|
25
31
|
## Configuration
|
|
26
32
|
|
|
27
33
|
### Environment Variables
|
|
28
34
|
|
|
29
35
|
| Variable | Required | Default | Description |
|
|
30
36
|
|----------|----------|---------|-------------|
|
|
31
|
-
| `VOXBURST_API_KEY` | Yes | — | Your VoxBurst API key |
|
|
37
|
+
| `VOXBURST_API_KEY` | Yes | — | Your VoxBurst API key (`vb_live_…`) |
|
|
32
38
|
| `VOXBURST_API_URL` | No | `https://api.voxburst.io` | API base URL |
|
|
39
|
+
| `VOXBURST_LOG_LEVEL` | No | `info` | Log verbosity: `debug`, `info`, `warn`, or `error` |
|
|
40
|
+
| `VOXBURST_RATE_LIMIT` | No | `100` | Max requests per tool/resource key within the rate limit window |
|
|
41
|
+
| `VOXBURST_RATE_WINDOW_MS` | No | `60000` | Rate limit window in milliseconds |
|
|
33
42
|
|
|
34
43
|
Get your API key from [VoxBurst Settings](https://app.voxburst.io/settings/api).
|
|
35
44
|
|
|
@@ -42,9 +51,9 @@ Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/
|
|
|
42
51
|
"mcpServers": {
|
|
43
52
|
"voxburst": {
|
|
44
53
|
"command": "npx",
|
|
45
|
-
"args": ["@voxburst/mcp-server"],
|
|
54
|
+
"args": ["-y", "@voxburst/mcp-server"],
|
|
46
55
|
"env": {
|
|
47
|
-
"VOXBURST_API_KEY": "
|
|
56
|
+
"VOXBURST_API_KEY": "vb_live_your_api_key_here"
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
}
|
|
@@ -60,31 +69,74 @@ Add to your Cursor MCP settings:
|
|
|
60
69
|
"mcpServers": {
|
|
61
70
|
"voxburst": {
|
|
62
71
|
"command": "npx",
|
|
63
|
-
"args": ["@voxburst/mcp-server"],
|
|
72
|
+
"args": ["-y", "@voxburst/mcp-server"],
|
|
64
73
|
"env": {
|
|
65
|
-
"VOXBURST_API_KEY": "
|
|
74
|
+
"VOXBURST_API_KEY": "vb_live_your_api_key_here"
|
|
66
75
|
}
|
|
67
76
|
}
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
```
|
|
71
80
|
|
|
72
|
-
### Windsurf
|
|
81
|
+
### Windsurf
|
|
82
|
+
|
|
83
|
+
Add to `~/.codeium/windsurf/mcp_config.json` (create the file if it doesn't exist). The top-level key is `mcpServers`:
|
|
73
84
|
|
|
74
85
|
```json
|
|
75
86
|
{
|
|
76
|
-
"
|
|
87
|
+
"mcpServers": {
|
|
77
88
|
"voxburst": {
|
|
78
89
|
"command": "npx",
|
|
79
|
-
"args": ["@voxburst/mcp-server"],
|
|
90
|
+
"args": ["-y", "@voxburst/mcp-server"],
|
|
80
91
|
"env": {
|
|
81
|
-
"VOXBURST_API_KEY": "
|
|
92
|
+
"VOXBURST_API_KEY": "vb_live_your_api_key_here"
|
|
82
93
|
}
|
|
83
94
|
}
|
|
84
95
|
}
|
|
85
96
|
}
|
|
86
97
|
```
|
|
87
98
|
|
|
99
|
+
### VS Code
|
|
100
|
+
|
|
101
|
+
Add to `.vscode/mcp.json`. VS Code uses `servers` as the top-level key, not `mcpServers`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"servers": {
|
|
106
|
+
"voxburst": {
|
|
107
|
+
"type": "stdio",
|
|
108
|
+
"command": "npx",
|
|
109
|
+
"args": ["-y", "@voxburst/mcp-server"],
|
|
110
|
+
"env": {
|
|
111
|
+
"VOXBURST_API_KEY": "vb_live_your_api_key_here"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Claude Code
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
claude mcp add --env VOXBURST_API_KEY=vb_live_your_api_key_here --transport stdio voxburst \
|
|
122
|
+
-- npx -y @voxburst/mcp-server
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Codex CLI
|
|
126
|
+
|
|
127
|
+
Codex CLI uses TOML (`~/.codex/config.toml`), not JSON:
|
|
128
|
+
|
|
129
|
+
```toml
|
|
130
|
+
[mcp_servers.voxburst]
|
|
131
|
+
command = "npx"
|
|
132
|
+
args = ["-y", "@voxburst/mcp-server"]
|
|
133
|
+
|
|
134
|
+
[mcp_servers.voxburst.env]
|
|
135
|
+
VOXBURST_API_KEY = "vb_live_your_api_key_here"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Full setup details, tool reference, and troubleshooting: see the [MCP Server docs](https://docs.voxburst.io/sdks/mcp).
|
|
139
|
+
|
|
88
140
|
## Available Tools
|
|
89
141
|
|
|
90
142
|
### Post Management
|
|
@@ -94,10 +146,15 @@ Create a new social media post, optionally scheduled for later.
|
|
|
94
146
|
|
|
95
147
|
```typescript
|
|
96
148
|
{
|
|
97
|
-
content: string,
|
|
98
|
-
accountIds: string[],
|
|
99
|
-
mediaUrls?: string[],
|
|
100
|
-
|
|
149
|
+
content: string, // Post content (required)
|
|
150
|
+
accountIds: string[], // Target account IDs (required)
|
|
151
|
+
mediaUrls?: string[], // Public HTTPS URLs — registered with VoxBurst automatically
|
|
152
|
+
mediaIds?: string[], // VoxBurst media IDs for files already uploaded via /v1/media/upload
|
|
153
|
+
scheduledFor?: string, // ISO 8601 datetime for scheduling
|
|
154
|
+
saveAsDraft?: boolean, // Save as draft without publishing
|
|
155
|
+
contentType?: 'TEXT' | 'IMAGE' | 'VIDEO' | 'CAROUSEL' | 'REEL' | 'STORY' | 'THREAD', // Required for Instagram
|
|
156
|
+
firstComment?: string, // Auto-posted as a comment after publishing (max 2,200 chars)
|
|
157
|
+
firstCommentDelay?: number // Seconds to wait before posting the first comment (0-3600, default 0)
|
|
101
158
|
}
|
|
102
159
|
```
|
|
103
160
|
|
|
@@ -112,10 +169,10 @@ List posts with optional filtering.
|
|
|
112
169
|
|
|
113
170
|
```typescript
|
|
114
171
|
{
|
|
115
|
-
status?: 'draft' | 'scheduled' | 'published' | 'failed',
|
|
172
|
+
status?: 'draft' | 'approved' | 'scheduled' | 'publishing' | 'published' | 'failed' | 'partial' | 'cancelled' | 'unpublished' | 'archived' | 'all',
|
|
116
173
|
accountId?: string,
|
|
117
|
-
limit?: number,
|
|
118
|
-
|
|
174
|
+
limit?: number, // 1-100, default 20
|
|
175
|
+
cursor?: string // Pagination cursor from the previous response's next_cursor
|
|
119
176
|
}
|
|
120
177
|
```
|
|
121
178
|
|
|
@@ -142,8 +199,8 @@ Validate content against platform rules before posting.
|
|
|
142
199
|
|
|
143
200
|
```typescript
|
|
144
201
|
{
|
|
145
|
-
content: string,
|
|
146
|
-
|
|
202
|
+
content: string, // Content to validate (required)
|
|
203
|
+
platforms: string[] // Platform constants to validate against, e.g. ["TWITTER", "INSTAGRAM"] — not account IDs (required)
|
|
147
204
|
}
|
|
148
205
|
```
|
|
149
206
|
|
|
@@ -199,6 +256,8 @@ Resources provide read-only access to VoxBurst data:
|
|
|
199
256
|
| `accounts://{id}` | Single account details |
|
|
200
257
|
| `posts://recent` | Recent posts (last 20) |
|
|
201
258
|
| `posts://{id}` | Single post details |
|
|
259
|
+
| `voxburst://accounts` | All connected accounts (alternate URI scheme) |
|
|
260
|
+
| `voxburst://posts` | Recent posts (alternate URI scheme) |
|
|
202
261
|
|
|
203
262
|
## Example Conversations
|
|
204
263
|
|
|
@@ -257,7 +316,7 @@ npm run build
|
|
|
257
316
|
### Running Locally
|
|
258
317
|
|
|
259
318
|
```bash
|
|
260
|
-
VOXBURST_API_KEY=
|
|
319
|
+
VOXBURST_API_KEY=vb_test_xxx npm start
|
|
261
320
|
```
|
|
262
321
|
|
|
263
322
|
### Testing
|
|
@@ -268,12 +327,14 @@ npm test
|
|
|
268
327
|
|
|
269
328
|
## Error Handling
|
|
270
329
|
|
|
271
|
-
The server provides
|
|
330
|
+
The server provides structured error messages:
|
|
331
|
+
|
|
332
|
+
- **Missing API Key:** `Authentication error: No authentication configured. Set VOXBURST_API_KEY environment variable.`
|
|
333
|
+
- **Authentication Error:** `{"error":"API_ERROR","message":"API request failed: 401","statusCode":401}`
|
|
334
|
+
- **Rate Limiting:** `{"error":"RATE_LIMIT_EXCEEDED","message":"Rate limit exceeded for tool \"...\". Try again after ..."}`
|
|
335
|
+
- **Validation Error:** `{"error":"API_ERROR","message":"API request failed: 400","statusCode":400}`
|
|
272
336
|
|
|
273
|
-
|
|
274
|
-
- **Authentication Error:** `VoxBurst API Error (401): Invalid API key`
|
|
275
|
-
- **Rate Limiting:** `VoxBurst API Error (429): Rate limit exceeded`
|
|
276
|
-
- **Validation Error:** `VoxBurst API Error (400): Content exceeds platform limit`
|
|
337
|
+
GUI clients (Claude Desktop, Cursor, Windsurf) do not display these in the chat UI on failure — check the client's MCP log file (e.g. `~/Library/Logs/Claude/mcp*.log` for Claude Desktop). Set `VOXBURST_LOG_LEVEL=debug` for more detail. Full troubleshooting reference: [docs.voxburst.io/sdks/mcp](https://docs.voxburst.io/sdks/mcp#troubleshooting).
|
|
277
338
|
|
|
278
339
|
## Security
|
|
279
340
|
|
|
@@ -10,22 +10,29 @@ const analytics_js_1 = require("../tools/analytics.js");
|
|
|
10
10
|
// Mock client factory
|
|
11
11
|
function createMockClient() {
|
|
12
12
|
return {
|
|
13
|
+
// Shaped to match formatAccountResponse in
|
|
14
|
+
// src/services/account-service.ts — see the Account interface in client.ts.
|
|
13
15
|
listAccounts: vitest_1.vi.fn().mockResolvedValue([
|
|
14
16
|
{
|
|
15
17
|
id: 'acc_1',
|
|
16
18
|
platform: 'twitter',
|
|
17
|
-
|
|
19
|
+
username: 'test',
|
|
18
20
|
displayName: 'Test User',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
avatarUrl: null,
|
|
22
|
+
accountType: null,
|
|
23
|
+
status: 'active',
|
|
24
|
+
connectedAt: '2026-03-03T00:00:00Z',
|
|
21
25
|
},
|
|
22
26
|
]),
|
|
23
27
|
getAccount: vitest_1.vi.fn().mockResolvedValue({
|
|
24
28
|
id: 'acc_1',
|
|
25
29
|
platform: 'twitter',
|
|
26
|
-
|
|
30
|
+
username: 'test',
|
|
27
31
|
displayName: 'Test User',
|
|
28
|
-
|
|
32
|
+
avatarUrl: null,
|
|
33
|
+
accountType: null,
|
|
34
|
+
status: 'active',
|
|
35
|
+
connectedAt: '2026-03-03T00:00:00Z',
|
|
29
36
|
}),
|
|
30
37
|
createPost: vitest_1.vi.fn().mockResolvedValue({
|
|
31
38
|
id: 'post_1',
|
|
@@ -146,7 +153,7 @@ function createMockClient() {
|
|
|
146
153
|
(0, vitest_1.it)('validates content', async () => {
|
|
147
154
|
const result = await (0, posts_js_1.handleValidateContent)(client, {
|
|
148
155
|
content: 'Test content',
|
|
149
|
-
|
|
156
|
+
platforms: ['TWITTER'],
|
|
150
157
|
});
|
|
151
158
|
(0, vitest_1.expect)(result).toHaveProperty('valid', true);
|
|
152
159
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,mCAA8D;AAC9D,gDAA8H;AAC9H,sDAA4E;AAC5E,wDAAsF;AAGtF,sBAAsB;AACtB,SAAS,gBAAgB;IACvB,OAAO;QACL,YAAY,EAAE,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACtC;gBACE,EAAE,EAAE,OAAO;gBACX,QAAQ,EAAE,SAAS;gBACnB,
|
|
1
|
+
{"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -6,20 +6,84 @@ export interface VoxBurstConfig {
|
|
|
6
6
|
apiKey: string;
|
|
7
7
|
apiUrl: string;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Mirrors the `Account` payload returned by GET /v1/accounts and
|
|
11
|
+
* GET /v1/accounts/:id. Source of truth is `formatAccountResponse` in
|
|
12
|
+
* src/services/account-service.ts — keep this in sync with it, not with the
|
|
13
|
+
* database model.
|
|
14
|
+
*
|
|
15
|
+
* The client casts responses without runtime validation, so a field declared
|
|
16
|
+
* here that the API does not send is not a type error — it is a lie that
|
|
17
|
+
* propagates into MCP tool descriptions and makes an agent reason about data
|
|
18
|
+
* that never arrives.
|
|
19
|
+
*
|
|
20
|
+
* `null` vs absent is meaningful: the first five fields are always serialized
|
|
21
|
+
* and may be null; every optional field below is omitted from the payload
|
|
22
|
+
* entirely rather than sent as null.
|
|
23
|
+
*/
|
|
9
24
|
export interface Account {
|
|
10
25
|
id: string;
|
|
26
|
+
/** Lowercased on the wire (e.g. 'google_business', not 'GOOGLE_BUSINESS'). */
|
|
11
27
|
platform: 'twitter' | 'linkedin' | 'instagram' | 'facebook' | 'tiktok' | 'threads' | 'bluesky' | 'youtube' | 'pinterest' | 'reddit' | 'snapchat' | 'telegram' | 'google_business' | 'mastodon' | 'whatsapp';
|
|
12
|
-
handle
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
28
|
+
/** Platform handle. Null when the platform does not expose one. */
|
|
29
|
+
username: string | null;
|
|
30
|
+
/** Human-readable account name. Null when unknown. */
|
|
31
|
+
displayName: string | null;
|
|
32
|
+
/** Profile picture URL. Null when the platform did not supply one. */
|
|
33
|
+
avatarUrl: string | null;
|
|
34
|
+
/** Platform-specific classification (e.g. 'business', 'creator'). Null when not applicable. */
|
|
35
|
+
accountType: string | null;
|
|
36
|
+
/** Lowercased on the wire. */
|
|
37
|
+
status: 'active' | 'expired' | 'revoked' | 'disconnected';
|
|
38
|
+
/** ISO 8601. */
|
|
39
|
+
connectedAt: string;
|
|
40
|
+
/** From the latest metrics snapshot. Absent when no snapshot has a follower count. */
|
|
41
|
+
followers?: number;
|
|
42
|
+
/** Instagram only: 'fb_login' (Facebook Login / FLOB) or 'instagram_login' (Instagram Direct). */
|
|
43
|
+
oauthVersion?: string;
|
|
44
|
+
/** Instagram only: whether a connected Facebook account can unlock Facebook Login for Business. */
|
|
45
|
+
flobProbe?: {
|
|
46
|
+
flobAvailable: boolean;
|
|
47
|
+
facebookAccountId?: string;
|
|
48
|
+
facebookPlatformUserId?: string;
|
|
49
|
+
pageId?: string;
|
|
50
|
+
checkedAt: string;
|
|
51
|
+
};
|
|
52
|
+
/** YouTube only: true when the connection predates the full 'youtube' scope and cannot manage playlists until reconnected. */
|
|
53
|
+
needsPlaylistReauth?: boolean;
|
|
54
|
+
/** LinkedIn only: true when the connection lacks 'w_organization_social' and cannot post to company pages until reconnected. */
|
|
55
|
+
needsOrgScopeReauth?: boolean;
|
|
56
|
+
/** Google Business only: true when at least one location has been selected to sync. */
|
|
57
|
+
gmbLocationsConfigured?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Connect-time scope verification result.
|
|
60
|
+
*
|
|
61
|
+
* ABSENT IS NOT HEALTHY. Accounts connected before scope verification shipped
|
|
62
|
+
* have no result at all. Treat a missing `scopeHealth` as unknown — do not
|
|
63
|
+
* report the account as fully permissioned on the strength of its absence.
|
|
64
|
+
*/
|
|
65
|
+
scopeHealth?: {
|
|
66
|
+
/** 'OK' | 'DEGRADED' | 'UNKNOWN' | 'NOT_APPLICABLE' */
|
|
67
|
+
status: string;
|
|
68
|
+
/** Capabilities that cannot work with what the platform granted. */
|
|
69
|
+
degradedCapabilities: Array<{
|
|
70
|
+
capability: string;
|
|
71
|
+
label: string;
|
|
72
|
+
/** Granted for a different Page/account rather than missing outright. */
|
|
73
|
+
grantedForOtherTargetsOnly?: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
/** One user-facing sentence. Absent when the account is healthy. */
|
|
76
|
+
message?: string;
|
|
77
|
+
/** Why the granted set is unknown or not applicable. */
|
|
78
|
+
reason?: string;
|
|
79
|
+
verifiedAt?: string;
|
|
80
|
+
};
|
|
17
81
|
}
|
|
18
82
|
export interface Post {
|
|
19
83
|
id: string;
|
|
20
84
|
content: string;
|
|
21
85
|
mediaUrls?: string[];
|
|
22
|
-
status: 'draft' | 'scheduled' | 'published' | 'failed' | 'cancelled' | 'unpublished';
|
|
86
|
+
status: 'draft' | 'approved' | 'scheduled' | 'publishing' | 'published' | 'failed' | 'partial' | 'cancelled' | 'unpublished' | 'archived';
|
|
23
87
|
scheduledFor?: string;
|
|
24
88
|
publishedAt?: string;
|
|
25
89
|
accounts: string[];
|
|
@@ -54,15 +118,27 @@ export interface AccountMetrics {
|
|
|
54
118
|
avgEngagementRate: number;
|
|
55
119
|
collectedAt: string;
|
|
56
120
|
}
|
|
121
|
+
export type ContentType = 'TEXT' | 'IMAGE' | 'VIDEO' | 'CAROUSEL' | 'THREAD' | 'STORY' | 'REEL';
|
|
122
|
+
export interface MediaRecord {
|
|
123
|
+
id: string;
|
|
124
|
+
filename: string;
|
|
125
|
+
contentType: string;
|
|
126
|
+
status: string;
|
|
127
|
+
publicUrl?: string;
|
|
128
|
+
}
|
|
57
129
|
export interface CreatePostRequest {
|
|
58
130
|
content: string;
|
|
59
131
|
mediaUrls?: string[];
|
|
132
|
+
mediaIds?: string[];
|
|
60
133
|
accountIds: string[];
|
|
61
134
|
scheduledFor?: string;
|
|
62
135
|
saveAsDraft?: boolean;
|
|
136
|
+
contentType?: ContentType;
|
|
137
|
+
firstComment?: string;
|
|
138
|
+
firstCommentDelay?: number;
|
|
63
139
|
}
|
|
64
140
|
export interface ListPostsRequest {
|
|
65
|
-
status?: Post['status'];
|
|
141
|
+
status?: Post['status'] | 'all';
|
|
66
142
|
accountId?: string;
|
|
67
143
|
limit?: number;
|
|
68
144
|
cursor?: string;
|
|
@@ -71,6 +147,13 @@ export interface UpdatePostRequest {
|
|
|
71
147
|
content?: string;
|
|
72
148
|
scheduledFor?: string;
|
|
73
149
|
accountIds?: string[];
|
|
150
|
+
contentType?: ContentType;
|
|
151
|
+
firstComment?: string;
|
|
152
|
+
firstCommentDelay?: number;
|
|
153
|
+
media?: string[];
|
|
154
|
+
platformOverrides?: Record<string, {
|
|
155
|
+
content?: string;
|
|
156
|
+
}>;
|
|
74
157
|
}
|
|
75
158
|
export interface AnalyticsOverviewParams {
|
|
76
159
|
startDate?: string;
|
|
@@ -115,6 +198,7 @@ export declare class VoxBurstClient {
|
|
|
115
198
|
private request;
|
|
116
199
|
listAccounts(): Promise<Account[]>;
|
|
117
200
|
getAccount(accountId: string): Promise<Account>;
|
|
201
|
+
registerMedia(url: string, contentType: string, filename?: string): Promise<MediaRecord>;
|
|
118
202
|
createPost(request: CreatePostRequest): Promise<Post>;
|
|
119
203
|
listPosts(params?: ListPostsRequest): Promise<Post[]>;
|
|
120
204
|
getPost(postId: string): Promise<Post>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,iBAAiB,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5M,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -6,6 +6,15 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.VoxBurstClient = exports.VoxBurstAPIError = void 0;
|
|
8
8
|
exports.createClientFromEnv = createClientFromEnv;
|
|
9
|
+
function inferContentType(url) {
|
|
10
|
+
const ext = url.split('?')[0].split('.').pop()?.toLowerCase() ?? '';
|
|
11
|
+
const map = {
|
|
12
|
+
jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png',
|
|
13
|
+
gif: 'image/gif', webp: 'image/webp',
|
|
14
|
+
mp4: 'video/mp4', mov: 'video/quicktime', webm: 'video/webm', avi: 'video/x-msvideo',
|
|
15
|
+
};
|
|
16
|
+
return map[ext] ?? 'image/jpeg';
|
|
17
|
+
}
|
|
9
18
|
class VoxBurstAPIError extends Error {
|
|
10
19
|
statusCode;
|
|
11
20
|
code;
|
|
@@ -45,8 +54,8 @@ class VoxBurstClient {
|
|
|
45
54
|
let errorCode;
|
|
46
55
|
try {
|
|
47
56
|
const errorJson = JSON.parse(errorBody);
|
|
48
|
-
errorMessage = errorJson.message
|
|
49
|
-
errorCode = errorJson.code;
|
|
57
|
+
errorMessage = errorJson.error?.message ?? errorJson.message ?? errorMessage;
|
|
58
|
+
errorCode = errorJson.error?.code ?? errorJson.code;
|
|
50
59
|
}
|
|
51
60
|
catch {
|
|
52
61
|
// Use default error message
|
|
@@ -63,9 +72,27 @@ class VoxBurstClient {
|
|
|
63
72
|
async getAccount(accountId) {
|
|
64
73
|
return this.request('GET', `/v1/accounts/${accountId}`);
|
|
65
74
|
}
|
|
75
|
+
// Media Methods
|
|
76
|
+
async registerMedia(url, contentType, filename) {
|
|
77
|
+
return this.request('POST', '/v1/media/register', { url, contentType, filename });
|
|
78
|
+
}
|
|
66
79
|
// Post Methods
|
|
67
80
|
async createPost(request) {
|
|
68
|
-
|
|
81
|
+
const { mediaUrls, mediaIds, ...rest } = request;
|
|
82
|
+
// Resolve mediaUrls to registered media IDs before posting
|
|
83
|
+
const resolvedIds = [...(mediaIds ?? [])];
|
|
84
|
+
if (mediaUrls && mediaUrls.length > 0) {
|
|
85
|
+
for (const url of mediaUrls) {
|
|
86
|
+
const ct = inferContentType(url);
|
|
87
|
+
const filename = url.split('/').pop()?.split('?')[0] ?? 'media';
|
|
88
|
+
const record = await this.registerMedia(url, ct, filename);
|
|
89
|
+
resolvedIds.push(record.id);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return this.request('POST', '/v1/posts', {
|
|
93
|
+
...rest,
|
|
94
|
+
...(resolvedIds.length > 0 ? { media: resolvedIds } : {}),
|
|
95
|
+
});
|
|
69
96
|
}
|
|
70
97
|
async listPosts(params) {
|
|
71
98
|
const queryParams = new URLSearchParams();
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA+
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ const rate_limiter_js_1 = require("./middleware/rate-limiter.js");
|
|
|
19
19
|
const auth_js_1 = require("./middleware/auth.js");
|
|
20
20
|
const logger_js_1 = require("./middleware/logger.js");
|
|
21
21
|
const SERVER_NAME = 'voxburst';
|
|
22
|
-
const SERVER_VERSION = '0.
|
|
22
|
+
const SERVER_VERSION = '0.3.0';
|
|
23
23
|
/**
|
|
24
24
|
* Create and configure the MCP server with production hardening
|
|
25
25
|
*/
|
|
@@ -163,7 +163,8 @@ function createServer(client, logger, rateLimiter) {
|
|
|
163
163
|
const { uri } = request.params;
|
|
164
164
|
const startTime = Date.now();
|
|
165
165
|
// Rate limiting for resource reads
|
|
166
|
-
const
|
|
166
|
+
const normalizedUri = uri.split('?')[0].split('#')[0];
|
|
167
|
+
const rateResult = rateLimiter.check(`resource:${normalizedUri}`);
|
|
167
168
|
if (!rateResult.allowed) {
|
|
168
169
|
logger.warn('Rate limit exceeded for resource', { resource: uri });
|
|
169
170
|
throw new Error(`Rate limit exceeded. Try again after ${new Date(rateResult.resetAt).toISOString()}.`);
|
|
@@ -235,6 +236,10 @@ function formatErrorResponse(error) {
|
|
|
235
236
|
*/
|
|
236
237
|
function formatErrorMessage(error) {
|
|
237
238
|
if (error instanceof client_js_1.VoxBurstAPIError) {
|
|
239
|
+
// Don't leak internal server error details to MCP clients
|
|
240
|
+
if (error.statusCode >= 500) {
|
|
241
|
+
return `VoxBurst API Error (${error.statusCode}): An internal error occurred. Please try again.`;
|
|
242
|
+
}
|
|
238
243
|
return `VoxBurst API Error (${error.statusCode}): ${error.message}${error.code ? ` [${error.code}]` : ''}`;
|
|
239
244
|
}
|
|
240
245
|
if (error instanceof Error) {
|
|
@@ -256,13 +261,36 @@ async function main() {
|
|
|
256
261
|
console.error(`Authentication error: ${authResult.error}`);
|
|
257
262
|
process.exit(1);
|
|
258
263
|
}
|
|
259
|
-
logger.info('
|
|
264
|
+
logger.info('API key present', { method: authResult.method });
|
|
260
265
|
// Create API client from environment
|
|
261
266
|
const client = (0, client_js_1.createClientFromEnv)();
|
|
267
|
+
// Verify the API key actually works with a single lightweight authenticated
|
|
268
|
+
// call, before completing MCP initialize. Presence alone (checked above) is
|
|
269
|
+
// not proof of validity — an invalid/expired key would otherwise only be
|
|
270
|
+
// discovered on the first tool call, producing a confusing "connected but
|
|
271
|
+
// broken" state. Keep this to one request — no retries, no long timeouts.
|
|
272
|
+
try {
|
|
273
|
+
await client.listAccounts();
|
|
274
|
+
logger.info('Authentication validated', { method: authResult.method });
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
const message = error instanceof client_js_1.VoxBurstAPIError
|
|
278
|
+
? `${error.message}${error.code ? ` [${error.code}]` : ''}`
|
|
279
|
+
: error instanceof Error
|
|
280
|
+
? error.message
|
|
281
|
+
: String(error);
|
|
282
|
+
logger.error('API key validation failed', { error: message });
|
|
283
|
+
console.error(`Authentication error: ${message}`);
|
|
284
|
+
process.exit(1);
|
|
285
|
+
}
|
|
262
286
|
// Create rate limiter
|
|
287
|
+
const _parseRateInt = (val, fallback) => {
|
|
288
|
+
const n = parseInt(val ?? '', 10);
|
|
289
|
+
return Number.isFinite(n) && n > 0 ? n : fallback;
|
|
290
|
+
};
|
|
263
291
|
const rateLimiter = new rate_limiter_js_1.RateLimiter({
|
|
264
|
-
maxRequests:
|
|
265
|
-
windowMs:
|
|
292
|
+
maxRequests: _parseRateInt(process.env.VOXBURST_RATE_LIMIT, 100),
|
|
293
|
+
windowMs: _parseRateInt(process.env.VOXBURST_RATE_WINDOW_MS, 60000),
|
|
266
294
|
});
|
|
267
295
|
// Create and start server
|
|
268
296
|
const server = createServer(client, logger, rateLimiter);
|