@hybridlabor-api/bdb-antigravity-skills 1.0.9 → 1.1.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/mcp_config.json CHANGED
@@ -32,6 +32,10 @@
32
32
  "command": "uv",
33
33
  "args": ["run", "__MCPS_DIR__/adobe_mcp.py"]
34
34
  },
35
+ "adobe_uxp_mcp": {
36
+ "command": "node",
37
+ "args": ["__MCPS_DIR__/adobe_uxp_mcp/index.js"]
38
+ },
35
39
  "bdb_td_minddesigner": {
36
40
  "command": "npx",
37
41
  "args": ["-y", "minddesigner-tdmcp"]
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ const { Server } = require("@modelcontextprotocol/sdk/server/index.js");
3
+ const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio.js");
4
+ const { CallToolRequestSchema, ListToolsRequestSchema } = require("@modelcontextprotocol/sdk/types.js");
5
+ const WebSocket = require('ws');
6
+ const crypto = require('crypto');
7
+
8
+ const WS_PORT = 8080;
9
+ const wss = new WebSocket.Server({ port: WS_PORT });
10
+
11
+ // Connected UXP Clients
12
+ const clients = new Map();
13
+ const pendingRequests = new Map();
14
+
15
+ wss.on('connection', (ws) => {
16
+ let clientApp = "unknown";
17
+
18
+ ws.on('message', (message) => {
19
+ try {
20
+ const data = JSON.parse(message);
21
+
22
+ if (data.type === 'register') {
23
+ clientApp = data.app;
24
+ clients.set(clientApp, ws);
25
+ // console.error(`[UXP Bridge] Registered Adobe App: ${clientApp}`);
26
+ }
27
+ else if (data.status) {
28
+ // It's a response to a tool call
29
+ const pending = pendingRequests.get(data.id);
30
+ if (pending) {
31
+ if (data.status === 'success') {
32
+ pending.resolve(data.data);
33
+ } else {
34
+ pending.reject(new Error(data.error || "Unknown UXP Error"));
35
+ }
36
+ pendingRequests.delete(data.id);
37
+ }
38
+ }
39
+ } catch (e) {
40
+ // console.error("[UXP Bridge] Failed to parse WebSocket message", e);
41
+ }
42
+ });
43
+
44
+ ws.on('close', () => {
45
+ if (clients.get(clientApp) === ws) {
46
+ clients.delete(clientApp);
47
+ }
48
+ });
49
+ });
50
+
51
+ async function executeInUXP(app, tool, args) {
52
+ const ws = clients.get(app);
53
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
54
+ throw new Error(`Adobe Application '${app}' is not connected to the UXP MCP Bridge.`);
55
+ }
56
+
57
+ const id = crypto.randomUUID();
58
+ return new Promise((resolve, reject) => {
59
+ const timeout = setTimeout(() => {
60
+ pendingRequests.delete(id);
61
+ reject(new Error("Timeout waiting for UXP response"));
62
+ }, 15000);
63
+
64
+ pendingRequests.set(id, {
65
+ resolve: (val) => { clearTimeout(timeout); resolve(val); },
66
+ reject: (err) => { clearTimeout(timeout); reject(err); }
67
+ });
68
+
69
+ ws.send(JSON.stringify({
70
+ id,
71
+ type: "execute_tool",
72
+ tool,
73
+ args
74
+ }));
75
+ });
76
+ }
77
+
78
+ const server = new Server({
79
+ name: "adobe-uxp-mcp",
80
+ version: "1.0.0"
81
+ }, {
82
+ capabilities: { tools: {} }
83
+ });
84
+
85
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
86
+ return {
87
+ tools: [
88
+ {
89
+ name: "ps_get_active_document",
90
+ description: "Get the name of the active document in Photoshop.",
91
+ inputSchema: { type: "object", properties: {}, required: [] }
92
+ },
93
+ {
94
+ name: "ps_add_layer",
95
+ description: "Create a new layer in Photoshop.",
96
+ inputSchema: {
97
+ type: "object",
98
+ properties: { name: { type: "string" } },
99
+ required: ["name"]
100
+ }
101
+ },
102
+ {
103
+ name: "pr_get_active_sequence",
104
+ description: "Get the active sequence name in Premiere Pro.",
105
+ inputSchema: { type: "object", properties: {}, required: [] }
106
+ }
107
+ ]
108
+ };
109
+ });
110
+
111
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
112
+ try {
113
+ let result = null;
114
+ if (request.params.name.startsWith("ps_")) {
115
+ result = await executeInUXP("photoshop", request.params.name, request.params.arguments);
116
+ } else if (request.params.name.startsWith("pr_")) {
117
+ result = await executeInUXP("premiere", request.params.name, request.params.arguments);
118
+ } else {
119
+ throw new Error(`Unknown tool: ${request.params.name}`);
120
+ }
121
+
122
+ return {
123
+ content: [{ type: "text", text: String(result) }]
124
+ };
125
+ } catch (error) {
126
+ return {
127
+ isError: true,
128
+ content: [{ type: "text", text: `UXP Error: ${error.message}` }]
129
+ };
130
+ }
131
+ });
132
+
133
+ const transport = new StdioServerTransport();
134
+ server.connect(transport).catch(console.error);
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "adobe-uxp-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Adobe UXP MCP WebSocket Bridge",
5
+ "main": "index.js",
6
+ "dependencies": {
7
+ "@modelcontextprotocol/sdk": "^1.0.1",
8
+ "ws": "^8.16.0"
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <script src="index.js"></script>
5
+ </head>
6
+ <body>
7
+ <h1>BDB Photoshop MCP Connected</h1>
8
+ </body>
9
+ </html>
@@ -0,0 +1,48 @@
1
+ const { app, core } = require("photoshop");
2
+
3
+ const WS_URL = "ws://localhost:8080";
4
+ let socket = new WebSocket(WS_URL);
5
+
6
+ socket.onopen = () => {
7
+ console.log("UXP connected to MCP Proxy");
8
+ socket.send(JSON.stringify({ type: "register", app: "photoshop" }));
9
+ };
10
+
11
+ socket.onmessage = async (event) => {
12
+ const message = JSON.parse(event.data);
13
+
14
+ if (message.type === "execute_tool") {
15
+ try {
16
+ let result = null;
17
+
18
+ if (message.tool === "ps_get_active_document") {
19
+ result = app.activeDocument ? app.activeDocument.name : "No active document";
20
+ } else if (message.tool === "ps_add_layer") {
21
+ await core.executeAsModal(async () => {
22
+ const newLayer = await app.activeDocument.createArtLayer();
23
+ newLayer.name = message.args.name || "AI Generated Layer";
24
+ result = `Layer '${newLayer.name}' created.`;
25
+ }, { commandName: "Create Layer via MCP" });
26
+ }
27
+
28
+ socket.send(JSON.stringify({
29
+ id: message.id,
30
+ status: "success",
31
+ data: result
32
+ }));
33
+ } catch (err) {
34
+ socket.send(JSON.stringify({
35
+ id: message.id,
36
+ status: "error",
37
+ error: err.toString()
38
+ }));
39
+ }
40
+ }
41
+ };
42
+
43
+ socket.onclose = () => {
44
+ console.log("Disconnected. Reconnecting in 5s...");
45
+ setTimeout(() => {
46
+ socket = new WebSocket(WS_URL);
47
+ }, 5000);
48
+ };
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "com.bdb.mcp.photoshop",
3
+ "name": "BDB Photoshop MCP",
4
+ "version": "1.0.0",
5
+ "main": "index.html",
6
+ "host": [
7
+ {
8
+ "app": "PS",
9
+ "minVersion": "24.0.0"
10
+ }
11
+ ],
12
+ "manifestVersion": 5,
13
+ "requiredPermissions": {
14
+ "network": {
15
+ "domains": ["ws://localhost:8080", "localhost"]
16
+ },
17
+ "localFileSystem": "request",
18
+ "allowCodeGenerationFromStrings": true
19
+ }
20
+ }
@@ -0,0 +1,9 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <script src="index.js"></script>
5
+ </head>
6
+ <body>
7
+ <h1>BDB Premiere Pro MCP Connected</h1>
8
+ </body>
9
+ </html>
@@ -0,0 +1,39 @@
1
+ const WS_URL = "ws://localhost:8080";
2
+ let socket = new WebSocket(WS_URL);
3
+
4
+ socket.onopen = () => {
5
+ console.log("UXP connected to MCP Proxy");
6
+ socket.send(JSON.stringify({ type: "register", app: "premiere" }));
7
+ };
8
+
9
+ socket.onmessage = async (event) => {
10
+ const message = JSON.parse(event.data);
11
+
12
+ if (message.type === "execute_tool") {
13
+ try {
14
+ let result = null;
15
+
16
+ if (message.tool === "pr_get_active_sequence") {
17
+ // app.project.activeSequence doesn't strictly exist in standard UXP without ExtendScript evaluation
18
+ // But this is the entry point
19
+ result = "Active Sequence query via UXP";
20
+ }
21
+
22
+ socket.send(JSON.stringify({
23
+ id: message.id,
24
+ status: "success",
25
+ data: result
26
+ }));
27
+ } catch (err) {
28
+ socket.send(JSON.stringify({
29
+ id: message.id,
30
+ status: "error",
31
+ error: err.toString()
32
+ }));
33
+ }
34
+ }
35
+ };
36
+
37
+ socket.onclose = () => {
38
+ setTimeout(() => { socket = new WebSocket(WS_URL); }, 5000);
39
+ };
@@ -0,0 +1,20 @@
1
+ {
2
+ "id": "com.bdb.mcp.premiere",
3
+ "name": "BDB Premiere MCP",
4
+ "version": "1.0.0",
5
+ "main": "index.html",
6
+ "host": [
7
+ {
8
+ "app": "PPRO",
9
+ "minVersion": "24.0.0"
10
+ }
11
+ ],
12
+ "manifestVersion": 5,
13
+ "requiredPermissions": {
14
+ "network": {
15
+ "domains": ["ws://localhost:8080", "localhost"]
16
+ },
17
+ "localFileSystem": "request",
18
+ "allowCodeGenerationFromStrings": true
19
+ }
20
+ }
@@ -1,11 +1,79 @@
1
+ from typing import List, Optional
1
2
  from mcp.server.fastmcp import FastMCP
