mseep-lightfast-mcp 0.0.1__py3-none-any.whl

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 (43) hide show
  1. common/__init__.py +21 -0
  2. common/types.py +182 -0
  3. lightfast_mcp/__init__.py +50 -0
  4. lightfast_mcp/core/__init__.py +14 -0
  5. lightfast_mcp/core/base_server.py +205 -0
  6. lightfast_mcp/exceptions.py +55 -0
  7. lightfast_mcp/servers/__init__.py +1 -0
  8. lightfast_mcp/servers/blender/__init__.py +5 -0
  9. lightfast_mcp/servers/blender/server.py +358 -0
  10. lightfast_mcp/servers/blender_mcp_server.py +82 -0
  11. lightfast_mcp/servers/mock/__init__.py +5 -0
  12. lightfast_mcp/servers/mock/server.py +101 -0
  13. lightfast_mcp/servers/mock/tools.py +161 -0
  14. lightfast_mcp/servers/mock_server.py +78 -0
  15. lightfast_mcp/utils/__init__.py +1 -0
  16. lightfast_mcp/utils/logging_utils.py +69 -0
  17. mseep_lightfast_mcp-0.0.1.dist-info/METADATA +36 -0
  18. mseep_lightfast_mcp-0.0.1.dist-info/RECORD +43 -0
  19. mseep_lightfast_mcp-0.0.1.dist-info/WHEEL +5 -0
  20. mseep_lightfast_mcp-0.0.1.dist-info/entry_points.txt +7 -0
  21. mseep_lightfast_mcp-0.0.1.dist-info/licenses/LICENSE +21 -0
  22. mseep_lightfast_mcp-0.0.1.dist-info/top_level.txt +3 -0
  23. tools/__init__.py +46 -0
  24. tools/ai/__init__.py +8 -0
  25. tools/ai/conversation_cli.py +345 -0
  26. tools/ai/conversation_client.py +399 -0
  27. tools/ai/conversation_session.py +342 -0
  28. tools/ai/providers/__init__.py +11 -0
  29. tools/ai/providers/base_provider.py +64 -0
  30. tools/ai/providers/claude_provider.py +200 -0
  31. tools/ai/providers/openai_provider.py +204 -0
  32. tools/ai/tool_executor.py +257 -0
  33. tools/common/__init__.py +99 -0
  34. tools/common/async_utils.py +419 -0
  35. tools/common/errors.py +222 -0
  36. tools/common/logging.py +252 -0
  37. tools/common/types.py +130 -0
  38. tools/orchestration/__init__.py +15 -0
  39. tools/orchestration/cli.py +320 -0
  40. tools/orchestration/config_loader.py +348 -0
  41. tools/orchestration/server_orchestrator.py +466 -0
  42. tools/orchestration/server_registry.py +187 -0
  43. tools/orchestration/server_selector.py +242 -0
