Build, test, and extend the TD MCP server.
git clone https://github.com/Verbalize-public/td-mcp.git
cd td-mcp
npm ci
npm run gen # OpenAPI bundle, Python handlers, TypeScript client
npm run build # gen + tsc → dist/TouchDesigner side: import td/mcp_webserver_base.tox or use create_td_project for owned instances.
| Command | Purpose |
|---|---|
npm run dev |
MCP Inspector against dist/cli.js --stdio |
npm run hub |
Start tdmcp-hub on :9980 (usually auto via ensureHub) |
npm run http |
HTTP transport on :6280 |
npm test |
Unit + integration suites |
npm run test:unit |
Vitest unit tests |
npm run test:integration |
Integration tests (some need live TD on 9981) |
npm run lint |
Biome, TypeScript, Ruff, Prettier |
npm run format |
Auto-fix formatting |
npm run coverage |
V8 coverage report |
make build |
Docker-based TD module build |
src/
├── api/ # OpenAPI schema (source of truth)
├── core/ # Constants, shared types
├── features/tools/# MCP tool definitions + handlers
├── gen/ # Generated Orval client + Zod (do not edit)
├── hub/ # tdmcp-hub server
├── server/ # TouchDesignerServer (MCP)
├── tdClient/ # HTTP client to TD WebServer / hub proxy
└── transport/ # stdio + HTTP transport
td/
├── modules/ # Python inside TouchDesigner
├── mcp_webserver_base.tox
└── genHandlers.js # Python handler codegen
templates/mcp_project/ # create_td_project / inject kit
tests/unit/ tests/integration/
docs/
Generated output: dist/, src/gen/, td/modules/td_server/openapi_server/openapi/openapi.yaml, and the template copy of that OpenAPI file.
After editing src/api/index.yml:
npm run genSteps:
gen:openapi— Redocly bundle →td/modules/.../openapi.yamlandtemplates/mcp_project/modules/.../openapi.yamlgen:handlers— Python handler stubs intd/modules/gen:mcp— TypeScript client + Zod insrc/gen/
Then npm run build and restart MCP clients.
package.json is the version source. On version bump:
npm run version # syncs API version in td/modules/utils/version.py via syncApiServerVersionsThere is no npm publish workflow in CI — bump version when the MCP/API contract changes.
Use your local dist/cli.js:
{
"mcpServers": {
"touchdesigner": {
"command": "node",
"args": ["/absolute/path/to/td-mcp/dist/cli.js", "--stdio"]
}
}
}Agents: read AGENT_MCP.md for sticky targets, lifecycle, and verification. Run only one TD MCP server entry in your client.
npm run test:unit
# TD-independent integration:
npx vitest run tests/integration/mcpToolsResponse.test.ts
npx vitest run tests/integration/httpTransport.test.ts
# Live TD on 9981:
TD_WEB_SERVER_HOST=http://127.0.0.1 TD_WEB_SERVER_PORT=9981 \
npx vitest run tests/integration/touchDesignerClientAndWebServer.test.tsChanging MCP/API surface? Add integration coverage — see .claude/skills/integration-test-guard/SKILL.md.
- ESM TypeScript, tabs, double quotes; Python 3.9+, Ruff tabs/88 cols
- Imperative commit subjects:
feat:,fix:,test:,docs:,chore: - Run
npm run lintandnpm run test:unitbefore PRs