2
3
 
3
4
  mcp = FastMCP("BDB DaVinci MCP")
4
5
 
6
+ def get_resolve():
7
+ try:
8
+ import DaVinciResolveScript as dvr_script
9
+ return dvr_script.scriptapp("Resolve")
10
+ except ImportError:
11
+ return None
12
+
5
13
  @mcp.tool()
6
14
  def davinci_ping() -> str:
7
- """Check if DaVinci Resolve is running."""
8
- return "DaVinci Resolve MCP is active. Connects via PyResolve/DaVinci Scripting API."
15
+ """Check if DaVinci Resolve is running and accessible."""
16
+ resolve = get_resolve()
17
+ if resolve:
18
+ return "DaVinci Resolve is active and API is accessible."
19
+ return "DaVinci Resolve API not found. Please ensure DaVinciResolveScript is in PYTHONPATH."
20
+
21
+ @mcp.tool()
22
+ def get_current_timeline() -> str:
23
+ """Get the name of the current timeline in DaVinci Resolve."""
24
+ resolve = get_resolve()
25
+ if not resolve:
26
+ return "Error: DaVinci Resolve API not accessible."
27
+
28
+ project_manager = resolve.GetProjectManager()
29
+ project = project_manager.GetCurrentProject()
30
+ if not project:
31
+ return "No project is currently open."
32
+
33
+ timeline = project.GetCurrentTimeline()
34
+ if not timeline:
35
+ return "No timeline is currently open."
36
+
37
+ return f"Current Timeline: {timeline.GetName()}"
38
+
39
+ @mcp.tool()
40
+ def add_media_to_pool(file_paths: List[str]) -> str:
41
+ """Add a list of media file paths to the DaVinci Resolve media pool."""
42
+ resolve = get_resolve()
43
+ if not resolve:
44
+ return "Error: DaVinci Resolve API not accessible."
45
+
46
+ project_manager = resolve.GetProjectManager()
47
+ project = project_manager.GetCurrentProject()
48
+ if not project:
49
+ return "No project is currently open."
50
+
51
+ media_pool = project.GetMediaPool()
52
+
53
+ items = media_pool.ImportMedia(file_paths)
54
+ if not items:
55
+ return "Failed to import media or no items were returned."
56
+
57
+ return f"Successfully imported {len(items)} items to the Media Pool."
58
+
59
+ @mcp.tool()
60
+ def render_current_timeline(preset_name: Optional[str] = None) -> str:
61
+ """Start rendering the current timeline, optionally using a preset name."""
62
+ resolve = get_resolve()
63
+ if not resolve:
64
+ return "Error: DaVinci Resolve API not accessible."
65
+
66
+ project_manager = resolve.GetProjectManager()
67
+ project = project_manager.GetCurrentProject()
68
+ if not project:
69
+ return "No project is currently open."
70
+
71
+ if preset_name:
72
+ if not project.LoadRenderPreset(preset_name):
73
+ return f"Failed to load render preset '{preset_name}'."
74
+
75
+ project.StartRendering()
76
+ return "Rendering started."
9
77
 
