{"_id":"@alisaitteke/ttt","_rev":"9-78c452bc14b482d4347767b9d7ae1744","name":"@alisaitteke/ttt","dist-tags":{"latest":"0.2.17"},"versions":{"0.2.0":{"name":"@alisaitteke/ttt","version":"0.2.0","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.0","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ui":"dist/ui/cli.js","ttt":"dist/index.js","ttt-ui":"dist/ui/cli.js"},"dist":{"shasum":"1575f8bd7ec2a78715f917f155faa14b92f7749c","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.0.tgz","fileCount":392,"integrity":"sha512-51IiRK2KLcQIcYfQ5YsjIazRLvw8a2MRYuHe7KCS5T7fr66fISBdx2PabNOBe9mA6y4P/V2ZkxZdUOFazHCbPg==","signatures":[{"sig":"MEQCIF8L+N9GRPk7hDsMp1D+mfxnWSinRDa/PoCpPDtp7UDWAiBxwsMuENloZsp3BMmCGPHXalAKPY3dRHzPBdBvvTzFQw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2262482},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"e27a0b3c3c332fc5b0feeb6157e207a1c52b8742","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","vue-renderer-markdown":"^0.0.62","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.0_1778103691132_0.9227000282419917","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@alisaitteke/ttt","version":"0.2.1","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.1","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ui":"dist/ui/cli.js","ttt":"dist/index.js","ttt-ui":"dist/ui/cli.js"},"dist":{"shasum":"a918e0f5b400496c8ee1a9b0f9ef92cf3a13a8ee","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.1.tgz","fileCount":392,"integrity":"sha512-W4RudBftY1ja+5ODXpRwBWkVw2ujByF/atbqxTaGicAv95f68TL3Yegh0btUzBCXgDR33dIPmqARqRSXGk4COw==","signatures":[{"sig":"MEYCIQCbLYp45OT+ucaP+gxZsLTDfsBSeDyj1CgL6gfQGy6YcQIhAL9fDefvgc3OMsbfLy6ZDmukq+hnrAlEJniTkOkmVx+p","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2262523},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"bd5c714c803c64904436c21ae48277772af0c3e2","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","vue-renderer-markdown":"^0.0.62","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.1_1778103982834_0.4964094093333078","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@alisaitteke/ttt","version":"0.2.2","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.2","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ui":"dist/ui/cli.js","ttt":"dist/index.js","ttt-ui":"dist/ui/cli.js"},"dist":{"shasum":"97b9ce0b925e25431df60dc2f2f74d3ab3cc4de4","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.2.tgz","fileCount":392,"integrity":"sha512-6n1Ss9Lzx4qZeehmNdPnis/TiTw1RuXRRrPn7inaTlhhpiMm5qHpAumQ9qMO/E7t/YlRJeERW2fFLHC3EC3aAA==","signatures":[{"sig":"MEUCIQCwiXmb4pK9bRm5auqjs0KOGWVMUIF4u9LyTqwf/3WNwAIgHGqi1XQslsblWaUSW37lf72w9s4X/77a5NuegwXcR8E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2262523},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"085572b149c90a50f0e42a570df4982f2e977d21","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","vue-renderer-markdown":"^0.0.62","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.2_1778104128783_0.13345627581647412","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@alisaitteke/ttt","version":"0.2.4","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.4","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ttt":"dist/index.js"},"dist":{"shasum":"54205c73ae1dd99a9aa90f431f9f6201e4c709f7","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.4.tgz","fileCount":388,"integrity":"sha512-1b1WdqjHQLtGdoFjyPDS8bcJ8JgS33PENpaYq5R7PHVQCRxwQuvD/QniWGbA6hc/KnTga3bTv1PCzI5NwzkxfA==","signatures":[{"sig":"MEUCIQCYEwDxvCFyDXGqrzbJB39aO8AfBxe6+hOWiSTeQbr1yAIgXyLkdEAoafZ+f2efWm2t4GXHg2iNltAvwz6bdeRcKIQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1621499},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"0f90277127f5aae838cd645830fa35853cf64bbc","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"overrides":{"uuid":"^11.0.0"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.4_1778105799092_0.08695246016012592","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@alisaitteke/ttt","version":"0.2.5","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.5","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ttt":"dist/index.js"},"dist":{"shasum":"21c6cb399fecafb57606d18c505b02494544d376","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.5.tgz","fileCount":388,"integrity":"sha512-eya50lVry/Kgp6y241WdLLC5jSZsoJQ5Bk/xxhxfFzYXn5oqqhV9kAaxRwDfWcGiIHHv8+5CZshf5IY1NGECOw==","signatures":[{"sig":"MEQCID7S2+Xc+HxogPxY+XH3Ko8SEQcI3GZroNi5RDZGvvGnAiBb0vDaaydCoJtNzkWNjFpawPk9WGBPGsfI1+s/XVIF2Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1620970},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"9bd0aea6c2c4ac35f6f5716e3d3cafbe8d25b613","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"overrides":{"uuid":"^11.0.0"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.5_1778107920805_0.30452787337956577","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"@alisaitteke/ttt","version":"0.2.6","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.6","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ttt":"dist/index.js"},"dist":{"shasum":"475b31277b75338e611b33878879cc6691d54d23","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.6.tgz","fileCount":396,"integrity":"sha512-7wQyRC/nFaaAfVLt91nh1ZU0ws8le95pQg8u1EwXB0nlbO59SPN5nLU00jT/+a+Es/shzlGsklYrEWVbu05Zzw==","signatures":[{"sig":"MEYCIQD2l49Pr/O32WFgscJRtafj6CTSkzgKerG7U81KbjSrrAIhANG6+pedgRuMiwhBxMIneBuhEt93kSUkFz3ElEZU/I3n","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1626377},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"a6fe9cc01291cb217bb12189e565afad914e4146","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"overrides":{"uuid":"^11.0.0"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.6_1778109059029_0.01591586702074288","host":"s3://npm-registry-packages-npm-production"}},"0.2.7":{"name":"@alisaitteke/ttt","version":"0.2.7","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.7","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ttt":"dist/index.js"},"dist":{"shasum":"239904a9907aaa041aefcf8ca3fe14b0f948ac77","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.7.tgz","fileCount":396,"integrity":"sha512-uFg6+nZrvxBUPIJ1+eBzHkKE/BSR2456acdF/ZMfGmGDoEgb/BxGowYMmf8g68wr54HTLE1jicTaAWHs632Vqw==","signatures":[{"sig":"MEUCIQChgccYJCsbq8iCFKX1qOwogvla+wbCq06lAyRfbQ4/GQIgdqJYIE1JuyVw4Mh1Tzrpg6q3UWueOkH8jgEON3/oUHI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1626889},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"a61f61697271bf035fa1e1bf0c5d440c690d9d1b","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","dev:ui:web":"npm --prefix web run dev","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","prepublishOnly":"npm run build","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"overrides":{"uuid":"^11.0.0"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","keytar":"^7.9.0","qrcode":"^1.5.4","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.7_1778109409864_0.1178704061297966","host":"s3://npm-registry-packages-npm-production"}},"0.2.16":{"name":"@alisaitteke/ttt","version":"0.2.16","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","_id":"@alisaitteke/ttt@0.2.16","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"bin":{"ttt":"dist/index.js"},"dist":{"shasum":"7c6908ed3171127e85d5207df65c4e876d02ac1f","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.16.tgz","fileCount":392,"integrity":"sha512-agWDHBPUvMsd4Npo+n1yO6thE1Vmw8QUkmg9kb3DubZ3CW0eVfqnVmnkvMqTr7nEoF+54jDc8hAxYoQqkZbh0g==","signatures":[{"sig":"MEUCIBM5yp/LiAdIYnDaxqLSQkgRpCF1RPKXOfoCsQiA+YXdAiEAzfJ2OGb6vDt55CiExnswPodFFg1mN5g+QjZfewkGDcI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1629015},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"0e6a484acc0ebf79dc935527b2a0903061188190","mcpName":"io.github.alisaitteke/ttt","scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","lint":"eslint src --ext .ts","build":"npm run build:server && npm run build:web","start":"node dist/index.js","tauri":"tauri","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","format":"prettier --write \"src/**/*.ts\"","prepare":"npm run build","start:ui":"node dist/ui/cli.js","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","tauri:dev":"cross-env TAURI=1 tauri dev","dev:ui:web":"npm --prefix web run dev","tauri:build":"tauri build","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","format:check":"prettier --check \"src/**/*.ts\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","release:notes":"node scripts/generate-release-notes.mjs","prepublishOnly":"npm run build","build:server:bundle":"node scripts/build-server-bundle.mjs","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts"},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"overrides":{"uuid":"^11.0.0"},"repository":{"url":"git+https://github.com/alisaitteke/ttt.git","type":"git"},"_npmVersion":"10.9.2","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ai":"^6.0.175","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0","get-port":"^7.1.0","@hapi/boom":"^9.1.3","@ai-sdk/mcp":"^1.0.40","async-mutex":"^0.5.0","@ai-sdk/groq":"^3.0.38","@ai-sdk/google":"^3.0.67","@ai-sdk/openai":"^3.0.61","better-sqlite3":"^12.9.0","@ai-sdk/anthropic":"^3.0.75","@hono/node-server":"^1.13.7","@alisaitteke/docker-mcp":"^0.2.4","@whiskeysockets/baileys":"^6.7.21","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.2","eslint":"^9.18.0","esbuild":"^0.28.0","globals":"^17.6.0","prettier":"^3.4.2","cross-env":"^10.1.0","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","typescript":"^5.7.3","@types/node":"^22.10.5","concurrently":"^9.1.2","@tauri-apps/cli":"^2.11.1","@types/better-sqlite3":"^7.6.13","@typescript-eslint/parser":"^8.20.0","@typescript-eslint/eslint-plugin":"^8.20.0"},"_npmOperationalInternal":{"tmp":"tmp/ttt_0.2.16_1778183694181_0.3758469119844292","host":"s3://npm-registry-packages-npm-production"}},"0.2.17":{"name":"@alisaitteke/ttt","version":"0.2.17","description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","main":"dist/index.js","type":"module","bin":{"ttt":"dist/index.js"},"scripts":{"dev":"tsc-watch --onSuccess \"tsc-alias\"","dev:ui":"concurrently -n server,web -c blue,green \"npm:dev:ui:server\" \"npm:dev:ui:web\"","dev:ui:server":"tsx watch src/ui/cli.ts --port 5174 --no-open","dev:ui:web":"npm --prefix web run dev","build":"npm run build:server && npm run build:web","build:server":"tsc && tsc-alias && chmod +x dist/index.js dist/ui/cli.js","build:server:bundle":"node scripts/build-server-bundle.mjs","build:web":"npm --prefix web ci --no-audit --no-fund && npm --prefix web run build","start":"node dist/index.js","start:ui":"node dist/ui/cli.js","lint":"eslint src --ext .ts","verify:docker-tools":"tsx scripts/verify-docker-tool-parity.ts","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","tauri":"tauri","tauri:dev":"cross-env TAURI=1 tauri dev","tauri:build":"tauri build","release:notes":"node scripts/generate-release-notes.mjs","prepare":"npm run build","prepublishOnly":"npm run build"},"keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"author":{"name":"Ali Sait Teke"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/alisaitteke/ttt.git"},"homepage":"https://github.com/alisaitteke/ttt#readme","bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"engines":{"node":">=18.0.0"},"publishConfig":{"access":"public"},"dependencies":{"@ai-sdk/anthropic":"^3.0.75","@ai-sdk/google":"^3.0.67","@ai-sdk/groq":"^3.0.38","@ai-sdk/mcp":"^1.0.40","@ai-sdk/openai":"^3.0.61","@alisaitteke/docker-mcp":"^0.2.4","@hapi/boom":"^9.1.3","@hono/node-server":"^1.13.7","@modelcontextprotocol/sdk":"^1.0.4","@openrouter/ai-sdk-provider":"^2.9.0","@whiskeysockets/baileys":"^6.7.21","ai":"^6.0.175","async-mutex":"^0.5.0","better-sqlite3":"^12.9.0","get-port":"^7.1.0","hono":"^4.6.14","open":"^10.1.0","pino":"^9.6.0"},"overrides":{"uuid":"^11.0.0"},"mcpName":"io.github.alisaitteke/ttt","devDependencies":{"@tauri-apps/cli":"^2.11.1","@types/better-sqlite3":"^7.6.13","@types/node":"^22.10.5","@typescript-eslint/eslint-plugin":"^8.20.0","@typescript-eslint/parser":"^8.20.0","concurrently":"^9.1.2","cross-env":"^10.1.0","esbuild":"^0.28.0","eslint":"^9.18.0","globals":"^17.6.0","prettier":"^3.4.2","tsc-alias":"^1.8.10","tsc-watch":"^6.2.1","tsx":"^4.19.2","typescript":"^5.7.3"},"_id":"@alisaitteke/ttt@0.2.17","gitHead":"0521466250c3c98a565065d4504015ef7fe7bc05","types":"./dist/index.d.ts","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-I6Oh/fs4u06S3ORLUg0w0NRhEsGuAil4zxAUC+B5SgnvG7QB8GMZy2qSQY2sKFcXTmyiIDxv+9yc8TaCEDR6eQ==","shasum":"a3450bbe9f5ed97aba10267ec2123ac19e11b9b4","tarball":"https://registry.npmjs.org/@alisaitteke/ttt/-/ttt-0.2.17.tgz","fileCount":392,"unpackedSize":1631824,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCGmSmL9UrYGc/IXqPt3R7nEN1gw1XiZnNyUqOyROQAOQIgMHAgdsxWWJ0tCTOe/higE/m9E9jg83u6QeWSq1CqG9U="}]},"_npmUser":{"name":"axee","email":"alisaitt@gmail.com"},"directories":{},"maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ttt_0.2.17_1778187914474_0.39177719705171965"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-06T21:41:30.969Z","modified":"2026-05-07T21:05:14.809Z","0.2.0":"2026-05-06T21:41:31.347Z","0.2.1":"2026-05-06T21:46:23.073Z","0.2.2":"2026-05-06T21:48:48.982Z","0.2.4":"2026-05-06T22:16:39.255Z","0.2.5":"2026-05-06T22:52:00.982Z","0.2.6":"2026-05-06T23:10:59.208Z","0.2.7":"2026-05-06T23:16:50.108Z","0.2.16":"2026-05-07T19:54:54.376Z","0.2.17":"2026-05-07T21:05:14.687Z"},"bugs":{"url":"https://github.com/alisaitteke/ttt/issues"},"author":{"name":"Ali Sait Teke"},"license":"MIT","homepage":"https://github.com/alisaitteke/ttt#readme","keywords":["mcp","model-context-protocol","design-automation","local-automation","orchestrator","ai","photoshop","docker","figma","after-effects","creative-cloud","ttt"],"repository":{"type":"git","url":"git+https://github.com/alisaitteke/ttt.git"},"description":"TTT (The Tortoise Trainer) — provider-driven local MCP orchestrator with optional bundled web UI for Adobe automation, Docker, and more backends (scaffolded integrations: Figma, OpenClaw, Hermes)","maintainers":[{"name":"axee","email":"alisaitt@gmail.com"}],"readme":"# TTT — The Tortoise Trainer\n\n[![npm version](https://img.shields.io/npm/v/@alisaitteke/ttt.svg)](https://www.npmjs.com/package/@alisaitteke/ttt)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Desktop release (Tauri)](https://github.com/alisaitteke/ttt/actions/workflows/release.yml/badge.svg)](https://github.com/alisaitteke/ttt/actions/workflows/release.yml)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)\n[![Platform](https://img.shields.io/badge/Platform-macOS%20%7C%20Windows%20%7C%20Linux-lightgrey.svg)]()\n[![Patreon](https://img.shields.io/badge/Patreon-Support-FF424D?logo=patreon&logoColor=white)](https://www.patreon.com/tttanimals)\n\n[![Standalone UI — click to watch demo](./images/frame_generic_light.png)](https://github.com/alisaitteke/ttt/blob/master/images/demo-ps-gp-wp.mp4)\n\n### Quick start\n\nRun the UI **in the background** (you can close the terminal afterward). After it starts, open the URL from `ui-background.json` in your TTT data directory (`TTT_HOME`, default `~/.ttt`). Details: [Running the UI in the background](#running-the-ui-in-the-background-detached).\n\n```bash\nnpx @alisaitteke/ttt start -D\n```\n\nSame as **`npx @alisaitteke/ttt start --detach`**.\n\nOr run in the **foreground** (random free port; opens your browser):\n\n```bash\nnpx @alisaitteke/ttt start\n```\n\n### Desktop app (without `npx`)\n\nNative installers ship on **[GitHub Releases](https://github.com/alisaitteke/ttt/releases/latest)** alongside npm. Each build is a **[Tauri 2](https://tauri.app/start/)** shell that bundles **Node.js** and the exact same standalone UI/backend as **`ttt start`**. MCP over stdio for Cursor / Claude Desktop remains **`npx @alisaitteke/ttt mcp`**.\n\n| Platform | Typical artifacts |\n| --- | --- |\n| macOS | Universal `.dmg` |\n| Windows | `.msi` / NSIS installers (see release) |\n| Linux | `.deb`, `.rpm` |\n\n**Develop the shell locally (macOS / Rust installed):**\n\n```bash\nnpm install\nnpm run tauri:dev   # Runs `dev:ui` with TAURI=1 and opens the Tauri tray window pointing at Vite port 5173\n```\n\nProduction-style bundle (downloads Node runtimes listed in `TAURI_BUNDLE_TARGETS`):\n\n```bash\nnpm run build\nTAURI_BUNDLE_TARGETS=darwin-arm64,darwin-x64 node scripts/tauri-prepare-bundle.mjs   # omit second target on single-arch staging\nnpm run tauri:build\n```\n\nIterate without re-running `npm ci`:\n\n```bash\nTAURI_PREPARE_SKIP_NPM_CI=1 TAURI_BUNDLE_TARGETS=darwin-arm64 node scripts/tauri-prepare-bundle.mjs\n```\n\n**Release CI:** tagging `v*` runs [`.github/workflows/release.yml`](.github/workflows/release.yml). Configure Secrets for code signing (`TAURI_SIGNING_PRIVATE_KEY` + updater password). Regenerate updater keys anytime with:\n\n```bash\nCI=true npx @tauri-apps/cli signer generate -w .keys/tauri-updater.key -p \"\" --force\n```\n\nCopy the `.pub` file text into `src-tauri/tauri.conf.json → plugins.updater.pubkey` (never commit the `.key`; add it under repository secrets).\n\nTTT (named after the famous Osman Hamdi Bey painting *The Tortoise Trainer*) is a Model Context Protocol (MCP) server that gives AI assistants — Claude, Cursor, and others — natural-language control over **local backends** you enable: Adobe apps for design and motion, Docker for containers and infra, optional **WhatsApp messaging** when you use the bundled web UI, with more integrations following the same pattern.\n\nThe architecture is **provider-driven**: each backend contributes MCP tools from its own tree under `src/providers/`; the server rolls them together in `src/providers/index.ts`.\n\n## Supported tools & backends\n\n| Provider | Status | Tool Prefix | Notes |\n|---|---|---|---|\n| **Photoshop** | ✅ Full | `photoshop_` | 50+ tools covering document/layer/text/filter/adjustment operations |\n| **After Effects** | ✅ Partial | `aftereffects_` | ~18 tools for composition/layer management, animation basics |\n| **Docker** | ✅ Full | `docker_` (+ `dockerhub_*`, `ghcr_*`) | Containers, images, networks, volumes, Compose, exec, system, and registry tooling against a local daemon |\n| **Illustrator** | 🚧 Scaffolded | `illustrator_` | Provider structure in place, tools not yet implemented |\n| **Figma** | 🚧 Scaffolded | `figma_` | Planned: REST API / plugin bridge |\n| **OpenClaw** | 🚧 Scaffolded | `openclaw_` | Planned: REST API integration |\n| **Hermes** | 🚧 Scaffolded | `hermes_` | Planned |\n| **WhatsApp** | ✅ Beta | `whatsapp_` | Messaging via [Baileys](https://github.com/WhiskeySockets/Baileys) in the **standalone UI** only (QR-linked session); see [WhatsApp (Messaging)](#whatsapp-messaging) |\n\n## 🖥️ Standalone UI (no IDE required)\n\nDon't want to wire this into Claude Desktop or Cursor? The same package ships a fully local web UI that lets you chat with an AI model and invoke TTT MCP tools—including Adobe automation and Docker—through the server underneath.\n\n### Supported providers\n\nPick any of the following on first launch — bring your own API key:\n\n| Provider | Models | Get a key |\n|---|---|---|\n| **Anthropic** | Claude Sonnet / Opus / Haiku | [console.anthropic.com](https://console.anthropic.com/settings/keys) |\n| **OpenAI** | GPT-5, GPT-4.1, o-series | [platform.openai.com](https://platform.openai.com/api-keys) |\n| **Google** | Gemini 2.5 Pro / Flash / Flash-Lite | [aistudio.google.com](https://aistudio.google.com/apikey) |\n| **OpenRouter** | 100+ models from any provider | [openrouter.ai](https://openrouter.ai/keys) |\n\n### What happens on first launch\n\n1. Pick a provider and paste your API key.\n2. The key is validated against the provider, then stored alongside chat history and other settings in `~/.ttt/data.db` (SQLite, protected by your OS user account). Keys never leave your machine.\n3. Type natural-language prompts. The UI streams the model's reply, runs tool calls in real time, and renders each tool call as an inspectable card (input + result).\n4. Switch provider, model, or **enabled backends** (Photoshop, After Effects, Docker, WhatsApp, …) anytime from the composer bar — chats, costs and tool history are persisted across sessions.\n\n**Optional:** you can supply API keys via environment variables instead of the UI (handy for automation). Each provider has a `TTT_<PROVIDER>_API_KEY` name, e.g. `TTT_ANTHROPIC_API_KEY`, `TTT_OPENAI_API_KEY`, `TTT_GOOGLE_API_KEY`, `TTT_OPENROUTER_API_KEY`, `TTT_GROQ_API_KEY`. When set, the variable takes precedence over the stored key for that provider.\n\n### WhatsApp (Messaging)\n\nWhatsApp is integrated as an optional **connection adapter** inside the **standalone UI**, not as a classic filesystem/process backend:\n\n1. Run the standalone UI (`npx @alisaitteke/ttt start` or detached mode).\n2. Open **Settings → Messaging**, choose **WhatsApp**, and link your phone with **QR code** (same flow as WhatsApp “Linked devices”).\n3. Enable **WhatsApp** for the chats where you want `whatsapp_*` tools — alongside Photoshop, Docker, etc., if you like.\n\n**Important**\n\n- **Unofficial API.** Linking uses the same multi-device Web mechanism third-party libraries rely on; it is **not** supported by Meta for automation. Use responsibly and comply with [WhatsApp Terms of Service](https://www.whatsapp.com/legal).\n- **Beta.** Behavior may change; sessions may need reconnect after client/library updates.\n- **Session files** live under `${TTT_HOME}/connections/whatsapp/` (default `~/.ttt/connections/whatsapp/`).\n- **Extended read tools** (optional): In the WhatsApp dialog you can opt in to **Allow AI to read chats & contacts**. That exposes extra MCP tools (`whatsapp_list_chats`, `whatsapp_fetch_messages`, `whatsapp_search_contacts`) that read from the local Baileys cache — disable anytime.\n\nWhen you chat **inside this UI**, the server runs MCP tooling with an internal HTTP **bridge** so WhatsApp calls hit the live Baileys socket in the same process.\n\n**Cursor / Claude Desktop (stdio MCP only):** The registry includes `whatsapp_*`, but those handlers need `TTT_CONNECTION_BRIDGE_URL` and `TTT_CONNECTION_BRIDGE_SECRET` pointing at your UI session. That secret is generated **per UI server run** and is injected automatically when the UI spawns MCP — **not** when an IDE launches `npx @alisaitteke/ttt mcp` alone. For WhatsApp, prefer chatting from the **standalone UI** unless you wire bridge credentials yourself in advanced setups.\n\n### Per-chat backend selection\n\nThe UI lets you pick which backends are active for each chat (Photoshop, After Effects, Docker, WhatsApp, …). Combine them—for example Photoshop + Docker—or narrow to one backend. The agent only sees prefixes you enable for that conversation.\n\n### CLI commands\n\n```bash\nttt start [-D] [--detach] [--port 5174] [--host 127.0.0.1] [--no-open]\nttt stop\nttt mcp\n```\n\n| Command | What it does |\n|---|---|\n| `ttt start` | Start the browser UI in the foreground (random free port; opens your browser). |\n| `ttt start -D` / `ttt start --detach` | Start the UI in the background; the parent process exits after spawn. |\n| `ttt stop` | Stop the detached UI recorded in `ui-background.json`. |\n| `ttt mcp` | Run the MCP server over stdio (used by Cursor / Claude Desktop). |\n| `ttt --help` / `ttt --version` | Show help / version. |\n\n### Running the UI in the background (detached)\n\nThe standalone UI is a **long-lived HTTP server** on your machine. If you do not want to keep a terminal window open, run it **detached** so the process keeps serving after the shell exits. This works on **macOS and Windows** (the CLI uses a detached child process and hides the console window on Windows).\n\n**What it does**\n\n- **`ttt start -D` / `ttt start --detach`** — Starts the UI server in the background. The parent process exits immediately after spawning the server.\n- **`ttt stop`** — Sends `SIGTERM` to the detached server recorded in the state file and removes that file when the process exits.\n- **State file** — `${TTT_HOME}/ui-background.json` (default `TTT_HOME` is `~/.ttt`). It contains the listening URL, port, host, PID, and start time once the server is ready.\n\n**Requirements**\n\n- **Port** — Omitted port picks a random free port (same as foreground); pass **`--port`** if you want a stable URL every time.\n- **`ttt stop` uses the same `TTT_HOME`** — If you override data directory with `TTT_HOME`, use the same value when stopping.\n\n**Examples**\n\n```bash\n# Foreground: random free port, browser opens\nnpx @alisaitteke/ttt start\n\n# Background: random port; URL written to ui-background.json when ready\nnpx @alisaitteke/ttt start --detach\n\n# Background on a fixed port; skip auto-opening the browser from the child process\nnpx @alisaitteke/ttt start --detach --no-open --port 5174\n\n# Stop the detached server (default ~/.ttt/ui-background.json)\nnpx @alisaitteke/ttt stop\n```\n\nRead `ui-background.json` for the exact URL. If a daemon is already running, a second detach (`--detach` or `-D`) is rejected until you `ttt stop` or the old process dies (stale state is cleared automatically).\n\n**Not the same as the MCP command**\n\n`npx @alisaitteke/ttt mcp` runs the **MCP server over stdio** for Cursor, Claude Desktop, and the UI’s own agent loop. It is meant to be spawned by those hosts, not left running as a detached terminal service. Background mode applies to **`ttt start`** only.\n\n### Notes\n\n- The agent only sees tools exposed by **TTT** for the prefixes active in that chat—for example `photoshop_*`, `aftereffects_*`, `docker_*` / `dockerhub_*` / `ghcr_*` when Docker is enabled, and `whatsapp_*` when WhatsApp is enabled (requires linked session in Messaging settings). Built-in shell, file, and web tools are disabled.\n- Tech stack: Vue 3 + Tailwind v4 + [shadcn-vue](https://www.shadcn-vue.com/) on the frontend; [Hono](https://hono.dev/) + the [Vercel AI SDK](https://sdk.vercel.ai/) on the backend. The agent loop talks to this same TTT MCP server over STDIO — the same code path as the IDE integration.\n\n---\n\n## Example Prompts\n\nBelow are example prompts you can use with AI assistants (Claude, Cursor, etc.) when this MCP server is configured:\n\n<details>\n<summary>🎨 Basic Design Creation</summary>\n\n```\nCreate a 1920x1080 Photoshop document with RGB color mode.\nAdd a light blue background layer and fill it with RGB(240, 248, 255).\nAdd centered text \"Welcome\" in 64pt font.\nSave as welcome.psd to my Desktop.\n```\n\n</details>\n\n<details>\n<summary>🖼️ Stock Image Design (with Pexels MCP)</summary>\n\n```\nSearch Pexels for \"mountain sunset\" images.\nCreate a 1920x1080 Photoshop document.\nPlace the downloaded image and fit it to fill the entire canvas.\nApply a subtle Gaussian blur of 3px.\nIncrease brightness by 15 and contrast by 10.\nAdd white text \"Adventure Awaits\" centered at the top in 72pt.\nSet the text opacity to 90% and blend mode to OVERLAY.\nSave as adventure.jpg with quality 10.\n```\n\n</details>\n\n<details>\n<summary>✨ Photo Enhancement</summary>\n\n```\nOpen photo.jpg from my Desktop in Photoshop.\nApply auto levels and auto contrast.\nApply unsharp mask with amount 120%, radius 1.5, threshold 0.\nIncrease saturation by 15.\nCrop to remove 100px from each edge.\nSave as enhanced-photo.jpg with quality 12.\n```\n\n</details>\n\n<details>\n<summary>🎭 Layer Effects & Blending</summary>\n\n```\nCreate a 1200x800 document.\nAdd a new layer named \"Background\" and fill with RGB(50, 50, 50).\nPlace logo.png at position (100, 100).\nFit the logo layer to 50% of its current size.\nSet blend mode to SCREEN and opacity to 85%.\nAdd another layer, fill with RGB(255, 100, 50).\nSet this layer's blend mode to MULTIPLY and opacity to 60%.\nMerge all visible layers.\nSave as composite.psd.\n```\n\n</details>\n\n<details>\n<summary>🎬 After Effects Animation</summary>\n\n```\nCreate a 1920x1080 composition named \"Intro Animation\" at 30fps for 5 seconds.\nAdd a solid layer (red, 1920x1080) named \"Background\".\nAdd a text layer \"HELLO WORLD\" at position 960, 540.\nSet the text layer opacity to 0%.\nAnimate the text opacity from 0% to 100% over time.\nSet the background layer opacity to 80%.\nSave the project as intro.aep to Desktop.\n```\n\n</details>\n\n---\n\n## Features\n\n- ✅ **Provider-driven MCP**: Backends live under `src/providers/` (e.g. `adobe/photoshop/`, `docker/`) and register tools through a shared `Provider` interface; `src/providers/index.ts` is the single entry that composes the live server.\n- ✅ **Unified local orchestration**: One MCP process exposes every enabled backend; Cursor, Claude Desktop, and the standalone UI all hit the same registry and handlers.\n- ✅ **Standalone UI**: Local chat with model choice, persisted history, and **per-chat backend selection** (Photoshop, After Effects, Docker, WhatsApp, …).\n- ✅ **Adobe desktop automation (supported apps)**: Photoshop via AppleScript (macOS) / COM (Windows) with ExtendScript execution; After Effects on macOS via JXA and file-backed script I/O; Windows After Effects via `afterfx.exe -r` (⚠️ untested). Auto-discovery with optional `PHOTOSHOP_PATH` / `AFTER_EFFECTS_PATH`.\n- ✅ **Docker Engine**: Full `docker_*` surface plus `dockerhub_*` and `ghcr_*` registry tools when the local daemon is running and reachable.\n- ✅ **WhatsApp (beta, UI-hosted)**: `whatsapp_*` tools for status, recipient checks, send text/image (public URL), and optional extended read tools with explicit UI consent; session via Baileys in the **standalone UI** with QR linking under Settings → Messaging.\n- ✅ **Photoshop-specific depth**: Undo/redo, history states, playing actions, and custom ExtendScript—all scoped to the Photoshop provider, not universal across every tool name.\n- 🚧 **More backends**: Illustrator, Figma, OpenClaw, and Hermes ship as scaffolds today; they follow the same provider pattern as Adobe and Docker.\n\n## Installation\n\n### Using NPX (Recommended)\n\nNo installation required! Just configure your MCP client to launch:\n\n```bash\nnpx -y @alisaitteke/ttt mcp\n```\n\n### From Source\n\n```bash\ngit clone https://github.com/alisaitteke/ttt.git\ncd ttt\nnpm install\nnpm run build\n```\n\n## Configuration\n\n### For Cursor\n\nAdd to your Cursor settings (`.cursor/config.json` or workspace settings):\n\n```json\n{\n  \"mcpServers\": {\n    \"ttt\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@alisaitteke/ttt\", \"mcp\"],\n      \"env\": {\n        \"LOG_LEVEL\": \"1\"\n      }\n    }\n  }\n}\n```\n\n### For Claude Desktop\n\nAdd to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\\Claude\\claude_desktop_config.json` on Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"ttt\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@alisaitteke/ttt\", \"mcp\"],\n      \"env\": {\n        \"LOG_LEVEL\": \"1\"\n      }\n    }\n  }\n}\n```\n\n## Environment Variables\n\n- `TTT_HOME`: (Optional) Override the TTT data directory (default `~/.ttt`). Used for SQLite, exports, credential-relative paths, WhatsApp adapter files under `connections/whatsapp/`, and the detached UI state file (`ui-background.json`). See [Running the UI in the background](#running-the-ui-in-the-background-detached).\n- `PHOTOSHOP_PATH`: (Optional) Specify custom Photoshop installation path\n- `AFTER_EFFECTS_PATH`: (Optional) Specify custom After Effects installation path\n- `LOG_LEVEL`: Logging level (0=DEBUG, 1=INFO, 2=WARN, 3=ERROR)\n- `TTT_CONNECTION_BRIDGE_URL` / `TTT_CONNECTION_BRIDGE_SECRET`: Used by the WhatsApp MCP tools to POST to `${URL}/api/internal/connections/whatsapp/tools/...` with header `x-ttt-bridge-secret`. In normal use the **standalone UI sets these when it spawns MCP** for chat; you do not configure them manually. External MCP hosts (Cursor, Claude Desktop) do not receive the ephemeral secret unless you replicate the bridge yourself.\n- `TTT_WHATSAPP_EXTENDED_DATA_CONSENT`: Set to `1` by the UI’s agent when the user enabled extended read tools in **Settings → Messaging → WhatsApp**; registers `whatsapp_list_chats`, `whatsapp_fetch_messages`, and `whatsapp_search_contacts`. Not intended for manual editing.\n\n## Tool Reference\n\n<details>\n<summary><strong>Photoshop tools</strong> (50+ tools, <code>photoshop_*</code> prefix)</summary>\n\n### Connection & Info\n- `photoshop_ping` — Test connection\n- `photoshop_get_version` — Get version info\n\n### Document Management\n- `photoshop_create_document` — Create new document\n- `photoshop_get_document_info` — Get active document info\n- `photoshop_save_document` — Save document (PSD/JPEG/PNG)\n- `photoshop_close_document` — Close document\n- `photoshop_resize_image` — Resize image dimensions\n- `photoshop_crop_document` — Crop document bounds\n\n### Layer Operations\n- `photoshop_create_layer` — Create new layer\n- `photoshop_delete_layer` — Delete active layer\n- `photoshop_create_text_layer` — Create text layer\n- `photoshop_fill_layer` — Fill with solid color\n- `photoshop_get_layers` — List all layers\n- `photoshop_duplicate_layer` — Duplicate layer\n- `photoshop_merge_visible_layers` — Merge visible layers\n- `photoshop_flatten_image` — Flatten to single layer\n- `photoshop_rasterize_layer` — Rasterize layer\n\n### Layer Properties\n- `photoshop_set_layer_opacity` — Set opacity (0-100)\n- `photoshop_set_layer_blend_mode` — Set blend mode (NORMAL, MULTIPLY, SCREEN, etc.)\n- `photoshop_set_layer_visibility` — Show/hide layer\n- `photoshop_set_layer_locked` — Lock/unlock layer\n- `photoshop_rename_layer` — Rename layer\n\n### Layer Ordering\n- `photoshop_move_layer_to_position` — Move relative to another layer\n- `photoshop_move_layer_to_top` — Move to top\n- `photoshop_move_layer_to_bottom` — Move to bottom\n- `photoshop_move_layer_up` — Move up one position\n- `photoshop_move_layer_down` — Move down one position\n\n### Layer Transformations\n- `photoshop_fit_layer_to_document` — Scale to fit/fill canvas\n- `photoshop_scale_layer` — Scale by percentage\n- `photoshop_move_layer` — Move by offset\n- `photoshop_rotate_layer` — Rotate by degrees\n\n### Filters\n- `photoshop_apply_gaussian_blur` — Gaussian blur\n- `photoshop_apply_sharpen` — Unsharp mask\n- `photoshop_apply_noise` — Add noise\n- `photoshop_apply_motion_blur` — Motion blur\n\n### Color Adjustments\n- `photoshop_adjust_brightness_contrast` — Brightness/contrast\n- `photoshop_adjust_hue_saturation` — Hue/saturation/lightness\n- `photoshop_auto_levels` — Auto levels\n- `photoshop_auto_contrast` — Auto contrast\n- `photoshop_desaturate` — Desaturate to grayscale\n- `photoshop_invert` — Invert colors\n\n### Text Formatting\n- `photoshop_set_text_font` — Set font family/size\n- `photoshop_set_text_color` — Set text color\n- `photoshop_set_text_alignment` — Set alignment\n- `photoshop_update_text_content` — Update text content\n\n### Selections & Masks\n- `photoshop_select_rectangle` — Create rectangular selection\n- `photoshop_select_all` — Select entire document\n- `photoshop_deselect` — Clear selection\n- `photoshop_invert_selection` — Invert selection\n- `photoshop_create_layer_mask` — Create mask from selection\n- `photoshop_delete_layer_mask` — Delete mask\n- `photoshop_apply_layer_mask` — Apply mask\n\n### History & Undo/Redo\n- `photoshop_undo` — Undo operation(s)\n- `photoshop_redo` — Redo operation(s)\n- `photoshop_get_history` — Get history states\n\n### Actions & Automation\n- `photoshop_play_action` — Play recorded action\n- `photoshop_execute_script` — Execute custom ExtendScript\n\n### Image Placement\n- `photoshop_place_image` — Place image file as layer\n- `photoshop_open_image` — Open image file as new document\n\n</details>\n\n<details>\n<summary><strong>After Effects tools</strong> (~18 tools, <code>aftereffects_*</code> prefix)</summary>\n\n⚠️ **Important**: Before using After Effects tools, enable **\"Allow Scripts to Write Files and Access Network\"** in After Effects Preferences > Scripting & Expressions.\n\n### Project Management\n- `aftereffects_ping` — Test connection\n- `aftereffects_get_version` — Get version info\n- `aftereffects_get_project_info` — Get project details\n- `aftereffects_save_project` — Save project\n- `aftereffects_open_project` — Open project file\n\n### Composition Management\n- `aftereffects_create_composition` — Create new comp\n- `aftereffects_list_compositions` — List all comps\n- `aftereffects_get_composition_info` — Get comp details\n- `aftereffects_delete_composition` — Delete comp\n\n### Layer Creation\n- `aftereffects_create_text_layer` — Add text layer\n- `aftereffects_create_solid_layer` — Add solid color layer\n- `aftereffects_create_shape_layer` — Add shape layer\n- `aftereffects_create_null_layer` — Add null object\n\n### Layer Properties\n- `aftereffects_set_layer_transform` — Set position/scale/rotation\n- `aftereffects_set_layer_opacity` — Set layer opacity\n\n### Layer Lifecycle\n- `aftereffects_rename_layer` — Rename layer\n- `aftereffects_delete_layer` — Delete layer\n- `aftereffects_duplicate_layer` — Duplicate layer\n\n</details>\n\n<details>\n<summary><strong>WhatsApp tools</strong> (<code>whatsapp_*</code> prefix — beta, UI-linked session)</summary>\n\nRequires the **standalone UI** (`ttt start`) running with WhatsApp linked under **Settings → Messaging**. Use `whatsapp_status` before sends when the session might have dropped (there is no `whatsapp_ping`). Recipient `to` fields use **digits only** (country code, no `+` or spaces).\n\n### Session & recipients\n- `whatsapp_status` — Linked-session reachability (connection hint).\n- `whatsapp_check_recipient` — Ask WhatsApp whether a number is registered (`onWhatsApp`).\n\n### Messaging\n- `whatsapp_send_message` — Plain text to `to`.\n- `whatsapp_send_image` — One image or looping GIF from a **public** `http(s)` URL (host downloads) **or** from `localFilePath`: an absolute path under `~/.ttt/drops` or `~/.ttt/exports` (staged uploads / MCP exports — not arbitrary paths). Exactly one source. Optional `caption`. For GIF-style animation from URLs, prefer `.mp4` or `.gif` — not `.webp` previews, which send as a static image.\n- `whatsapp_send_document` — Generic file (PDF, ZIP, archives, Office, etc.): same `localFilePath` restriction as above; optional `mimetype` (guess from extension if omitted), `fileName`, `caption`.\n\n### Extended read (optional UI consent)\nOnly registered when **Allow AI to read chats & contacts** is enabled in the WhatsApp settings dialog (sets `TTT_WHATSAPP_EXTENDED_DATA_CONSENT=1` for the UI-spawned MCP child):\n\n- `whatsapp_list_chats` — Recent chats from local Baileys cache (may be incomplete until sync).\n- `whatsapp_fetch_messages` — Recent messages for a chat (`chatJid` or phone `to`).\n- `whatsapp_search_contacts` — Substring search over synced contacts.\n\n</details>\n\n---\n\n## Context Tracking\n\nWhere a provider attaches it, responses include richer operational context (not every `docker_*` reply mirrors Photoshop document payloads). Examples:\n\n- **Document info**: Name, dimensions, resolution, color mode, layer count (Photoshop)\n- **Active layer**: Name, type, opacity, blend mode, visibility, lock state (Photoshop)\n- **Selection state**: Whether a selection is active (Photoshop)\n- **Composition**: Name, dimensions, frame rate, duration (After Effects)\n- **Operation result**: What changed for this invocation\n\nThis helps assistants stay aligned with the current document, layer, or composition across multiple calls when that data is available.\n\n---\n\n## Platform-Specific Notes\n\n### Windows\n\n- **Photoshop**: Uses COM automation to communicate with Photoshop\n- **After Effects**: Uses `afterfx.exe -r` command-line script execution (⚠️ untested by author, contributions welcome)\n- Registry-based auto-detection for installation paths\n- Supports both 32-bit and 64-bit versions\n\n### macOS\n\n- **Photoshop**: Uses AppleScript/OSA for communication\n- **After Effects**: Uses JXA (JavaScript for Automation) with `DoScriptFile` (AE 2024+ broke AppleScript `DoScriptFile`, so JXA is used exclusively)\n- Spotlight-based auto-detection\n- Supports multiple Adobe app versions installed simultaneously\n\n## Supported Versions\n\n- **Photoshop**: All versions (2012-2025+) via ExtendScript API\n- **After Effects**: 2024-2025+ tested on macOS; older versions should work but untested\n\n**Important Note**: While Photoshop 2022+ supports UXP for plugins, external automation via AppleScript/COM can only use ExtendScript. UXP is designed for internal plugins and cannot be invoked from external scripts. Therefore, this MCP server uses ExtendScript for maximum compatibility across all Photoshop versions.\n\n## Troubleshooting\n\n### Photoshop\n\n#### \"Photoshop not found\"\n\n1. Make sure Photoshop is installed in the default location\n2. Or set `PHOTOSHOP_PATH` environment variable to custom installation path\n\n```json\n{\n  \"env\": {\n    \"PHOTOSHOP_PATH\": \"C:\\\\Custom\\\\Path\\\\Adobe Photoshop 2025\\\\Photoshop.exe\"\n  }\n}\n```\n\n#### \"Failed to connect to Photoshop\"\n\n1. Ensure Photoshop is running (the server will try to launch it if not)\n2. Check that scripting is enabled in Photoshop preferences\n3. On Windows, verify COM automation is not blocked by security settings\n\n### After Effects\n\n#### \"After Effects not found\"\n\n1. Make sure After Effects is installed in the default location\n2. Or set `AFTER_EFFECTS_PATH` environment variable to custom installation path\n\n#### \"Script timed out\" or \"Make sure Allow Scripts to Write Files is enabled\"\n\n⚠️ This is the most common issue with After Effects!\n\n1. Open After Effects\n2. Go to **Preferences > Scripting & Expressions**\n3. Enable **\"Allow Scripts to Write Files and Access Network\"**\n4. Restart After Effects (or at least close and reopen any projects)\n\nAfter Effects scripts use file-based I/O to return results, and this preference MUST be enabled.\n\n### WhatsApp\n\n#### Tools return “require the TTT web UI” or bridge errors\n\nWhatsApp runs inside the **standalone UI** process (`ttt start`). Link the device under **Settings → Messaging**, enable **WhatsApp** for that chat, and use the standalone UI (or supply bridge env vars yourself for advanced setups). A Cursor/Claude-only MCP spawn does **not** get the ephemeral bridge secret.\n\n#### QR fails or “outdated web client” / session rejected\n\nUpdate WhatsApp on your phone and this package when prompted; use **Disconnect & remove session** in the WhatsApp dialog and scan again if the session was rejected.\n\n### General\n\n#### Debug Logging\n\nEnable detailed logging by setting `LOG_LEVEL=0`:\n\n```json\n{\n  \"env\": {\n    \"LOG_LEVEL\": \"0\"\n  }\n}\n```\n\n## Development\n\n### Build\n\n```bash\nnpm run build\n```\n\n### Watch Mode\n\n```bash\nnpm run dev\n```\n\n### Lint & Format\n\n```bash\nnpm run lint\nnpm run format\n```\n\n---\n\n## Architecture\n\nTTT is **provider-driven**: the MCP server core is backend-agnostic. Each provider owns detection, connections, lifecycle, and tool registration through the shared `Provider` interface—whether that is Adobe apps, Docker, or a future REST bridge. Adding a backend is dropping a folder under `src/providers/` and listing it in `src/providers/index.ts`.\n\n```\nsrc/\n├── core/                            # Provider-agnostic MCP plumbing\n│   ├── server.ts                    # TTTServer — wires registry + providers\n│   ├── tool-registry.ts             # In-memory tool registry\n│   └── types.ts                     # Provider interface\n├── providers/\n│   ├── index.ts                     # The list of enabled providers\n│   ├── adobe/\n│   │   ├── _shared/                 # Shared across all Adobe CC apps\n│   │   │   ├── platform/            # macOS / Windows ExtendScript executors\n│   │   │   └── detector/            # BaseAdobeDetector\n│   │   ├── photoshop/               # ✅ Fully implemented\n│   │   │   ├── detector.ts          # extends BaseAdobeDetector\n│   │   │   ├── connection.ts\n│   │   │   ├── api/                 # extendscript.ts, api-factory.ts\n│   │   │   ├── tools/               # photoshop_* MCP tools\n│   │   │   └── index.ts             # registers the Photoshop provider\n│   │   ├── illustrator/             # 🚧 scaffold\n│   │   └── after-effects/           # ✅ Initial implementation (~18 tools)\n│   │       ├── detector.ts          # extends BaseAdobeDetector\n│   │       ├── connection.ts\n│   │       ├── macos-executor.ts    # JXA + DoScriptFile + file-based I/O\n│   │       ├── windows-executor.ts  # afterfx.exe -r (untested)\n│   │       ├── extendscript.ts      # AE ExtendScript snippets\n│   │       ├── tools/               # aftereffects_* MCP tools\n│   │       └── index.ts             # registers the After Effects provider\n│   ├── docker/                      # ✅ Docker Engine (docker_* + registry tools)\n│   │   ├── dispatch-docker-tool.ts  # Bridges embedded docker-mcp tools\n│   │   └── index.ts                 # Registers the Docker provider\n│   ├── whatsapp/                    # ✅ whatsapp_* MCP tools (HTTP bridge → UI Baileys)\n│   │   └── index.ts\n│   ├── figma/                       # 🚧 scaffold\n│   ├── openclaw/                    # 🚧 scaffold\n│   └── hermes/                      # 🚧 scaffold\n├── connections/                     # Long-lived adapters used by the UI server\n│   └── adapters/whatsapp/         # Baileys socket + tool invoke for whatsapp_*\n├── ui/                              # Standalone Vue + Hono UI\n└── utils/\n    └── logger.ts\nexamples/                            # Cursor / Claude Desktop sample configs\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT\n\n## Acknowledgments\n\n- Built with the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/sdk)\n- Inspired by the Adobe Photoshop scripting community\n- WhatsApp linking uses the community [Baileys](https://github.com/WhiskeySockets/Baileys) library (not affiliated with Meta / WhatsApp)\n\n> A provider-driven **local MCP orchestrator**: one MCP server (and optional bundled web UI) unifies Adobe desktop automation, Docker Engine tooling, optional WhatsApp messaging via the UI, and other backends behind a shared tool registry.\n\n> **Note:** This is an unofficial, community-maintained project and is not affiliated with or endorsed by Adobe Inc., Figma Inc., Docker Inc., or any other vendor whose product TTT integrates with.\n","readmeFilename":"README.md"}