touchdesigner-mcp-server 0.4.0-alpha.1 → 0.4.0-alpha.2
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/README.ja.md +1 -0
- package/README.md +1 -0
- package/dist/cli.js +0 -0
- package/dist/gen/endpoints/TouchDesignerAPI.js +1 -1
- package/dist/gen/mcp/touchDesignerAPI.zod.js +1 -1
- package/dist/index.js +0 -0
- package/dist/server/touchDesignerServer.js +1 -1
- package/package.json +10 -12
- package/td/genHandlers.js +0 -47
- package/td/import_modules.py +0 -52
- package/td/mcp_webserver_base.tox +0 -0
- package/td/modules/mcp/controllers/__init__.py +0 -9
- package/td/modules/mcp/controllers/api_controller.py +0 -637
- package/td/modules/mcp/controllers/generated_handlers.py +0 -365
- package/td/modules/mcp/controllers/openapi_router.py +0 -265
- package/td/modules/mcp/services/__init__.py +0 -8
- package/td/modules/mcp/services/api_service.py +0 -555
- package/td/modules/mcp_webserver_script.py +0 -134
- package/td/modules/td_server/.dockerignore +0 -72
- package/td/modules/td_server/.openapi-generator/FILES +0 -55
- package/td/modules/td_server/.openapi-generator/VERSION +0 -1
- package/td/modules/td_server/.openapi-generator-ignore +0 -23
- package/td/modules/td_server/.travis.yml +0 -14
- package/td/modules/td_server/Dockerfile +0 -16
- package/td/modules/td_server/README.md +0 -49
- package/td/modules/td_server/git_push.sh +0 -57
- package/td/modules/td_server/openapi_server/__init__.py +0 -0
- package/td/modules/td_server/openapi_server/__main__.py +0 -19
- package/td/modules/td_server/openapi_server/controllers/__init__.py +0 -0
- package/td/modules/td_server/openapi_server/controllers/default_controller.py +0 -162
- package/td/modules/td_server/openapi_server/controllers/security_controller.py +0 -2
- package/td/modules/td_server/openapi_server/encoder.py +0 -19
- package/td/modules/td_server/openapi_server/models/__init__.py +0 -33
- package/td/modules/td_server/openapi_server/models/base_model.py +0 -68
- package/td/modules/td_server/openapi_server/models/create_node200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/create_node200_response_data.py +0 -63
- package/td/modules/td_server/openapi_server/models/create_node_request.py +0 -123
- package/td/modules/td_server/openapi_server/models/delete_node200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/delete_node200_response_data.py +0 -91
- package/td/modules/td_server/openapi_server/models/exec_node_method200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/exec_node_method200_response_data.py +0 -65
- package/td/modules/td_server/openapi_server/models/exec_node_method_request.py +0 -153
- package/td/modules/td_server/openapi_server/models/exec_node_method_request_args_inner.py +0 -34
- package/td/modules/td_server/openapi_server/models/exec_python_script200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/exec_python_script200_response_data.py +0 -65
- package/td/modules/td_server/openapi_server/models/exec_python_script200_response_data_result.py +0 -63
- package/td/modules/td_server/openapi_server/models/exec_python_script_request.py +0 -65
- package/td/modules/td_server/openapi_server/models/get_node_detail200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/get_nodes200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/get_nodes200_response_data.py +0 -65
- package/td/modules/td_server/openapi_server/models/get_td_info200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/get_td_info200_response_data.py +0 -155
- package/td/modules/td_server/openapi_server/models/get_td_python_class_details200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/get_td_python_classes200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/get_td_python_classes200_response_data.py +0 -63
- package/td/modules/td_server/openapi_server/models/td_node.py +0 -175
- package/td/modules/td_server/openapi_server/models/td_node_family_type.py +0 -44
- package/td/modules/td_server/openapi_server/models/td_python_class_details.py +0 -191
- package/td/modules/td_server/openapi_server/models/td_python_class_info.py +0 -127
- package/td/modules/td_server/openapi_server/models/td_python_method_info.py +0 -121
- package/td/modules/td_server/openapi_server/models/td_python_property_info.py +0 -123
- package/td/modules/td_server/openapi_server/models/update_node200_response.py +0 -125
- package/td/modules/td_server/openapi_server/models/update_node200_response_data.py +0 -149
- package/td/modules/td_server/openapi_server/models/update_node200_response_data_failed_inner.py +0 -91
- package/td/modules/td_server/openapi_server/models/update_node_request.py +0 -93
- package/td/modules/td_server/openapi_server/openapi/openapi.yaml +0 -975
- package/td/modules/td_server/openapi_server/test/__init__.py +0 -16
- package/td/modules/td_server/openapi_server/test/test_default_controller.py +0 -201
- package/td/modules/td_server/openapi_server/typing_utils.py +0 -30
- package/td/modules/td_server/openapi_server/util.py +0 -147
- package/td/modules/td_server/requirements.txt +0 -13
- package/td/modules/td_server/setup.py +0 -37
- package/td/modules/td_server/test-requirements.txt +0 -4
- package/td/modules/td_server/tox.ini +0 -11
- package/td/modules/utils/config.py +0 -7
- package/td/modules/utils/error_handling.py +0 -104
- package/td/modules/utils/logging.py +0 -23
- package/td/modules/utils/result.py +0 -40
- package/td/modules/utils/serialization.py +0 -57
- package/td/modules/utils/types.py +0 -33
- package/td/modules/utils/utils_logging.py +0 -60
- package/td/templates/mcp/api_controller_handlers.mustache +0 -63
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TouchDesigner MCP Web Server Serialization Utilities
|
|
3
|
-
Provides JSON serialization functionality for objects
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from typing import Any
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def safe_serialize(obj: Any) -> Any:
|
|
10
|
-
if obj is None:
|
|
11
|
-
return None
|
|
12
|
-
|
|
13
|
-
if hasattr(obj, "__class__") and obj.__class__.__name__ == "Result":
|
|
14
|
-
if hasattr(obj, "success") and hasattr(obj, "data") and hasattr(obj, "error"):
|
|
15
|
-
result_dict = {"success": obj.success}
|
|
16
|
-
if obj.success and obj.data is not None:
|
|
17
|
-
result_dict["data"] = safe_serialize(obj.data)
|
|
18
|
-
elif not obj.success and obj.error is not None:
|
|
19
|
-
result_dict["error"] = str(obj.error)
|
|
20
|
-
return result_dict
|
|
21
|
-
else:
|
|
22
|
-
return str(obj)
|
|
23
|
-
|
|
24
|
-
if isinstance(obj, (int, float, bool, str)):
|
|
25
|
-
return obj
|
|
26
|
-
|
|
27
|
-
if isinstance(obj, (list, tuple)):
|
|
28
|
-
return [safe_serialize(item) for item in obj]
|
|
29
|
-
|
|
30
|
-
if isinstance(obj, dict):
|
|
31
|
-
return {str(k): safe_serialize(v) for k, v in obj.items()}
|
|
32
|
-
|
|
33
|
-
if hasattr(obj, "eval") and callable(getattr(obj, "eval")):
|
|
34
|
-
try:
|
|
35
|
-
val = obj.eval()
|
|
36
|
-
if hasattr(val, "path") and callable(getattr(val, "path", None)):
|
|
37
|
-
return val.path
|
|
38
|
-
return val
|
|
39
|
-
except:
|
|
40
|
-
return str(obj)
|
|
41
|
-
|
|
42
|
-
if hasattr(obj, "path") and callable(getattr(obj, "path", None)):
|
|
43
|
-
return obj.path
|
|
44
|
-
|
|
45
|
-
if hasattr(obj, "__class__") and obj.__class__.__name__ == "Page":
|
|
46
|
-
return f"Page:{obj.name}" if hasattr(obj, "name") else str(obj)
|
|
47
|
-
|
|
48
|
-
if hasattr(obj, "__dict__"):
|
|
49
|
-
try:
|
|
50
|
-
serialized_dict = {}
|
|
51
|
-
for k, v in obj.__dict__.items():
|
|
52
|
-
serialized_dict[k] = safe_serialize(v)
|
|
53
|
-
return serialized_dict
|
|
54
|
-
except:
|
|
55
|
-
return str(obj)
|
|
56
|
-
|
|
57
|
-
return str(obj)
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Type definitions module for TouchDesigner MCP Web server
|
|
3
|
-
Defines Result and APIResponse types
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from typing import Any, Dict, TypedDict
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class Result(TypedDict, total=False):
|
|
10
|
-
"""Type representing operation results (equivalent to TypeScript Result pattern)"""
|
|
11
|
-
|
|
12
|
-
success: bool
|
|
13
|
-
data: Any # Data when successful
|
|
14
|
-
error: Any # Error information when failed
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class APIResponse(TypedDict, total=False):
|
|
18
|
-
"""Type representing API responses"""
|
|
19
|
-
|
|
20
|
-
statusCode: int
|
|
21
|
-
statusReason: str
|
|
22
|
-
data: str # JSON string
|
|
23
|
-
content_type: str
|
|
24
|
-
headers: Dict[str, str]
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class LogLevel:
|
|
28
|
-
"""Log level definitions"""
|
|
29
|
-
|
|
30
|
-
DEBUG = "DEBUG"
|
|
31
|
-
INFO = "INFO"
|
|
32
|
-
WARNING = "WARNING"
|
|
33
|
-
ERROR = "ERROR"
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import traceback
|
|
2
|
-
from enum import Enum
|
|
3
|
-
from typing import Optional, Union
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class LogLevel(Enum):
|
|
7
|
-
|
|
8
|
-
DEBUG = 0
|
|
9
|
-
INFO = 1
|
|
10
|
-
WARNING = 2
|
|
11
|
-
ERROR = 3
|
|
12
|
-
|
|
13
|
-
@classmethod
|
|
14
|
-
def from_string(cls, level_str: str) -> "LogLevel":
|
|
15
|
-
level_map = {
|
|
16
|
-
"DEBUG": cls.DEBUG,
|
|
17
|
-
"INFO": cls.INFO,
|
|
18
|
-
"WARNING": cls.WARNING,
|
|
19
|
-
"ERROR": cls.ERROR,
|
|
20
|
-
}
|
|
21
|
-
return level_map.get(level_str.upper(), cls.INFO)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class Logger:
|
|
25
|
-
|
|
26
|
-
def __init__(self, min_level: LogLevel = LogLevel.INFO):
|
|
27
|
-
self.min_level = min_level
|
|
28
|
-
|
|
29
|
-
def log(
|
|
30
|
-
self,
|
|
31
|
-
message: str,
|
|
32
|
-
level: Union[LogLevel, str] = LogLevel.INFO,
|
|
33
|
-
exception: Optional[Exception] = None,
|
|
34
|
-
):
|
|
35
|
-
if isinstance(level, str):
|
|
36
|
-
level = LogLevel.from_string(level)
|
|
37
|
-
|
|
38
|
-
if level.value < self.min_level.value:
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
prefix = f"[{level.name}]"
|
|
42
|
-
print(f"{prefix} {message}")
|
|
43
|
-
|
|
44
|
-
if exception and level.value >= LogLevel.ERROR.value:
|
|
45
|
-
print(traceback.format_exc())
|
|
46
|
-
|
|
47
|
-
def debug(self, message: str):
|
|
48
|
-
self.log(message, LogLevel.DEBUG)
|
|
49
|
-
|
|
50
|
-
def info(self, message: str):
|
|
51
|
-
self.log(message, LogLevel.INFO)
|
|
52
|
-
|
|
53
|
-
def warning(self, message: str):
|
|
54
|
-
self.log(message, LogLevel.WARNING)
|
|
55
|
-
|
|
56
|
-
def error(self, message: str, exception: Optional[Exception] = None):
|
|
57
|
-
self.log(message, LogLevel.ERROR, exception)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
logger = Logger()
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# Auto-generated MCP handlers
|
|
2
|
-
import json
|
|
3
|
-
import inspect
|
|
4
|
-
import re
|
|
5
|
-
from utils.types import Result
|
|
6
|
-
from utils.result import error_result
|
|
7
|
-
|
|
8
|
-
# Service instance singleton pattern
|
|
9
|
-
_api_service_instance = None
|
|
10
|
-
|
|
11
|
-
def get_api_service():
|
|
12
|
-
global _api_service_instance
|
|
13
|
-
if _api_service_instance is None:
|
|
14
|
-
from mcp.services.api_service import api_service
|
|
15
|
-
_api_service_instance = api_service
|
|
16
|
-
return _api_service_instance
|
|
17
|
-
|
|
18
|
-
def camel_to_snake(name):
|
|
19
|
-
"""Convert camelCase to snake_case"""
|
|
20
|
-
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
|
|
21
|
-
return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower()
|
|
22
|
-
|
|
23
|
-
{{#operations}}
|
|
24
|
-
def {{operationId}}(body: str = None, **kwargs) -> Result:
|
|
25
|
-
"""
|
|
26
|
-
Auto-generated handler for operation: {{operationId}}
|
|
27
|
-
"""
|
|
28
|
-
try:
|
|
29
|
-
print(f"[DEBUG] Handler '{{operationId}}' called with body: {body}, kwargs: {kwargs}")
|
|
30
|
-
service_method = getattr(get_api_service(), "{{operationId}}", None)
|
|
31
|
-
if not callable(service_method):
|
|
32
|
-
return error_result("Service method '{{operationId}}' not implemented")
|
|
33
|
-
|
|
34
|
-
# Merge body
|
|
35
|
-
if body:
|
|
36
|
-
try:
|
|
37
|
-
parsed_body = json.loads(body)
|
|
38
|
-
kwargs.update(parsed_body)
|
|
39
|
-
except Exception as e:
|
|
40
|
-
return error_result(f"Invalid JSON body: {str(e)}")
|
|
41
|
-
|
|
42
|
-
# CamelCase → SnakeCase 変換
|
|
43
|
-
kwargs_snake_case = {camel_to_snake(k): v for k, v in kwargs.items()}
|
|
44
|
-
|
|
45
|
-
sig = inspect.signature(service_method)
|
|
46
|
-
|
|
47
|
-
# Prepare args matching the function signature
|
|
48
|
-
call_args = {}
|
|
49
|
-
for param_name in sig.parameters:
|
|
50
|
-
if param_name in kwargs_snake_case:
|
|
51
|
-
call_args[param_name] = kwargs_snake_case[param_name]
|
|
52
|
-
|
|
53
|
-
return service_method(**call_args)
|
|
54
|
-
|
|
55
|
-
except Exception as e:
|
|
56
|
-
return error_result(f"Handler for '{{operationId}}' failed: {str(e)}")
|
|
57
|
-
{{/operations}}
|
|
58
|
-
|
|
59
|
-
__all__ = [
|
|
60
|
-
{{#operations}}
|
|
61
|
-
"{{operationId}}",
|
|
62
|
-
{{/operations}}
|
|
63
|
-
]
|