@vdoninja/mcp 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/SKILL.md +90 -0
- package/assets/cloudflare/worker-proxy.js +89 -0
- package/assets/cloudflare/wrangler.toml.example +10 -0
- package/package.json +66 -0
- package/references/advanced-diagnostics.md +45 -0
- package/references/mcp-tool-contract.md +184 -0
- package/references/quickstart-and-compat.md +198 -0
- package/references/vdo-ninja-p2p-data-notes.md +156 -0
- package/scripts/demo-file-workflow.js +168 -0
- package/scripts/demo-message-workflow.js +167 -0
- package/scripts/install-mcp.js +302 -0
- package/scripts/lib/bridge-session.js +2331 -0
- package/scripts/lib/bridge-utils.js +185 -0
- package/scripts/lib/fake-network-sdk.js +293 -0
- package/scripts/lib/load-vdo-sdk.js +36 -0
- package/scripts/lib/mcp-stdio-parser.js +137 -0
- package/scripts/lib/tool-profiles.js +122 -0
- package/scripts/vdo-data-bridge.js +157 -0
- package/scripts/vdo-mcp-server.js +1425 -0
- package/scripts/vdo-mcp-streamable-http.js +270 -0
- package/server.json +134 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mcp
|
|
3
|
+
description: Use VDO.Ninja WebRTC data channels as MCP tools for bot-to-bot messaging and reliable file transfer, with clear transport limits, optional TURN, and optional join-token/session-MAC security.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# VDO.Ninja MCP Skill
|
|
7
|
+
|
|
8
|
+
Use this skill to run VDO.Ninja as an MCP data bridge in Codex, Claude Code, and compatible MCP clients.
|
|
9
|
+
|
|
10
|
+
## What It Is For
|
|
11
|
+
|
|
12
|
+
- Fast bot-to-bot data messaging.
|
|
13
|
+
- Reliable file send/receive over WebRTC data channels.
|
|
14
|
+
- Optional secure room membership and peer allowlists.
|
|
15
|
+
|
|
16
|
+
## What It Is Not
|
|
17
|
+
|
|
18
|
+
- Not a generic TCP tunnel.
|
|
19
|
+
- Not guaranteed firewall bypass.
|
|
20
|
+
|
|
21
|
+
## Core Transport Truth
|
|
22
|
+
|
|
23
|
+
- Transport is WebRTC data channels.
|
|
24
|
+
- TURN can improve success on restrictive networks.
|
|
25
|
+
- TURN is not guaranteed to bypass all enterprise policies.
|
|
26
|
+
|
|
27
|
+
## Fast Path
|
|
28
|
+
|
|
29
|
+
1. Install MCP registration:
|
|
30
|
+
`npm i @vdoninja/mcp @roamhq/wrtc`
|
|
31
|
+
|
|
32
|
+
2. Register for Codex/Claude:
|
|
33
|
+
`npx vdon-mcp-install`
|
|
34
|
+
|
|
35
|
+
3. Start server:
|
|
36
|
+
`npx vdon-mcp-server`
|
|
37
|
+
|
|
38
|
+
4. Optional least-privilege tool profile:
|
|
39
|
+
`VDON_MCP_TOOL_PROFILE=core|file|state|full npx vdon-mcp-server`
|
|
40
|
+
|
|
41
|
+
5. First tool call:
|
|
42
|
+
`{ "name": "vdo_capabilities", "arguments": {} }`
|
|
43
|
+
|
|
44
|
+
## Two Primary Workflows
|
|
45
|
+
|
|
46
|
+
### Workflow A: Messaging
|
|
47
|
+
|
|
48
|
+
- Connect peer A and peer B with `vdo_connect`.
|
|
49
|
+
- Send with `vdo_send`.
|
|
50
|
+
- Receive with `vdo_receive`.
|
|
51
|
+
- Demo script: `npm run mcp:demo:message`
|
|
52
|
+
|
|
53
|
+
### Workflow B: File Transfer
|
|
54
|
+
|
|
55
|
+
- Send with `vdo_file_send` or `vdo_file_send_path`.
|
|
56
|
+
- Track with `vdo_file_transfers`.
|
|
57
|
+
- Read with `vdo_file_receive` or persist with `vdo_file_save`.
|
|
58
|
+
- Resume interrupted send with `vdo_file_resume`.
|
|
59
|
+
- Demo script: `npm run mcp:demo:file`
|
|
60
|
+
|
|
61
|
+
## Security Controls
|
|
62
|
+
|
|
63
|
+
- `join_token` + `join_token_secret`
|
|
64
|
+
- `enforce_join_token`
|
|
65
|
+
- `allow_peer_stream_ids`
|
|
66
|
+
- `require_session_mac`
|
|
67
|
+
|
|
68
|
+
For secure presets, set `VDON_MCP_JOIN_TOKEN_SECRET` before install/runtime.
|
|
69
|
+
`@vdoninja/mcp` depends on `@vdoninja/sdk`, so SDK installs transitively.
|
|
70
|
+
|
|
71
|
+
## AI Agent Contract
|
|
72
|
+
|
|
73
|
+
- Call `vdo_capabilities` first.
|
|
74
|
+
- Call `vdo_connect` before send/file/state tools.
|
|
75
|
+
- Prefer least-privilege tool profile.
|
|
76
|
+
- For files, use file tools instead of manual chunking via `vdo_send`.
|
|
77
|
+
- Handle `validation_error` and retry idempotently.
|
|
78
|
+
|
|
79
|
+
## Testing
|
|
80
|
+
|
|
81
|
+
- Product test bar: `npm run test:mcp`
|
|
82
|
+
- Full engineering suite: `npm run test:mcp:all`
|
|
83
|
+
- Live diagnostics (optional): `MCP/references/advanced-diagnostics.md`
|
|
84
|
+
|
|
85
|
+
## References
|
|
86
|
+
|
|
87
|
+
- Operator quickstart: `MCP/references/quickstart-and-compat.md`
|
|
88
|
+
- Tool contract: `MCP/references/mcp-tool-contract.md`
|
|
89
|
+
- Transport notes: `MCP/references/vdo-ninja-p2p-data-notes.md`
|
|
90
|
+
- Registry manifest: `MCP/server.json`
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Worker proxy template for a remote MCP HTTP endpoint.
|
|
3
|
+
*
|
|
4
|
+
* This Worker does not run WebRTC itself.
|
|
5
|
+
* It forwards MCP JSON-RPC requests to an upstream vdo-mcp-streamable-http server.
|
|
6
|
+
*
|
|
7
|
+
* Required secrets/config:
|
|
8
|
+
* - MCP_UPSTREAM_URL: e.g. https://your-origin.example.com/mcp
|
|
9
|
+
* - MCP_UPSTREAM_TOKEN: bearer token expected by upstream server
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
async fetch(request, env) {
|
|
14
|
+
const url = new URL(request.url);
|
|
15
|
+
|
|
16
|
+
if (request.method === 'OPTIONS') {
|
|
17
|
+
return new Response(null, {
|
|
18
|
+
status: 204,
|
|
19
|
+
headers: corsHeaders(env)
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (url.pathname === '/health') {
|
|
24
|
+
return json({
|
|
25
|
+
ok: true,
|
|
26
|
+
mode: 'cloudflare_proxy',
|
|
27
|
+
ts: new Date().toISOString()
|
|
28
|
+
}, 200, env);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (url.pathname !== '/mcp') {
|
|
32
|
+
return json({ ok: false, error: 'not_found' }, 404, env);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (request.method !== 'POST') {
|
|
36
|
+
return json({ ok: false, error: 'method_not_allowed' }, 405, env);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const upstreamUrl = env.MCP_UPSTREAM_URL;
|
|
40
|
+
if (!upstreamUrl) {
|
|
41
|
+
return json({ ok: false, error: 'missing_upstream_url' }, 500, env);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const upstreamToken = env.MCP_UPSTREAM_TOKEN || '';
|
|
45
|
+
const body = await request.text();
|
|
46
|
+
|
|
47
|
+
const headers = {
|
|
48
|
+
'content-type': 'application/json'
|
|
49
|
+
};
|
|
50
|
+
if (upstreamToken) {
|
|
51
|
+
headers.authorization = `Bearer ${upstreamToken}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const upstreamRes = await fetch(upstreamUrl, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers,
|
|
57
|
+
body
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const upstreamBody = await upstreamRes.text();
|
|
61
|
+
return new Response(upstreamBody, {
|
|
62
|
+
status: upstreamRes.status,
|
|
63
|
+
headers: {
|
|
64
|
+
...corsHeaders(env),
|
|
65
|
+
'content-type': upstreamRes.headers.get('content-type') || 'application/json; charset=utf-8'
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function json(payload, status, env) {
|
|
72
|
+
return new Response(JSON.stringify(payload), {
|
|
73
|
+
status,
|
|
74
|
+
headers: {
|
|
75
|
+
...corsHeaders(env),
|
|
76
|
+
'content-type': 'application/json; charset=utf-8'
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function corsHeaders(env) {
|
|
82
|
+
const allowOrigin = env.MCP_ALLOW_ORIGIN || '*';
|
|
83
|
+
return {
|
|
84
|
+
'access-control-allow-origin': allowOrigin,
|
|
85
|
+
'access-control-allow-methods': 'GET,POST,OPTIONS',
|
|
86
|
+
'access-control-allow-headers': 'authorization,content-type',
|
|
87
|
+
'access-control-max-age': '600'
|
|
88
|
+
};
|
|
89
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vdoninja/mcp",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "VDO.Ninja MCP bridge for WebRTC data-channel messaging, file transfer, and room sync.",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"homepage": "https://github.com/steveseguin/ninjasdk/tree/main/MCP",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/steveseguin/ninjasdk.git",
|
|
10
|
+
"directory": "MCP"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/steveseguin/ninjasdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"vdo.ninja",
|
|
19
|
+
"webrtc",
|
|
20
|
+
"data-channel",
|
|
21
|
+
"p2p",
|
|
22
|
+
"ai"
|
|
23
|
+
],
|
|
24
|
+
"bin": {
|
|
25
|
+
"vdon-mcp-install": "scripts/install-mcp.js",
|
|
26
|
+
"vdon-mcp-server": "scripts/vdo-mcp-server.js",
|
|
27
|
+
"vdon-mcp-http": "scripts/vdo-mcp-streamable-http.js",
|
|
28
|
+
"vdon-mcp-demo-message": "scripts/demo-message-workflow.js",
|
|
29
|
+
"vdon-mcp-demo-file": "scripts/demo-file-workflow.js"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"mcp:install": "node scripts/install-mcp.js",
|
|
33
|
+
"mcp:server": "node scripts/vdo-mcp-server.js",
|
|
34
|
+
"mcp:http": "node scripts/vdo-mcp-streamable-http.js",
|
|
35
|
+
"demo:message": "node scripts/demo-message-workflow.js",
|
|
36
|
+
"demo:file": "node scripts/demo-file-workflow.js"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"SKILL.md",
|
|
40
|
+
"server.json",
|
|
41
|
+
"assets/cloudflare/worker-proxy.js",
|
|
42
|
+
"assets/cloudflare/wrangler.toml.example",
|
|
43
|
+
"references/advanced-diagnostics.md",
|
|
44
|
+
"references/mcp-tool-contract.md",
|
|
45
|
+
"references/quickstart-and-compat.md",
|
|
46
|
+
"references/vdo-ninja-p2p-data-notes.md",
|
|
47
|
+
"scripts/demo-file-workflow.js",
|
|
48
|
+
"scripts/demo-message-workflow.js",
|
|
49
|
+
"scripts/install-mcp.js",
|
|
50
|
+
"scripts/vdo-data-bridge.js",
|
|
51
|
+
"scripts/vdo-mcp-server.js",
|
|
52
|
+
"scripts/vdo-mcp-streamable-http.js",
|
|
53
|
+
"scripts/lib/bridge-session.js",
|
|
54
|
+
"scripts/lib/bridge-utils.js",
|
|
55
|
+
"scripts/lib/fake-network-sdk.js",
|
|
56
|
+
"scripts/lib/load-vdo-sdk.js",
|
|
57
|
+
"scripts/lib/mcp-stdio-parser.js",
|
|
58
|
+
"scripts/lib/tool-profiles.js"
|
|
59
|
+
],
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=18"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"@vdoninja/sdk": "^1.3.18"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# VDO.Ninja MCP Advanced Diagnostics
|
|
2
|
+
|
|
3
|
+
This page is optional. Use it when you are debugging reliability or network edge cases.
|
|
4
|
+
|
|
5
|
+
## Live Test Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
LIVE_VDO_TEST=1 npm run test:mcp:live
|
|
9
|
+
LIVE_VDO_TEST=1 npm run test:mcp:soak
|
|
10
|
+
LIVE_VDO_TEST=1 npm run test:mcp:matrix
|
|
11
|
+
LIVE_VDO_TEST=1 npm run test:mcp:preset:matrix
|
|
12
|
+
LIVE_VDO_TEST=1 SOAK_MATRIX_SWEEP_RUNS=20 npm run test:mcp:matrix:sweep
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Secure preset matrix:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
LIVE_VDO_TEST=1 VDON_MCP_JOIN_TOKEN_SECRET=change_me npm run test:mcp:preset:matrix
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Preset Matrix Notes
|
|
22
|
+
|
|
23
|
+
- `PRESET_MATRIX_ADAPTIVE_FALLBACK=1` enables candidate fallback.
|
|
24
|
+
- `PRESET_MATRIX_ALLOW_DIRECT_FALLBACK=1` allows direct fallback after TURN candidates.
|
|
25
|
+
- `PRESET_MATRIX_STRICT=1` fails process when any profile fails.
|
|
26
|
+
- `PRESET_CONNECT_ATTEMPTS`, `PRESET_CONNECT_TIMEOUT_MS`, and `PRESET_CHANNEL_READY_TIMEOUT_MS` control connect behavior.
|
|
27
|
+
|
|
28
|
+
Artifacts are written to:
|
|
29
|
+
|
|
30
|
+
- `MCP/tests/artifacts/latest-preset-matrix-report.json`
|
|
31
|
+
- `MCP/tests/artifacts/latest-preset-matrix-summary.txt`
|
|
32
|
+
- `MCP/tests/artifacts/history/preset-matrix-*.json`
|
|
33
|
+
- `MCP/tests/artifacts/history/preset-matrix-*.txt`
|
|
34
|
+
|
|
35
|
+
## Soak / Matrix Knobs
|
|
36
|
+
|
|
37
|
+
- Smoke: `LIVE_SMOKE_RETRIES`, `LIVE_SMOKE_TIMEOUT_MS`
|
|
38
|
+
- Soak: `SOAK_RETRIES`, `SOAK_TIMEOUT_MS`
|
|
39
|
+
- Matrix: `SOAK_MATRIX_PROFILE_RETRIES`, `SOAK_MATRIX_PROFILE_TIMEOUT_MS`
|
|
40
|
+
- Sweep: `SOAK_MATRIX_SWEEP_RUNS`, `SOAK_MATRIX_SWEEP_TIMEOUT_MS`, `SOAK_MATRIX_SWEEP_MIN_SUCCESS_RATE`
|
|
41
|
+
|
|
42
|
+
## Important
|
|
43
|
+
|
|
44
|
+
- WebRTC data channels are the transport.
|
|
45
|
+
- TURN helps reachability but is not a universal bypass for all enterprise firewall policies.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# VDO.Ninja MCP Tool Contract
|
|
2
|
+
|
|
3
|
+
Implemented by:
|
|
4
|
+
|
|
5
|
+
- `MCP/scripts/vdo-mcp-server.js`
|
|
6
|
+
- Installer automation: `MCP/scripts/install-mcp.js`
|
|
7
|
+
- Discovery manifest: `MCP/server.json`
|
|
8
|
+
|
|
9
|
+
## Transport
|
|
10
|
+
|
|
11
|
+
- JSON-RPC 2.0 over stdio
|
|
12
|
+
- Input:
|
|
13
|
+
- newline-delimited JSON messages
|
|
14
|
+
- `Content-Length` framed messages
|
|
15
|
+
- Output:
|
|
16
|
+
- framed when framed input is detected
|
|
17
|
+
- newline JSON otherwise
|
|
18
|
+
|
|
19
|
+
## Runtime Limit
|
|
20
|
+
|
|
21
|
+
- `VDON_MCP_MAX_MESSAGE_BYTES` (default `1048576`)
|
|
22
|
+
- `VDON_MCP_TOOL_PROFILE` (default `full`, values: `core|file|state|full`)
|
|
23
|
+
|
|
24
|
+
## Server CLI Flags
|
|
25
|
+
|
|
26
|
+
Supported by `MCP/scripts/vdo-mcp-server.js`:
|
|
27
|
+
|
|
28
|
+
- `--tool-profile <core|file|state|full>`
|
|
29
|
+
- `--max-message-bytes <bytes>`
|
|
30
|
+
- `--join-token-secret <secret>`
|
|
31
|
+
- `--enforce-join-token <true|false>`
|
|
32
|
+
- `--allow-peer-stream-ids <a,b,c>`
|
|
33
|
+
- `--require-session-mac <true|false>`
|
|
34
|
+
|
|
35
|
+
## Capability Profiles
|
|
36
|
+
|
|
37
|
+
- `core`: `vdo_connect`, `vdo_send`, `vdo_receive`, `vdo_status`, `vdo_disconnect`, `vdo_list_sessions`, `vdo_capabilities`, `vdo_sync_peers`, `vdo_sync_announce`
|
|
38
|
+
- `file`: `core` + all file transfer tools
|
|
39
|
+
- `state`: `core` + all state sync tools
|
|
40
|
+
- `full`: `core` + file + state tools
|
|
41
|
+
|
|
42
|
+
Enforcement:
|
|
43
|
+
|
|
44
|
+
- `tools/list` only advertises tools in the active profile.
|
|
45
|
+
- Calling a disabled tool returns `validation_error`.
|
|
46
|
+
|
|
47
|
+
## Core Session Tools
|
|
48
|
+
|
|
49
|
+
- `vdo_connect`
|
|
50
|
+
- `vdo_send`
|
|
51
|
+
- `vdo_receive`
|
|
52
|
+
- `vdo_status`
|
|
53
|
+
- `vdo_disconnect`
|
|
54
|
+
- `vdo_list_sessions`
|
|
55
|
+
- `vdo_capabilities`
|
|
56
|
+
|
|
57
|
+
### `vdo_connect` notable options
|
|
58
|
+
|
|
59
|
+
- transport: `room`, `stream_id`, `target_stream_id`, `host`, `force_turn`
|
|
60
|
+
- resiliency: `heartbeat_ms`, `reconnect_ms`, `max_reconnect_ms`
|
|
61
|
+
- security: `join_token`, `join_token_secret`, `join_token_ttl_ms`, `enforce_join_token`, `allow_peer_stream_ids`, `require_session_mac`
|
|
62
|
+
- file defaults: `file_chunk_bytes`, `file_max_bytes`, `file_ack_timeout_ms`, `file_max_retries`
|
|
63
|
+
- file spooling: `file_spool_dir`, `file_spool_threshold_bytes`, `keep_spool_files`
|
|
64
|
+
- state limits: `state_max_keys`, `state_max_snapshot_entries`
|
|
65
|
+
|
|
66
|
+
## Sync Tools
|
|
67
|
+
|
|
68
|
+
- `vdo_sync_peers`: peer handshake/auth/state capabilities
|
|
69
|
+
- `vdo_sync_announce`: force immediate sync hello
|
|
70
|
+
|
|
71
|
+
## File Transfer Tools
|
|
72
|
+
|
|
73
|
+
- `vdo_file_send`: send from `data_base64`
|
|
74
|
+
- `vdo_file_send_path`: send directly from local `file_path`
|
|
75
|
+
- `vdo_file_resume`: resume outgoing transfer by `transfer_id`
|
|
76
|
+
- `vdo_file_transfers`: inspect incoming/outgoing transfer state
|
|
77
|
+
- `vdo_file_receive`: read completed incoming payload (`base64`/`utf8`/`json`)
|
|
78
|
+
- `vdo_file_save`: save completed incoming transfer directly to disk
|
|
79
|
+
|
|
80
|
+
## State Sync Tools (CRDT-lite)
|
|
81
|
+
|
|
82
|
+
- `vdo_state_set`: update key/value with local monotonic clock
|
|
83
|
+
- `vdo_state_get`: read key or full state snapshot
|
|
84
|
+
- `vdo_state_sync`: request/send full snapshot (`mode: request|send`)
|
|
85
|
+
|
|
86
|
+
Merge rule is tuple-based last-writer:
|
|
87
|
+
|
|
88
|
+
1. higher `clock` wins
|
|
89
|
+
2. if equal clock, lexicographically higher `actor` wins
|
|
90
|
+
|
|
91
|
+
## Protocol Envelope Family
|
|
92
|
+
|
|
93
|
+
Internal control/file/state envelopes use:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"__vdo_mcp": "vdo_mcp_bridge_v1",
|
|
98
|
+
"kind": "sync.* | file.* | state.*",
|
|
99
|
+
"payload": {}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Event Types via `vdo_receive`
|
|
104
|
+
|
|
105
|
+
Lifecycle:
|
|
106
|
+
|
|
107
|
+
- `ready`, `connected`, `disconnected`, `connection_failed`, `sdk_error`, `reconnect_scheduled`
|
|
108
|
+
- `peer_connected`, `peer_disconnected`, `data_channel_open`, `data_channel_close`
|
|
109
|
+
- `data_received`, `send_error`, `send_rejected`, `heartbeat_sent`
|
|
110
|
+
|
|
111
|
+
Sync/security:
|
|
112
|
+
|
|
113
|
+
- `sync_hello_sent`, `sync_peer_updated`, `sync_peer_rejected`, `protocol_auth_failed`
|
|
114
|
+
|
|
115
|
+
File:
|
|
116
|
+
|
|
117
|
+
- `file_offer_received`, `file_chunk_received`, `file_chunk_rejected`, `file_received`, `file_transfer_complete`, `file_transfer_cancelled`
|
|
118
|
+
|
|
119
|
+
State:
|
|
120
|
+
|
|
121
|
+
- `state_updated`, `state_snapshot_merged`, `state_protocol_unhandled`
|
|
122
|
+
|
|
123
|
+
## Error Shape
|
|
124
|
+
|
|
125
|
+
Tools return `isError: true` with:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"ok": false,
|
|
130
|
+
"error": {
|
|
131
|
+
"type": "validation_error | tool_error",
|
|
132
|
+
"message": "...",
|
|
133
|
+
"tool": "..."
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Client Wiring
|
|
139
|
+
|
|
140
|
+
Automated registration:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm i @vdoninja/mcp @roamhq/wrtc
|
|
144
|
+
npx vdon-mcp-install
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Preset registrations:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx vdon-mcp-install --preset core
|
|
151
|
+
npx vdon-mcp-install --preset file
|
|
152
|
+
npx vdon-mcp-install --preset state
|
|
153
|
+
npx vdon-mcp-install --preset secure-core
|
|
154
|
+
npx vdon-mcp-install --preset secure-full
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Removal:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
npx vdon-mcp-install --uninstall
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Codex-style:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"name": "vdo-ninja-mcp",
|
|
168
|
+
"command": "node",
|
|
169
|
+
"args": ["node_modules/@vdoninja/mcp/scripts/vdo-mcp-server.js"]
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Claude Code-style:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"mcpServers": {
|
|
178
|
+
"vdo-ninja-mcp": {
|
|
179
|
+
"command": "node",
|
|
180
|
+
"args": ["node_modules/@vdoninja/mcp/scripts/vdo-mcp-server.js"]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# VDO.Ninja MCP Quickstart
|
|
2
|
+
|
|
3
|
+
This is the fast path for users and AI agents.
|
|
4
|
+
|
|
5
|
+
## Transport Truth
|
|
6
|
+
|
|
7
|
+
- This bridge uses **WebRTC data channels**.
|
|
8
|
+
- It is **not** a generic TCP/SSH tunnel.
|
|
9
|
+
- TURN improves connectivity on restrictive networks, but it is **not** a guaranteed firewall bypass.
|
|
10
|
+
|
|
11
|
+
## 60-Second Setup
|
|
12
|
+
|
|
13
|
+
Install locally (no clone), including a Node WebRTC implementation:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @vdoninja/mcp @roamhq/wrtc
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Register MCP for Codex/Claude:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx vdon-mcp-install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Start the local MCP server:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx vdon-mcp-server
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Optional least-privilege profile:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
VDON_MCP_TOOL_PROFILE=core npx vdon-mcp-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Repo-local equivalents still work when developing in this repo:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm run mcp:install
|
|
41
|
+
node MCP/scripts/vdo-mcp-server.js
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
AI-first sanity check (recommended first call):
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{ "name": "vdo_capabilities", "arguments": {} }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Workflow A: Bot-to-Bot Message
|
|
51
|
+
|
|
52
|
+
1. Connect peer A:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "name": "vdo_connect", "arguments": { "room": "lab_1", "stream_id": "agent_a" } }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
2. Connect peer B:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{ "name": "vdo_connect", "arguments": { "room": "lab_1", "stream_id": "agent_b", "target_stream_id": "agent_a" } }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. Send:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"name": "vdo_send",
|
|
69
|
+
"arguments": {
|
|
70
|
+
"session_id": "<agent_a_session_id>",
|
|
71
|
+
"data": { "type": "chat.message", "text": "hello from agent_a" }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
4. Receive:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"name": "vdo_receive",
|
|
81
|
+
"arguments": {
|
|
82
|
+
"session_id": "<agent_b_session_id>",
|
|
83
|
+
"max_events": 100,
|
|
84
|
+
"wait_ms": 1000
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Runnable demo script:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx vdon-mcp-demo-message
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
For live network mode instead of fake/local demo mode:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
MCP_DEMO_FAKE=0 MCP_DEMO_FORCE_TURN=1 npx vdon-mcp-demo-message
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Workflow B: File Send/Receive
|
|
102
|
+
|
|
103
|
+
1. Reuse two connected peers from Workflow A.
|
|
104
|
+
|
|
105
|
+
2. Send file payload from agent A:
|
|
106
|
+
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"name": "vdo_file_send",
|
|
110
|
+
"arguments": {
|
|
111
|
+
"session_id": "<agent_a_session_id>",
|
|
112
|
+
"name": "notes.txt",
|
|
113
|
+
"mime": "text/plain",
|
|
114
|
+
"data_base64": "<base64>"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
3. On agent B, watch transfers:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"name": "vdo_file_transfers",
|
|
124
|
+
"arguments": {
|
|
125
|
+
"session_id": "<agent_b_session_id>",
|
|
126
|
+
"direction": "incoming"
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
4. Read completed file:
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"name": "vdo_file_receive",
|
|
136
|
+
"arguments": {
|
|
137
|
+
"session_id": "<agent_b_session_id>",
|
|
138
|
+
"transfer_id": "<transfer_id>",
|
|
139
|
+
"encoding": "utf8"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Runnable demo script:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npx vdon-mcp-demo-file
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For live network mode:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
MCP_DEMO_FAKE=0 MCP_DEMO_FORCE_TURN=1 npx vdon-mcp-demo-file
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Security Baseline
|
|
157
|
+
|
|
158
|
+
Use secure mode when needed:
|
|
159
|
+
|
|
160
|
+
- `join_token` + `join_token_secret`
|
|
161
|
+
- `enforce_join_token: true`
|
|
162
|
+
- `allow_peer_stream_ids: [...]`
|
|
163
|
+
- `require_session_mac: true`
|
|
164
|
+
|
|
165
|
+
For secure preset installs, set `VDON_MCP_JOIN_TOKEN_SECRET` first.
|
|
166
|
+
|
|
167
|
+
## Minimal Test Bar
|
|
168
|
+
|
|
169
|
+
Default MCP test run (fast, product-focused):
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npm run test:mcp
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
This runs:
|
|
176
|
+
|
|
177
|
+
- conformance
|
|
178
|
+
- server smoke
|
|
179
|
+
- sync security smoke
|
|
180
|
+
|
|
181
|
+
Full engineering suite (advanced):
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npm run test:mcp:all
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Compatibility Notes
|
|
188
|
+
|
|
189
|
+
- Codex and Claude Code both work via command-based local MCP registration.
|
|
190
|
+
- Registry metadata is in `MCP/server.json`.
|
|
191
|
+
- Tool contracts are in `MCP/references/mcp-tool-contract.md`.
|
|
192
|
+
- `@vdoninja/mcp` depends on `@vdoninja/sdk`, so SDK is installed transitively.
|
|
193
|
+
|
|
194
|
+
## Optional Advanced Diagnostics
|
|
195
|
+
|
|
196
|
+
For soak/matrix/preset-matrix/sweep tuning and all reliability knobs, use:
|
|
197
|
+
|
|
198
|
+
- `MCP/references/advanced-diagnostics.md`
|