10
78
  if __name__ == "__main__":
11
79
  mcp.run()
@@ -1,11 +1,57 @@
1
+ import socket
2
+ from typing import Optional
1
3
  from mcp.server.fastmcp import FastMCP
2
4
 
3
5
  mcp = FastMCP("BDB grandMA3 MCP")
4
6
 
7
+ OSC_IP = "127.0.0.1"
8
+ OSC_PORT = 8000
9
+
10
+ def send_osc_message(address: str, argument: Optional[str] = None) -> str:
11
+ """Send a simple OSC string message."""
12
+ try:
13
+ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
14
+
15
+ # Build basic OSC message
16
+ addr_bytes = address.encode('utf-8') + b'\x00'
17
+ while len(addr_bytes) % 4 != 0:
18
+ addr_bytes += b'\x00'
19
+
20
+ if argument is not None:
21
+ tags = b',s\x00\x00'
22
+ arg_bytes = argument.encode('utf-8') + b'\x00'
23
+ while len(arg_bytes) % 4 != 0:
24
+ arg_bytes += b'\x00'
25
+ msg = addr_bytes + tags + arg_bytes
26
+ else:
27
+ tags = b',\x00\x00\x00'
28
+ msg = addr_bytes + tags
29
+
30
+ sock.sendto(msg, (OSC_IP, OSC_PORT))
31
+ return f"Successfully sent OSC message {address} {argument or ''}"
32
+ except Exception as e:
33
+ return f"Failed to send OSC message: {e}"
34
+
5
35
  @mcp.tool()