@@ -0,0 +1,161 @@
1
+ """
2
+ Tool functions for the Mock MCP server.
3
+
4
+ These functions implement the actual tools that can be called via the MCP protocol.
5
+ """
6
+
7
+ import asyncio
8
+ import json
9
+ import time
10
+ from typing import Any
11
+
12
+ from fastmcp import Context
13
+
14
+ from ...utils.logging_utils import get_logger
15
+
16
+ logger = get_logger("MockTools")
17
+
18
+ # Global reference to current server instance for tools to access configuration
19
+ _current_server = None
20
+
21
+
22
+ def set_current_server(server):
23
+ """Set the current server instance for tools to access."""
24
+ global _current_server
25
+ _current_server = server
26
+
27
+
28
+ async def get_server_status(ctx: Context) -> dict[str, Any]:
29
+ """
30
+ Get the current status of the mock MCP server.
31
+ """
32
+ logger.info("Received request for server status.")
33
+ await asyncio.sleep(0.1) # Simulate a very small delay
34
+
35
+ if _current_server and hasattr(_current_server, "mcp") and _current_server.mcp:
36
+ server_name = _current_server.mcp.name
37
+ config_name = _current_server.config.name
38
+ description = _current_server.config.description
39
+ version = _current_server.SERVER_VERSION
40
+ server_info = getattr(_current_server, "info", None)
41
+ tools_count = len(
42
+ server_info.tools if server_info and hasattr(server_info, "tools") else []
43
+ )
44
+ else:
45
+ # Fallback for testing
46
+ server_name = "test-mock"
47
+ config_name = "test-mock"
48
+ description = "Mock MCP Server for testing"
49
+ version = "1.0.0"
50
+ tools_count = 3
51
+
52
+ return {
53
+ "status": "running",
54
+ "server_name": server_name,
55
+ "config_name": config_name,
56
+ "server_type": "mock",
57
+ "version": version,
58
+ "description": description,
59
+ "timestamp": time.time(),
60
+ "tools_available": tools_count,
61
+ "uptime_seconds": time.time()
62
+ - getattr(_current_server, "_start_time", time.time())
63
+ if _current_server
64
+ else 0,
65
+ }
66
+
67
+
68
+ async def fetch_mock_data(
69
+ ctx: Context, data_id: str, delay_seconds: float | None = None
70
+ ) -> dict[str, Any]:
71
+ """
72
+ Fetches mock data associated with a given ID after a specified delay.
73
+
74
+ Parameters:
75
+ - data_id: The identifier for the mock data to fetch.
76
+ - delay_seconds: The time in seconds to wait before returning the data.
77
+ """
78
+ default_delay = 0.5
79
+ if _current_server and hasattr(_current_server, "default_delay"):
80
+ default_delay = _current_server.default_delay
81
+
82
+ if delay_seconds is None:
83
+ delay_seconds = default_delay
84
+
85
+ logger.info(
86
+ f"Received request to fetch mock data for id: '{data_id}' with delay: {delay_seconds}s."
87
+ )
88
+ await asyncio.sleep(delay_seconds)
89
+
90
+ server_name = "mock-server"
91
+ if _current_server and hasattr(_current_server, "config"):
92
+ server_name = _current_server.config.name
93
+
94
+ mock_data = {
95
+ "id": data_id,
96
+ "content": f"This is mock content for {data_id}.",
97
+ "details": {
98
+ "field1": "value1",
99
+ "field2": 123,
100
+ "is_mock": True,
101
+ "server_name": server_name,
102
+ },
103
+ "retrieved_at": time.time(),
104
+ "delay_used": delay_seconds,
105
+ }
106
+
107
+ logger.info(f"Returning mock data for id: '{data_id}'.")
108
+ return mock_data
109
+
110
+
111
+ async def execute_mock_action(
112
+ ctx: Context,
113
+ action_name: str,
114
+ parameters: dict[str, Any] | None = None,
115
+ delay_seconds: float | None = None,
116
+ ) -> dict[str, Any]:
117
+ """
118
+ Simulates the execution of an action with given parameters after a specified delay.
119
+
120
+ Parameters:
121
+ - action_name: The name of the mock action to execute.
122
+ - parameters: A dictionary of parameters for the action.
123
+ - delay_seconds: The time in seconds to wait before returning the action result.
124
+ """
125
+ if parameters is None:
126
+ parameters = {}
127
+
128
+ default_delay = 0.5
129
+ if _current_server and hasattr(_current_server, "default_delay"):
130
+ default_delay = _current_server.default_delay
131
+
132
+ if delay_seconds is None:
133
+ delay_seconds = default_delay
134
+
135
+ logger.info(
136
+ f"Received request to execute mock action: '{action_name}' with params: "
137
+ f"{json.dumps(parameters)} and delay: {delay_seconds}s."
138
+ )
139
+
140
+ await asyncio.sleep(delay_seconds)
141
+
142
+ server_name = "mock-server"
143
+ if _current_server and hasattr(_current_server, "config"):
144
+ server_name = _current_server.config.name
145
+
146
+ result = {
147
+ "action_name": action_name,
148
+ "status": "completed_mock",
149
+ "parameters_received": parameters,
150
+ "message": f"Mock action '{action_name}' executed successfully on {server_name}.",
151
+ "completed_at": time.time(),
152
+ "delay_used": delay_seconds,
153
+ "server_info": {
154
+ "name": server_name,
155
+ "type": "mock",
156
+ "version": "1.0.0",
157
+ },
158
+ }
159
+
160
+ logger.info(f"Returning result for mock action: '{action_name}'.")
161
+ return result
@@ -0,0 +1,78 @@
1
+ """
2
+ Mock MCP server using the new modular architecture.
3
+ This is now the clean entry point for the Mock server.
4
+ """
5
+
6
+ import json
7
+ import os
8
+
9
+ from ..core.base_server import ServerConfig
10
+ from ..utils.logging_utils import configure_logging, get_logger
11
+ from .mock.server import MockMCPServer
12
+
13
+ # Configure logging
14
+ configure_logging(level="INFO")
15
+ logger = get_logger("MockMCP")
16
+
17
+ SERVER_NAME = "MockMCP"
18
+
19
+
20
+ def main():
21
+ """Run the Mock MCP server."""
22
+ logger.info("Starting Mock MCP server")
23
+
24
+ # Check for environment configuration (from ServerOrchestrator)
25
+ env_config = os.getenv("LIGHTFAST_MCP_SERVER_CONFIG")
26
+
27
+ if env_config:
28
+ try:
29
+ # Parse configuration from environment
30
+ config_data = json.loads(env_config)
31
+ config = ServerConfig(
32
+ name=config_data.get("name", SERVER_NAME),
33
+ description=config_data.get(
34
+ "description", "Mock MCP Server for testing and development"
35
+ ),
36
+ host=config_data.get("host", "localhost"),
37
+ port=config_data.get("port", 8000),
38
+ transport=config_data.get(
39
+ "transport", "streamable-http"
40
+ ), # Default to HTTP for subprocess
41
+ path=config_data.get("path", "/mcp"),
42
+ config=config_data.get(
43
+ "config", {"type": "mock", "delay_seconds": 0.5}
44
+ ),
45
+ )
46
+ logger.info(
47
+ f"Using environment configuration: {config.transport}://{config.host}:{config.port}"
48
+ )
49
+ except (json.JSONDecodeError, KeyError) as e:
50
+ logger.warning(f"Invalid environment configuration: {e}, using defaults")
51
+ config = _get_default_config()
52
+ else:
53
+ # Use default configuration for standalone running
54
+ config = _get_default_config()
55
+
56
+ # Create and run server
57
+ server = MockMCPServer(config)
58
+ server.run()
59
+
60
+
61
+ def _get_default_config() -> ServerConfig:
62
+ """Get default configuration for standalone running."""
63
+ return ServerConfig(
64
+ name=SERVER_NAME,
65
+ description="Mock MCP Server for testing and development",
66
+ host="localhost",
67
+ port=8002, # Use port 8002 by default for mock server
68
+ transport="streamable-http", # Use HTTP by default for easier testing
69
+ path="/mcp",
70
+ config={
71
+ "type": "mock",
72
+ "delay_seconds": 0.5,
73
+ },
74
+ )
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()
@@ -0,0 +1 @@
1
+ # This file makes 'utils' a Python package.
@@ -0,0 +1,69 @@
1
+ """Logging utilities for FastMCP."""
2
+
3
+ import logging
4
+ from typing import Literal
5
+
6
+ from rich.console import Console
7
+ from rich.logging import RichHandler
8
+
9
+
10
+ def get_logger(name: str) -> logging.Logger:
11
+ """Get a logger nested under FastMCP namespace.
12
+
13
+ Args:
14
+ name: the name of the logger, which will be prefixed with 'FastMCP.'
15
+
16
+ Returns:
17
+ a configured logger instance
18
+ """
19
+ return logging.getLogger(f"FastMCP.{name}")
20
+
21
+
22
+ def configure_logging(
23
+ level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] | int = "INFO",
24
+ logger: logging.Logger | None = None,
25
+ ) -> None:
26
+ """
27
+ Configure logging for FastMCP.
28
+
29
+ Args:
30
+ logger: the logger to configure
31
+ level: the log level to use
32
+ """
33
+ if logger is None:
34
+ # If no specific logger is passed, configure the root "FastMCP" logger.
35
+ # Child loggers created with get_logger() will inherit this configuration.
36
+ logger = logging.getLogger("FastMCP")
37
+
38
+ # Set the level for the logger we are configuring.
39
+ # This ensures that even if child loggers are created before this call,
40
+ # they will respect this base level if they don't override it.
41
+ logger.setLevel(level)
42
+
43
+ # Configure the handler specifically for the logger instance being passed or the root "FastMCP" logger.
44
+ # Avoid adding handlers to the root logger of Python's logging system unless intended.
45
+ handler = RichHandler(
46
+ console=Console(stderr=True), rich_tracebacks=True, show_path=False
47
+ )
48
+ # Using a simple formatter as RichHandler does most of the styling.
49
+ # The default RichHandler format is "%(message)s" and it includes time and level.
50
+ # formatter = logging.Formatter("%(message)s")
51
+ # handler.setFormatter(formatter) # Not strictly necessary if RichHandler default is fine
52
+
53
+ # Remove any existing handlers from THIS logger to avoid duplicates on reconfiguration.
54
+ # This is important if configure_logging can be called multiple times.
55
+ for hdlr in logger.handlers[:]:
56
+ logger.removeHandler(hdlr)
57
+
58
+ logger.addHandler(handler)
59
+
60
+ # Ensure that messages propagate up to the root "FastMCP" logger if this is a child logger.
61
+ # And ensure the root "FastMCP" logger doesn't propagate to Python's root logger
62
+ # if we only want RichHandler on "FastMCP" namespace.
63
+ if logger.name != "FastMCP":
64
+ logger.propagate = True # Default, but good to be aware of
65
+ else:
66
+ # For the root "FastMCP" logger, decide if it should propagate to Python's root.
67
+ # If Python's root has handlers (e.g. from basicConfig elsewhere), you might get duplicates.
68
+ # Setting propagate to False for "FastMCP" means only RichHandler will handle its logs.
69
+ logger.propagate = False
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.4
2
+ Name: mseep-lightfast-mcp
3
+ Version: 0.0.1
4
+ Summary: MCP server implementations for creative applications (Blender, etc.)
5
+ Author-email: mseep <support@skydeck.ai>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/lightfastai/lightfast-mcp
8
+ Project-URL: Bug Tracker, https://github.com/lightfastai/lightfast-mcp/issues
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Operating System :: OS Independent
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/plain
17
+ License-File: LICENSE
18
+ Requires-Dist: fastmcp>=2.0.0
19
+ Requires-Dist: rich
20
+ Requires-Dist: pyyaml
21
+ Requires-Dist: anthropic
22
+ Requires-Dist: openai
23
+ Requires-Dist: typer
24
+ Provides-Extra: dev
25
+ Requires-Dist: ruff; extra == "dev"
26
+ Requires-Dist: taskipy; extra == "dev"
27
+ Requires-Dist: pytest; extra == "dev"
28
+ Requires-Dist: pytest-asyncio; extra == "dev"
29
+ Requires-Dist: pytest-cov; extra == "dev"
30
+ Requires-Dist: coverage; extra == "dev"
31
+ Requires-Dist: nox; extra == "dev"
32
+ Requires-Dist: mypy; extra == "dev"
33
+ Requires-Dist: build; extra == "dev"
34
+ Dynamic: license-file
35
+
36
+ Package managed by MseeP.ai
@@ -0,0 +1,43 @@
1
+ common/__init__.py,sha256=wN-w27w5gXHXkHfVgShEKyJhMWVukCi2AeQa5j_QksA,372
2
+ common/types.py,sha256=HbSRCUMd5Red-XXdNzxaNqgC66PBiJySxnzpyelN8uw,4992
3
+ lightfast_mcp/__init__.py,sha256=QLNMWnqqLjuwtZy82RNZX0Kz-lxR2xtuxwzmYPZ1wws,1439
4
+ lightfast_mcp/exceptions.py,sha256=Ylq6umzYIxc4fqlpOBNcR9X76Jpc20IQP36e_8qjHjo,1274
5
+ lightfast_mcp/core/__init__.py,sha256=9uyaKzqPD_MkH_EYHTrZuC9g7iwGfqDl99iZ4NNGvMs,318
6
+ lightfast_mcp/core/base_server.py,sha256=O-DUgkcgvZgn4j67jyM7cX2NUGn0lEvkmprIHMhFR4U,7078
7
+ lightfast_mcp/servers/__init__.py,sha256=m8uQ9HUARdYcDupHSjscj_El8G_juzFDZXY5RmNO-pU,60
8
+ lightfast_mcp/servers/blender_mcp_server.py,sha256=v-94S9TGKME3HZatAfXjhoaDG-1FMVLMWzw5owGr8EE,2707
9
+ lightfast_mcp/servers/mock_server.py,sha256=G-1FYQjOsppy06hJHTgMcL2BpEeJ02CXKXpfbqK9IxY,2501
10
+ lightfast_mcp/servers/blender/__init__.py,sha256=XinY6nr6bsb5fHsfKZ4YhtNdtcoORXy8nnbUFbdMDUc,103
11
+ lightfast_mcp/servers/blender/server.py,sha256=QVP3kPvvdmw3Gg0cPYTg5RdC5mQLqy7_55_38bHvfvk,12099
12
+ lightfast_mcp/servers/mock/__init__.py,sha256=4huBgNiQrN3_aV6d3MZqeVE9A1WQBwURmswJC7cdBZ0,94
13
+ lightfast_mcp/servers/mock/server.py,sha256=zMxcClTfhi3hckvpHSOf_cTl6aSTrEC9qaQkIpmMgOQ,3271
14
+ lightfast_mcp/servers/mock/tools.py,sha256=1obQXq4KH3jQ1va7t14TExV0xXrusfCuH-pyDqnR0TA,4884
15
+ lightfast_mcp/utils/__init__.py,sha256=X1MkpWIRxOfTQVma5j7cKftMcy3e5sr7bccoE0vb91c,44
16
+ lightfast_mcp/utils/logging_utils.py,sha256=BX4gQ-foeJ71JaFUMt1MyAf76MleCnlWI3WMDrJGOf4,2756
17
+ mseep_lightfast_mcp-0.0.1.dist-info/licenses/LICENSE,sha256=F4vfMqNpXJNbT7M7GjiaPKktILSa7MzDQ9kB46jqpP4,1066
18
+ tools/__init__.py,sha256=KzA5Q-K5TyC2ZvTIumQuTlcBf4bvyuJfEICGZnTRwPw,1189
19
+ tools/ai/__init__.py,sha256=31XxLKEg-h69xz_sKqt3Yo_X7ijrtBJQjL4L5blmSVY,214
20
+ tools/ai/conversation_cli.py,sha256=AFXbaTewrhX6r7PtqBscMlYmkfWx7ozBLn-CLZVV7LQ,11674
21
+ tools/ai/conversation_client.py,sha256=tRxfs_Xpy0N63EZ_vyHSqV26jt-O0aTIzovXnek5tuo,14904
22
+ tools/ai/conversation_session.py,sha256=JcOUX-dxbKhtCuUXjCB9LZZMHwXbQY7zFj5a9cKomck,12372
23
+ tools/ai/tool_executor.py,sha256=Hn_yGgliVt-YCHNfVTX6ECmdGVhFmV18RNSfJXUp7po,9291
24
+ tools/ai/providers/__init__.py,sha256=vuU7vcV8vcSiMGDpg8HRjaRGBUtKOpH_JTbghhKrQUg,270
25
+ tools/ai/providers/base_provider.py,sha256=h3ANMzLZjdEEOqxHI2mgP447GUa4OYvWZcEShv43a5E,1774
26
+ tools/ai/providers/claude_provider.py,sha256=ruLRLDVNpdcUz7VRiKZdDdaEATe0ZOkCzAzR6ihHpvY,7510
27
+ tools/ai/providers/openai_provider.py,sha256=0izmr3dcTWUW5BnTqxNZkA72dWWUDhqM_lH5k4qZrE4,7394
28
+ tools/common/__init__.py,sha256=yOHjgLvPK_Yx10TQp79jVPyB84YJCFjH7zhYSpR33ig,2079
29
+ tools/common/async_utils.py,sha256=WT43Lw9hOEuNbRzRwGZV1jQppnYpdKa-DD4NM5KdweA,15520
30
+ tools/common/errors.py,sha256=j7LgwXJCeM-VvyrQgKa4PGqVu36O44dxSpn3Ca4GCsg,5659
31
+ tools/common/logging.py,sha256=siuAuC2OUKmVa0INWxZZpjTGMHVzfKSZH2lZ54BX-Q4,8364
32
+ tools/common/types.py,sha256=C7SwZWCM115ZxpbuSrrIYQCjWad2_8QZWtUGmzBxtP4,4045
33
+ tools/orchestration/__init__.py,sha256=znI_R1EcCun6_qbkqNaHphEjxUYD7Haayng2uf42aKg,402
34
+ tools/orchestration/cli.py,sha256=a1dIaiHYLTwIT5p7_EUdOoqn4Bj-6BUkb6uoZ0r3wA4,10576
35
+ tools/orchestration/config_loader.py,sha256=rzMZXytxPpiuQhBlz6VBkcX9IyhUIt8nuvWxkp5B0wE,12684
36
+ tools/orchestration/server_orchestrator.py,sha256=ZdqSMkZ8Bx8U6U3wqYWFy7LK30MTNfISSDW693FIpe4,17478
37
+ tools/orchestration/server_registry.py,sha256=piANwfafXDJ-zuOjCNRJACetr6_lZrB_Qc1BXDVaIgo,7119
38
+ tools/orchestration/server_selector.py,sha256=8eHs59e7rhNNWUkgMjZwPxodKnej6EGYE3vJJ99rGcA,9001
39
+ mseep_lightfast_mcp-0.0.1.dist-info/METADATA,sha256=n8uLOk1zJBh1Ye2sB5e06g0VVspfKdVDjv12Q2uwTg0,1294
40
+ mseep_lightfast_mcp-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
41
+ mseep_lightfast_mcp-0.0.1.dist-info/entry_points.txt,sha256=EF8QP2Lbm_H_MFR0Q3dDHi-alNcPiFfIVJdck225yHg,392
42
+ mseep_lightfast_mcp-0.0.1.dist-info/top_level.txt,sha256=-ZI_xMvvDtxXIaiKOLV8pLB9FMRuWecaUl1eWefmOzg,27
43
+ mseep_lightfast_mcp-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,7 @@
1
+ [console_scripts]
2
+ lightfast-blender = lightfast_mcp.servers.blender.server:main
3
+ lightfast-blender-server = lightfast_mcp.servers.blender_mcp_server:main
4
+ lightfast-conversation-client = tools.ai.conversation_cli:app
5
+ lightfast-mcp-orchestrator = tools.orchestration.cli:main
6
+ lightfast-mock = lightfast_mcp.servers.mock.server:main
7
+ lightfast-mock-server = lightfast_mcp.servers.mock_server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Lightfast
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ common
2
+ lightfast_mcp
3
+ tools
tools/__init__.py ADDED
@@ -0,0 +1,46 @@
1
+ """
2
+ Development tools for lightfast-mcp.
3
+
4
+ This package contains development and testing tools that are useful for
5
+ multi-server coordination and AI integration, but are not part of the
6
+ core MCP server implementations.
7
+
8
+ Core MCP servers are in the lightfast_mcp package.
9
+ Development tools are in this tools package.
10
+
11
+ ## Architecture
12
+ - tools.orchestration.ServerOrchestrator: Advanced server management
13
+ - tools.ai.ConversationClient: Modern AI conversation handling
14
+ - tools.common: Shared utilities, types, and error handling
15
+ """
16
+
17
+ # Import submodules to make them available for patching in tests
18
+ from . import ai, common, orchestration
19
+
20
+ # New architecture
21
+ from .ai import ConversationClient, create_conversation_client
22
+ from .orchestration import (
23
+ ConfigLoader,
24
+ ServerOrchestrator,
25
+ ServerRegistry,
26
+ ServerSelector,
27
+ get_orchestrator,
28
+ get_registry,
29
+ )
30
+
31
+ __all__ = [
32
+ # Submodules (for test patching)
33
+ "ai",
34
+ "common",
35
+ "orchestration",
36
+ # Orchestration
37
+ "ConfigLoader",
38
+ "ServerOrchestrator",
39
+ "ServerRegistry",
40
+ "ServerSelector",
41
+ "get_orchestrator",
42
+ "get_registry",
43
+ # AI
44
+ "ConversationClient",
45
+ "create_conversation_client",
46
+ ]
tools/ai/__init__.py ADDED
@@ -0,0 +1,8 @@
1
+ """AI integration tools for multi-server coordination."""
2
+
3
+ from .conversation_client import ConversationClient, create_conversation_client
4
+
5
+ __all__ = [
6
+ "ConversationClient",
7
+ "create_conversation_client",
8
+ ]