touchdesigner-mcp-server 1.4.9 → 1.4.10

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.
Files changed (45) hide show
  1. package/dist/api/customInstance.d.ts +5 -0
  2. package/dist/cli.d.ts +50 -0
  3. package/dist/core/compatibility.d.ts +102 -0
  4. package/dist/core/constants.d.ts +29 -0
  5. package/dist/core/errorHandling.d.ts +18 -0
  6. package/dist/core/logger.d.ts +24 -0
  7. package/dist/core/result.d.ts +25 -0
  8. package/dist/core/version.d.ts +21 -0
  9. package/dist/features/prompts/handlers/td_prompts.d.ts +6 -0
  10. package/dist/features/prompts/index.d.ts +1 -0
  11. package/dist/features/prompts/register.d.ts +6 -0
  12. package/dist/features/tools/handlers/tdTools.d.ts +4 -0
  13. package/dist/features/tools/index.d.ts +3 -0
  14. package/dist/features/tools/metadata/touchDesignerToolMetadata.d.ts +29 -0
  15. package/dist/features/tools/presenter/classListFormatter.d.ts +29 -0
  16. package/dist/features/tools/presenter/index.d.ts +18 -0
  17. package/dist/features/tools/presenter/markdownRenderer.d.ts +3 -0
  18. package/dist/features/tools/presenter/moduleHelpFormatter.d.ts +12 -0
  19. package/dist/features/tools/presenter/nodeDetailsFormatter.d.ts +16 -0
  20. package/dist/features/tools/presenter/nodeErrorsFormatter.d.ts +4 -0
  21. package/dist/features/tools/presenter/nodeListFormatter.d.ts +22 -0
  22. package/dist/features/tools/presenter/operationFormatter.d.ts +16 -0
  23. package/dist/features/tools/presenter/presenter.d.ts +10 -0
  24. package/dist/features/tools/presenter/responseFormatter.d.ts +83 -0
  25. package/dist/features/tools/presenter/scriptResultFormatter.d.ts +23 -0
  26. package/dist/features/tools/presenter/toolMetadataFormatter.d.ts +7 -0
  27. package/dist/features/tools/register.d.ts +7 -0
  28. package/dist/features/tools/toolDefinitions.d.ts +38 -0
  29. package/dist/features/tools/types.d.ts +43 -0
  30. package/dist/features/tools/utils/toolUtils.d.ts +0 -0
  31. package/dist/gen/endpoints/TouchDesignerAPI.d.ts +510 -0
  32. package/dist/gen/mcp/touchDesignerAPI.zod.d.ts +253 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/server/connectionManager.d.ts +25 -0
  35. package/dist/server/touchDesignerServer.d.ts +59 -0
  36. package/dist/tdClient/index.d.ts +7 -0
  37. package/dist/tdClient/touchDesignerClient.d.ts +167 -0
  38. package/dist/transport/config.d.ts +96 -0
  39. package/dist/transport/expressHttpManager.d.ts +86 -0
  40. package/dist/transport/factory.d.ts +81 -0
  41. package/dist/transport/index.d.ts +15 -0
  42. package/dist/transport/sessionManager.d.ts +180 -0
  43. package/dist/transport/transportRegistry.d.ts +92 -0
  44. package/dist/transport/validator.d.ts +43 -0
  45. package/package.json +1 -1