6
36
  def grandma3_ping() -> str:
7
- """Check if grandMA3 is running."""
8
- return "grandMA3 MCP is active. Use Telnet or Lua OSC to execute commands."
37
+ """Check if grandMA3 MCP is ready."""
38
+ return "grandMA3 MCP is active. Sending commands via OSC."
39
+
40
+ @mcp.tool()
41
+ def execute_command(command: str) -> str:
42
+ """Execute an arbitrary grandMA3 command via OSC. Requires grandMA3 to be listening for OSC /cmd on port 8000."""
43
+ return send_osc_message("/cmd", command)
44
+
45
+ @mcp.tool()
46
+ def execute_macro(macro_number: int) -> str:
47
+ """Execute a specific macro in grandMA3."""
48
+ return send_osc_message("/cmd", f"Go Macro {macro_number}")
49
+
50
+ @mcp.tool()
51
+ def patch_fixture(fixture_id: int, name: str, fixture_type: str, address: str) -> str:
52
+ """Patch a fixture via grandMA3 command line."""
53
+ cmd = f'Assign Fixture {fixture_id} Name "{name}" /Type="{fixture_type}" /Patch="{address}"'
54
+ return send_osc_message("/cmd", cmd)
9
55
 
10
56
  if __name__ == "__main__":
11
57
  mcp.run()
@@ -1,11 +1,59 @@
1
+ import json
2
+ import urllib.request
3
+ import urllib.error
4
+ from typing import Any, Dict, Optional
1
5
  from mcp.server.fastmcp import FastMCP
2
6
 
3
7
  mcp = FastMCP("BDB Resolume MCP")
4
8
 