@@ -0,0 +1,86 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ILogger } from "../core/logger.js";
3
+ import type { Result } from "../core/result.js";
4
+ import type { StreamableHttpTransportConfig } from "./config.js";
5
+ /**
6
+ * Express HTTP Manager
7
+ *
8
+ * Manages HTTP server lifecycle for Streamable HTTP transport.
9
+ * Handles multiple concurrent sessions by creating per-session transport and server instances.
10
+ *
11
+ * Key Features:
12
+ * - /mcp endpoint → routes to appropriate transport via TransportRegistry
13
+ * - /health endpoint → reports active session count
14
+ * - Per-session isolation → each client gets independent MCP protocol state
15
+ * - Graceful shutdown → cleans up all active sessions
16
+ *
17
+ * Architecture:
18
+ * ```
19
+ * Client 1 → POST /mcp → TransportRegistry.getOrCreate() → Transport 1 + Server 1
20
+ * Client 2 → POST /mcp → TransportRegistry.getOrCreate() → Transport 2 + Server 2
21
+ * ```
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const manager = new ExpressHttpManager(
26
+ * config,
27
+ * () => TouchDesignerServer.create(), // Server factory
28
+ * sessionManager,
29
+ * logger
30
+ * );
31
+ *
32
+ * // Start server
33
+ * const result = await manager.start();
34
+ *
35
+ * // Graceful shutdown
36
+ * await manager.stop();
37
+ * ```
38
+ */
39
+ export declare class ExpressHttpManager {
40
+ private readonly config;
41
+ private readonly serverFactory;
42
+ private readonly logger;
43
+ private readonly registry;
44
+ private server;
45
+ /**
46
+ * Create ExpressHttpManager with server factory
47
+ *
48
+ * @param config - Streamable HTTP transport configuration
49
+ * @param serverFactory - Factory function to create new Server instances per session
50
+ * @param sessionManager - Session manager for TTL tracking (optional)
51
+ * @param logger - Logger instance
52
+ */
53
+ constructor(config: StreamableHttpTransportConfig, serverFactory: () => McpServer, sessionManager: import("./sessionManager.js").ISessionManager | null, logger: ILogger);
54
+ /**
55
+ * Start HTTP server with Express app from SDK
56
+ *
57
+ * @returns Result indicating success or failure
58
+ */
59
+ start(): Promise<Result<void, Error>>;
60
+ /**
61
+ * Graceful shutdown
62
+ *
63
+ * Stops HTTP server and cleans up all active sessions.
64
+ *
65
+ * @returns Result indicating success or failure
66
+ */
67
+ stop(): Promise<Result<void, Error>>;
68
+ /**
69
+ * Check if server is running
70
+ *
71
+ * @returns True if server is running
72
+ */
73
+ isRunning(): boolean;
74
+ /**
75
+ * Get active session count
76
+ *
77
+ * @returns Number of active sessions
78
+ */
79
+ getActiveSessionCount(): number;
80
+ /**
81
+ * Get all active session IDs
82
+ *
83
+ * @returns Array of session IDs
84
+ */
85
+ getActiveSessionIds(): string[];
86
+ }
@@ -0,0 +1,81 @@
1
+ import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
2
+ import type { ILogger } from "../core/logger.js";
3
+ import type { Result } from "../core/result.js";
4
+ import type { TransportConfig } from "./config.js";
5
+ import type { ISessionManager } from "./sessionManager.js";
6
+ /**
7
+ * Factory for creating MCP transport instances based on configuration
8
+ *
9
+ * This factory implements the Factory pattern to encapsulate transport creation logic.
10
+ * It validates configuration and creates the appropriate transport type (stdio or HTTP).
11
+ */
12
+ export declare class TransportFactory {
13
+ /**
14
+ * Reset the internal state of a StreamableHTTPServerTransport instance
15
+ *
16
+ * WARNING: This method manipulates the private field '_initialized' using Reflect.set().
17
+ * This is fragile and may break if the MCP SDK implementation changes.
18
+ * There is currently no public API to reset the initialized state, so this is required
19
+ * to ensure the transport can be reused safely after a session is closed.
20
+ * If the SDK adds a public reset/init method, use that instead.
21
+ * If the SDK changes the field name or its semantics, update this code accordingly.
22
+ */
23
+ private static resetStreamableHttpState;
24
+ /**
25
+ * Create a transport instance from configuration
26
+ *
27
+ * @param config - Transport configuration (stdio or streamable-http)
28
+ * @param logger - Optional logger for HTTP transport session events (ignored for stdio)
29
+ * @param sessionManager - Optional session manager for HTTP transport (ignored for stdio)
30
+ * @returns Result with Transport instance or Error
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Create stdio transport
35
+ * const stdioResult = TransportFactory.create({ type: 'stdio' });
36
+ *
37
+ * // Create HTTP transport with logger and session manager
38
+ * const httpResult = TransportFactory.create({
39
+ * type: 'streamable-http',
40
+ * port: 6280,
41
+ * host: '127.0.0.1',
42
+ * endpoint: '/mcp'
43
+ * }, logger, sessionManager);
44
+ * ```
45
+ */
46
+ static create(config: TransportConfig, logger?: ILogger, sessionManager?: ISessionManager | null): Result<Transport, Error>;
47
+ /**
48
+ * Create a stdio transport instance
49
+ *
50
+ * @param _config - Stdio transport configuration (unused, kept for API consistency)
51
+ * @returns Result with StdioServerTransport instance
52
+ */
53
+ private static createStdio;
54
+ /**
55
+ * Create a streamable HTTP transport instance
56
+ *
57
+ * Creates a StreamableHTTPServerTransport with session management support.
58
+ * The transport instance is stateful and manages session lifecycle through callbacks.
59
+ *
60
+ * Note: DNS rebinding protection is handled by Express middleware (createMcpExpressApp)
61
+ * in the ExpressHttpManager, not by the transport itself.
62
+ *
63
+ * @param config - Streamable HTTP transport configuration
64
+ * @param logger - Optional logger for session lifecycle events
65
+ * @param sessionManager - Optional session manager for tracking sessions
66
+ * @returns Result with StreamableHTTPServerTransport instance or Error
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const config: StreamableHttpTransportConfig = {
71
+ * type: 'streamable-http',
72
+ * port: 6280,
73
+ * host: '127.0.0.1',
74
+ * endpoint: '/mcp',
75
+ * sessionConfig: { enabled: true }
76
+ * };
77
+ * const result = TransportFactory.createStreamableHttp(config, logger, sessionManager);
78
+ * ```
79
+ */
80
+ private static createStreamableHttp;
81
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Transport layer module exports
3
+ *
4
+ * This module provides type-safe configuration and validation for MCP transports:
5
+ * - stdio: Standard input/output transport
6
+ * - streamable-http: HTTP-based transport with SSE streaming
7
+ */
8
+ export type { SessionConfig, StdioTransportConfig, StreamableHttpTransportConfig, TransportConfig, TransportType, } from "./config.js";
9
+ export { DEFAULT_HTTP_CONFIG, DEFAULT_SESSION_CONFIG, isStdioTransportConfig, isStreamableHttpTransportConfig, TransportConfigSchema, } from "./config.js";
10
+ export { ExpressHttpManager } from "./expressHttpManager.js";
11
+ export { TransportFactory } from "./factory.js";
12
+ export type { ISessionManager, Session } from "./sessionManager.js";
13
+ export { SessionManager } from "./sessionManager.js";
14
+ export type { ValidationError } from "./validator.js";
15
+ export { TransportConfigValidator } from "./validator.js";
@@ -0,0 +1,180 @@
1
+ import type { ILogger } from "../core/logger.js";
2
+ import type { Result } from "../core/result.js";
3
+ import type { SessionConfig } from "./config.js";
4
+ /**
5
+ * Session metadata
6
+ */
7
+ export interface Session {
8
+ /**
9
+ * Unique session identifier (UUID v4)
10
+ */
11
+ id: string;
12
+ /**
13
+ * Timestamp when session was created (milliseconds since epoch)
14
+ */
15
+ createdAt: number;
16
+ /**
17
+ * Timestamp when session was last accessed (milliseconds since epoch)
18
+ */
19
+ lastAccessedAt: number;
20
+ /**
21
+ * Optional metadata associated with the session
22
+ */
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * Session manager interface
27
+ */
28
+ export interface ISessionManager {
29
+ /**
30
+ * Create a new session with auto-generated ID
31
+ */
32
+ create(metadata?: Record<string, unknown>): string;
33
+ /**
34
+ * Refresh last access time for a session
35
+ */
36
+ touch(sessionId: string): Result<void, Error>;
37
+ /**
38
+ * Register a callback invoked when a session expires via TTL cleanup.
39
+ */
40
+ setExpirationHandler(handler: (sessionId: string) => Promise<void> | void): void;
41
+ /**
42
+ * Register an existing session (created by SDK)
43
+ */
44
+ register(sessionId: string, metadata?: Record<string, unknown>): void;
45
+ /**
46
+ * Clean up a session by ID
47
+ */
48
+ cleanup(sessionId: string): Result<void, Error>;
49
+ /**
50
+ * List all active sessions
51
+ */
52
+ list(): Session[];
53
+ /**
54
+ * Start automatic TTL-based cleanup
55
+ */
56
+ startTTLCleanup(): void;
57
+ /**
58
+ * Stop automatic TTL-based cleanup
59
+ */
60
+ stopTTLCleanup(): void;
61
+ /**
62
+ * Get number of active sessions
63
+ */
64
+ getActiveSessionCount(): number;
65
+ /**
66
+ * Clear all sessions (for testing or emergency cleanup)
67
+ */
68
+ clearAll(): void;
69
+ }
70
+ /**
71
+ * Session Manager
72
+ *
73
+ * Manages client sessions for Streamable HTTP transport.
74
+ * Provides session creation, validation, TTL-based expiration, and automatic cleanup.
75
+ *
76
+ * Note: Session validation (checking if session ID exists) is now handled by
77
+ * StreamableHTTPServerTransport.handleRequest(). This SessionManager focuses on:
78
+ * - Session creation via SDK callbacks (onsessioninitialized)
79
+ * - Session cleanup via SDK callbacks (onsessionclosed) and TTL-based cleanup
80
+ * - Session tracking for health checks and monitoring
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const sessionManager = new SessionManager(
85
+ * { enabled: true, ttl: 60 * 60 * 1000 }, // 1 hour TTL
86
+ * logger
87
+ * );
88
+ *
89
+ * // Create session (typically called from SDK callback)
90
+ * const sessionId = sessionManager.create({ clientVersion: '1.0' });
91
+ *
92
+ * // Start automatic TTL-based cleanup
93
+ * sessionManager.startTTLCleanup();
94
+ *
95
+ * // Stop cleanup when done
96
+ * sessionManager.stopTTLCleanup();
97
+ * ```
98
+ */
99
+ export declare class SessionManager implements ISessionManager {
100
+ private readonly sessions;
101
+ private readonly config;
102
+ private readonly logger;
103
+ private cleanupInterval;
104
+ private onSessionExpired;
105
+ constructor(config: SessionConfig, logger: ILogger);
106
+ /**
107
+ * Create a new session with optional metadata
108
+ *
109
+ * @param metadata - Optional metadata to associate with the session
110
+ * @returns Session ID (UUID v4)
111
+ */
112
+ create(metadata?: Record<string, unknown>): string;
113
+ /**
114
+ * Update lastAccessedAt when a session receives activity
115
+ *
116
+ * @param sessionId - Session ID to refresh
117
+ */
118
+ touch(sessionId: string): Result<void, Error>;
119
+ /**
120
+ * Register a callback to run when TTL cleanup expires a session.
121
+ *
122
+ * @param handler - Callback invoked with expired session ID
123
+ */
124
+ setExpirationHandler(handler: (sessionId: string) => Promise<void> | void): void;
125
+ /**
126
+ * Register an SDK-created session for tracking
127
+ *
128
+ * This method registers sessions that were created by the MCP SDK's
129
+ * StreamableHTTPServerTransport. The SDK generates session IDs via the
130
+ * sessionIdGenerator callback, and then calls onsessioninitialized.
131
+ * This method creates a new tracking entry with current timestamps
132
+ * so the session can be managed for TTL cleanup and monitoring.
133
+ *
134
+ * @param sessionId - Session ID generated by SDK
135
+ * @param metadata - Optional metadata to associate with the session
136
+ */
137
+ register(sessionId: string, metadata?: Record<string, unknown>): void;
138
+ /**
139
+ * Clean up (delete) a session by ID
140
+ *
141
+ * @param sessionId - Session ID to clean up
142
+ * @returns Result indicating success or failure
143
+ */
144
+ cleanup(sessionId: string): Result<void, Error>;
145
+ /**
146
+ * List all active sessions
147
+ *
148
+ * @returns Array of all active sessions
149
+ */
150
+ list(): Session[];
151
+ /**
152
+ * Start automatic TTL-based cleanup
153
+ *
154
+ * Runs cleanup task at an interval of TTL/2 to remove expired sessions.
155
+ * Does nothing if TTL is not configured or cleanup is already running.
156
+ */
157
+ startTTLCleanup(): void;
158
+ /**
159
+ * Stop automatic TTL-based cleanup
160
+ */
161
+ stopTTLCleanup(): void;
162
+ /**
163
+ * Run a single cleanup task to remove expired sessions
164
+ *
165
+ * @private
166
+ */
167
+ private runCleanupTask;
168
+ /**
169
+ * Get number of active sessions
170
+ *
171
+ * @returns Number of active sessions
172
+ */
173
+ getActiveSessionCount(): number;
174
+ /**
175
+ * Clear all sessions
176
+ *
177
+ * Useful for testing or emergency cleanup.
178
+ */
179
+ clearAll(): void;
180
+ }
@@ -0,0 +1,92 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
+ import type { JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
4
+ import type { ILogger } from "../core/logger.js";
5
+ import type { Result } from "../core/result.js";
6
+ import type { StreamableHttpTransportConfig } from "./config.js";
7
+ import type { ISessionManager } from "./sessionManager.js";
8
+ /**
9
+ * Transport Registry
10
+ *
11
+ * Manages per-session transport and server instances for Streamable HTTP transport.
12
+ * Each session gets its own isolated transport and server to maintain independent MCP protocol state.
13
+ *
14
+ * Key Responsibilities:
15
+ * - Create new transport + server instances for new sessions
16
+ * - Reuse existing transport for requests with valid session IDs
17
+ * - Clean up sessions on close or expiration
18
+ * - Track active session count for health checks
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const registry = new TransportRegistry(config, sessionManager, logger);
23
+ *
24
+ * // In HTTP request handler
25
+ * const transport = await registry.getOrCreate(
26
+ * sessionId,
27
+ * requestBody,
28
+ * () => createTouchDesignerServer()
29
+ * );
30
+ *
31
+ * if (transport) {
32
+ * await transport.handleRequest(req, res, requestBody);
33
+ * }
34
+ *
35
+ * // On shutdown
36
+ * await registry.cleanup();
37
+ * ```
38
+ */
39
+ export declare class TransportRegistry {
40
+ private readonly sessions;
41
+ private readonly config;
42
+ private readonly sessionManager;
43
+ private readonly logger;
44
+ constructor(config: StreamableHttpTransportConfig, sessionManager: ISessionManager | null, logger: ILogger);
45
+ /**
46
+ * Get or create transport for a session
47
+ *
48
+ * Logic:
49
+ * 1. If sessionId exists and valid → return existing transport
50
+ * 2. If no sessionId and request is initialize → create new transport + server
51
+ * 3. Otherwise → return null (invalid session)
52
+ *
53
+ * @param sessionId - Session ID from mcp-session-id header (undefined for new sessions)
54
+ * @param requestBody - JSON-RPC request body
55
+ * @param serverFactory - Factory function to create new Server instances
56
+ * @returns Transport instance or null if session is invalid
57
+ */
58
+ getOrCreate(sessionId: string | undefined, requestBody: JSONRPCMessage, serverFactory: () => McpServer): Promise<StreamableHTTPServerTransport | null>;
59
+ /**
60
+ * Create a new session with transport and server instances
61
+ *
62
+ * @param serverFactory - Factory function to create new Server instances
63
+ * @returns Transport instance for the new session
64
+ */
65
+ private createSession;
66
+ /**
67
+ * Remove session from registry
68
+ *
69
+ * @param sessionId - Session ID to remove
70
+ */
71
+ remove(sessionId: string): void;
72
+ /**
73
+ * Get number of active sessions
74
+ *
75
+ * @returns Active session count
76
+ */
77
+ getCount(): number;
78
+ /**
79
+ * Get all session IDs
80
+ *
81
+ * @returns Array of session IDs
82
+ */
83
+ getSessionIds(): string[];
84
+ /**
85
+ * Cleanup all sessions
86
+ *
87
+ * Called during graceful shutdown to close all active sessions
88
+ *
89
+ * @returns Result indicating success or failure
90
+ */
91
+ cleanup(): Promise<Result<void, Error>>;
92
+ }
@@ -0,0 +1,43 @@
1
+ import type { Result } from "../core/result.js";
2
+ import type { TransportConfig } from "./config.js";
3
+ /**
4
+ * Validation error details
5
+ */
6
+ export interface ValidationError {
7
+ field: string;
8
+ message: string;
9
+ }
10
+ /**
11
+ * Transport configuration validator using Zod schemas
12
+ */
13
+ export declare class TransportConfigValidator {
14
+ /**
15
+ * Validate a transport configuration
16
+ *
17
+ * @param config - The configuration to validate
18
+ * @returns Result with validated config or validation errors
19
+ */
20
+ static validate(config: unknown): Result<TransportConfig, Error>;
21
+ /**
22
+ * Format Zod validation errors into structured ValidationError objects
23
+ *
24
+ * @param zodError - The Zod validation error
25
+ * @returns Array of structured validation errors
26
+ */
27
+ private static formatZodErrors;
28
+ /**
29
+ * Build a comprehensive error message from validation errors
30
+ *
31
+ * @param errors - Array of validation errors
32
+ * @returns Formatted error message
33
+ */
34
+ private static buildErrorMessage;
35
+ /**
36
+ * Validate and merge with defaults for HTTP transport
37
+ * This is a convenience method for applying default values after validation
38
+ *
39
+ * @param config - The configuration to validate
40
+ * @returns Result with validated and merged config
41
+ */
42
+ static validateAndMergeDefaults(config: unknown): Result<TransportConfig, Error>;
43
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "touchdesigner-mcp-server",
3
- "version": "1.4.9",
3
+ "version": "1.4.10",
4
4
  "description": "MCP server for TouchDesigner",
5
5
  "repository": {
6
6
  "type": "git",