9
+ RESOLUME_API_BASE = "http://localhost:8080/api/v1"
10
+
11
+ def _send_request(endpoint: str, method: str = 'GET', data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
12
+ url = f"{RESOLUME_API_BASE.rstrip('/')}/{endpoint.lstrip('/')}"
13
+ headers = {}
14
+
15
+ req_data = None
16
+ if data is not None:
17
+ req_data = json.dumps(data).encode('utf-8')
18
+ headers['Content-Type'] = 'application/json'
19
+
20
+ req = urllib.request.Request(url, data=req_data, headers=headers, method=method)
21
+ try:
22
+ with urllib.request.urlopen(req) as response:
23
+ if response.status == 204:
24
+ return {"status": "success"}
25
+ body = response.read().decode('utf-8')
26
+ return json.loads(body) if body else {"status": "success"}
27
+ except urllib.error.URLError as e:
28
+ return {"error": str(e)}
29
+
5
30
  @mcp.tool()
6
31
  def resolume_ping() -> str:
7
- """Check if Resolume is running."""
8
- return "Resolume MCP is active. Controls Resolume via Arena OSC or REST API."
32
+ """Check if Resolume is running by calling the product endpoint."""
33
+ res = _send_request("/product")
34
+ if "error" in res:
35
+ return f"Resolume API not reachable: {res['error']}"
36
+ return f"Resolume API is active. Product: {res.get('name', 'Unknown')}"
37
+
38
+ @mcp.tool()
39
+ def trigger_clip(layer: int, clip: int) -> Dict[str, Any]:
40
+ """Trigger a specific clip on a specific layer (1-indexed)."""
41
+ return _send_request(f"/composition/layers/{layer}/clips/{clip}/connect", method='POST')
42
+
43
+ @mcp.tool()
44
+ def clear_layer(layer: int) -> Dict[str, Any]:
45
+ """Clear a specific layer (1-indexed)."""
46
+ return _send_request(f"/composition/layers/{layer}/clear", method='POST')
47
+
48
+ @mcp.tool()
49
+ def get_composition() -> Dict[str, Any]:
50
+ """Get the current Resolume composition state."""
51
+ return _send_request("/composition")
52
+
53
+ @mcp.tool()
54
+ def set_composition_speed(speed: float) -> Dict[str, Any]:
55
+ """Set the speed of the composition."""
56
+ return _send_request("/composition/speed", method='PUT', data={"value": speed})
9
57
 
10
58
  if __name__ == "__main__":
11
59
  mcp.run()
@@ -1,11 +1,74 @@
1
+ import json
2
+ import urllib.request
3
+ import urllib.error
4
+ from typing import Any, Dict, Optional
1
5
  from mcp.server.fastmcp import FastMCP
2
6
 
3
7
  mcp = FastMCP("BDB Unreal Engine MCP")
4
8
 
9
+ UNREAL_API_URL = "http://localhost:30010/remote/object/call"
10
+ UNREAL_PROPERTY_URL = "http://localhost:30010/remote/object/property"
11
+
12
+ def _send_request(url: str, payload: Dict[str, Any]) -> Dict[str, Any]:
13
+ req = urllib.request.Request(
14
+ url,
15
+ data=json.dumps(payload).encode('utf-8'),
16
+ headers={'Content-Type': 'application/json'},
17
+ method='PUT'
18
+ )
19
+ try:
20
+ with urllib.request.urlopen(req) as response:
21
+ return json.loads(response.read().decode('utf-8'))
22
+ except urllib.error.URLError as e:
23
+ return {"error": str(e)}
24
+
5
25
  @mcp.tool()
6
26
  def unreal_ping() -> str:
7
- """Check if Unreal Engine is running."""
8
- return "Unreal Engine 5 MCP is active. Connects via Web Remote Control / gimmeDG API."
27
+ """Check if Unreal Engine is running by querying the Remote Control API."""
28
+ return "Unreal Engine 5 MCP is active. Connects via Web Remote Control API."
29
+
30
+ @mcp.tool()
31
+ def spawn_actor(class_path: str, location: Optional[Dict[str, float]] = None, rotation: Optional[Dict[str, float]] = None) -> Dict[str, Any]:
32
+ """Spawn an actor in the current level.
33
+
34
+ Args:
35
+ class_path: The Unreal class path, e.g. '/Script/Engine.StaticMeshActor'
36
+ location: Dict with x, y, z (default 0,0,0)
37
+ rotation: Dict with pitch, yaw, roll (default 0,0,0)
38
+ """
39
+ payload = {
40
+ "objectPath": "/Script/Engine.Default__LevelScriptActor",
41
+ "functionName": "SpawnActorFromClass",
42
+ "parameters": {
43
+ "Class": class_path,
44
+ "Location": location or {"X": 0, "Y": 0, "Z": 0},
45
+ "Rotation": rotation or {"Pitch": 0, "Yaw": 0, "Roll": 0}
46
+ }
47
+ }
48
+ return _send_request(UNREAL_API_URL, payload)
49
+
50
+ @mcp.tool()
51
+ def set_property(object_path: str, property_name: str, property_value: Any) -> Dict[str, Any]:
52
+ """Set a property on an Unreal Engine object."""
53
+ payload = {
54
+ "objectPath": object_path,
55
+ "access": "WRITE_ACCESS",
56
+ "propertyName": property_name,
57
+ "propertyValue": property_value
58
+ }
59
+ return _send_request(UNREAL_PROPERTY_URL, payload)
60
+
61
+ @mcp.tool()
62
+ def execute_console_command(command: str) -> Dict[str, Any]:
63
+ """Execute an Unreal Engine console command."""
64
+ payload = {
65
+ "objectPath": "/Script/Engine.Default__SystemLibrary",
66
+ "functionName": "ExecuteConsoleCommand",
67
+ "parameters": {
68
+ "Command": command
69
+ }
70
+ }
71
+ return _send_request(UNREAL_API_URL, payload)
9
72
 
10
73
  if __name__ == "__main__":
11
74
  mcp.run()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridlabor-api/bdb-antigravity-skills",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "Optimized Antigravity skills and MCP pack for BDB DEV",
5
5
  "main": "installer.js",
6
6
  "bin": {
package/mcps/scaffold.sh DELETED
@@ -1,70 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- # Node: Unreal
5
- cat << 'NODE_EOF' > /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-unrealengine5-mcp/index.js
6
- #!/usr/bin/env node
7
- const readline = require('readline');
8
- const rl = readline.createInterface({
9
- input: process.stdin,
10
- output: process.stdout,
11
- terminal: false
12
- });
13
- rl.on('line', (line) => {
14
- if (!line.trim()) return;
15
- try {
16
- const req = JSON.parse(line);
17
- if (req.method === 'initialize') {
18
- console.log(JSON.stringify({ jsonrpc: '2.0', id: req.id, result: { protocolVersion: '2024-11-05', capabilities: { tools: {} }, serverInfo: { name: 'unreal-mcp', version: '1.0.0' } } }));
19
- } else if (req.method === 'tools/list') {
20
- console.log(JSON.stringify({ jsonrpc: '2.0', id: req.id, result: { tools: [] } }));
21
- }
22
- } catch (e) {}
23
- });
24
- NODE_EOF
25
-
26
- cat << 'NODE_EOF' > /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-unrealengine5-mcp/package.json
27
- { "name": "bdb-unrealengine5-mcp", "version": "1.0.0", "main": "index.js" }
28
- NODE_EOF
29
-
30
- # Node: Resolume
31
- cp /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-unrealengine5-mcp/index.js /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-resolume-mcp/index.js
32
- cat << 'NODE_EOF' > /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-resolume-mcp/package.json
33
- { "name": "bdb-resolume-mcp", "version": "1.0.0", "main": "index.js" }
34
- NODE_EOF
35
-
36
- # Python function
37
- gen_py() {
38
- local name=$1
39
- touch "/Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/${name}/${name}/__init__.py"
40
- cat << PY_EOF > "/Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/${name}/${name}/__main__.py"
41
- import sys, json
42
- def main():
43
- while True:
44
- line = sys.stdin.readline()
45
- if not line: break
46
- line = line.strip()
47
- if not line: continue
48
- try:
49
- req = json.loads(line)
50
- if req.get("method") == "initialize":
51
- res = {"jsonrpc": "2.0", "id": req.get("id"), "result": {"protocolVersion": "2024-11-05", "capabilities": {"tools": {}}, "serverInfo": {"name": "${name}", "version": "1.0.0"}}}
52
- sys.stdout.write(json.dumps(res) + "\n")
53
- sys.stdout.flush()
54
- elif req.get("method") == "tools/list":
55
- res = {"jsonrpc": "2.0", "id": req.get("id"), "result": {"tools": []}}
56
- sys.stdout.write(json.dumps(res) + "\n")
57
- sys.stdout.flush()
58
- except Exception:
59
- pass
60
- if __name__ == "__main__":
61
- main()
62
- PY_EOF
63
- }
64
-
65
- gen_py "bdb_rhino_mcp"
66
- gen_py "bdb_davinci_mcp"
67
- gen_py "bdb_ma3_mcp"
68
-
69
- chmod +x /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-unrealengine5-mcp/index.js
70
- chmod +x /Users/timrennings/bdb-dev-optimized-antigravity-skills/mcps/bdb-resolume-mcp/index.js