hanzo-mcp 0.8.2__py3-none-any.whl → 0.8.4__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.
Potentially problematic release.
This version of hanzo-mcp might be problematic. Click here for more details.
- hanzo_mcp/__init__.py +15 -2
- hanzo_mcp/bridge.py +133 -127
- hanzo_mcp/cli.py +45 -21
- hanzo_mcp/compute_nodes.py +68 -55
- hanzo_mcp/config/settings.py +11 -0
- hanzo_mcp/core/base_agent.py +520 -0
- hanzo_mcp/core/model_registry.py +436 -0
- hanzo_mcp/dev_server.py +3 -2
- hanzo_mcp/server.py +4 -1
- hanzo_mcp/tools/__init__.py +61 -46
- hanzo_mcp/tools/agent/__init__.py +63 -52
- hanzo_mcp/tools/agent/agent_tool.py +12 -1
- hanzo_mcp/tools/agent/cli_tools.py +543 -0
- hanzo_mcp/tools/agent/network_tool.py +11 -55
- hanzo_mcp/tools/agent/unified_cli_tools.py +259 -0
- hanzo_mcp/tools/common/batch_tool.py +2 -0
- hanzo_mcp/tools/common/context.py +3 -1
- hanzo_mcp/tools/config/config_tool.py +121 -9
- hanzo_mcp/tools/filesystem/__init__.py +18 -0
- hanzo_mcp/tools/llm/__init__.py +44 -16
- hanzo_mcp/tools/llm/llm_tool.py +13 -0
- hanzo_mcp/tools/llm/llm_unified.py +911 -0
- hanzo_mcp/tools/shell/__init__.py +7 -1
- hanzo_mcp/tools/shell/auto_background.py +24 -0
- hanzo_mcp/tools/shell/bash_tool.py +14 -28
- hanzo_mcp/tools/shell/zsh_tool.py +266 -0
- hanzo_mcp-0.8.4.dist-info/METADATA +411 -0
- {hanzo_mcp-0.8.2.dist-info → hanzo_mcp-0.8.4.dist-info}/RECORD +31 -25
- hanzo_mcp-0.8.2.dist-info/METADATA +0 -526
- {hanzo_mcp-0.8.2.dist-info → hanzo_mcp-0.8.4.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.8.2.dist-info → hanzo_mcp-0.8.4.dist-info}/entry_points.txt +0 -0
- {hanzo_mcp-0.8.2.dist-info → hanzo_mcp-0.8.4.dist-info}/top_level.txt +0 -0
hanzo_mcp/__init__.py
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
"""Hanzo AI - Implementation of Hanzo capabilities using MCP."""
|
|
2
2
|
|
|
3
|
+
# Polyfill typing.override for Python < 3.12
|
|
4
|
+
try: # pragma: no cover
|
|
5
|
+
from typing import override as _override # type: ignore
|
|
6
|
+
except Exception: # pragma: no cover
|
|
7
|
+
import typing as _typing
|
|
8
|
+
|
|
9
|
+
def override(obj): # type: ignore
|
|
10
|
+
return obj
|
|
11
|
+
|
|
12
|
+
_typing.override = override # type: ignore[attr-defined]
|
|
13
|
+
|
|
3
14
|
# Configure FastMCP logging globally for stdio transport
|
|
4
15
|
import os
|
|
5
16
|
import warnings
|
|
6
17
|
|
|
7
18
|
# Suppress litellm deprecation warnings about event loop
|
|
8
|
-
warnings.filterwarnings(
|
|
19
|
+
warnings.filterwarnings(
|
|
20
|
+
"ignore", message="There is no current event loop", category=DeprecationWarning
|
|
21
|
+
)
|
|
9
22
|
|
|
10
23
|
if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
|
|
11
24
|
try:
|
|
@@ -15,4 +28,4 @@ if os.environ.get("HANZO_MCP_TRANSPORT") == "stdio":
|
|
|
15
28
|
except ImportError:
|
|
16
29
|
pass
|
|
17
30
|
|
|
18
|
-
__version__ = "0.
|
|
31
|
+
__version__ = "0.8.4"
|
hanzo_mcp/bridge.py
CHANGED
|
@@ -4,21 +4,21 @@ This module provides MCP server functionality that allows Claude instances
|
|
|
4
4
|
to communicate with each other, enabling peer-to-peer agent networks.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
import argparse
|
|
8
|
-
import asyncio
|
|
9
|
-
import json
|
|
10
|
-
import logging
|
|
11
7
|
import os
|
|
12
8
|
import sys
|
|
9
|
+
import json
|
|
10
|
+
import asyncio
|
|
11
|
+
import logging
|
|
12
|
+
import argparse
|
|
13
13
|
from typing import Any, Dict, List, Optional
|
|
14
|
-
from dataclasses import
|
|
14
|
+
from dataclasses import asdict, dataclass
|
|
15
15
|
|
|
16
16
|
import mcp.server.fastmcp as mcp
|
|
17
17
|
from mcp import tool
|
|
18
|
-
from mcp.
|
|
19
|
-
from mcp.server.models import InitializationOptions
|
|
18
|
+
from mcp.types import INTERNAL_ERROR, Tool, TextContent
|
|
20
19
|
from mcp.server.stdio import stdio_server
|
|
21
|
-
from mcp.
|
|
20
|
+
from mcp.server.models import InitializationOptions
|
|
21
|
+
from mcp.server.fastmcp import FastMCP
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
@@ -26,213 +26,212 @@ logger = logging.getLogger(__name__)
|
|
|
26
26
|
@dataclass
|
|
27
27
|
class BridgeConfig:
|
|
28
28
|
"""Configuration for MCP bridge."""
|
|
29
|
+
|
|
29
30
|
target_port: int
|
|
30
31
|
instance_id: int
|
|
31
32
|
role: str
|
|
32
33
|
source_instance: Optional[int] = None
|
|
33
34
|
target_instance: Optional[int] = None
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
|
|
36
|
+
|
|
36
37
|
class ClaudeBridge(FastMCP):
|
|
37
38
|
"""MCP Bridge server for Claude-to-Claude communication."""
|
|
38
|
-
|
|
39
|
+
|
|
39
40
|
def __init__(self, config: BridgeConfig):
|
|
40
41
|
"""Initialize the bridge.
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
Args:
|
|
43
44
|
config: Bridge configuration
|
|
44
45
|
"""
|
|
45
46
|
# Set server name based on target instance
|
|
46
47
|
super().__init__(f"claude_instance_{config.instance_id}")
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
self.config = config
|
|
49
50
|
self.conversation_history: List[Dict[str, Any]] = []
|
|
50
51
|
self.shared_context: Dict[str, Any] = {}
|
|
51
|
-
|
|
52
|
+
|
|
52
53
|
# Register tools
|
|
53
54
|
self._register_tools()
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
def _register_tools(self):
|
|
56
57
|
"""Register MCP tools for inter-Claude communication."""
|
|
57
|
-
|
|
58
|
+
|
|
58
59
|
@self.tool()
|
|
59
60
|
async def chat_with_claude(message: str, context: Optional[str] = None) -> str:
|
|
60
61
|
"""Chat with another Claude instance.
|
|
61
|
-
|
|
62
|
+
|
|
62
63
|
Args:
|
|
63
64
|
message: Message to send to the other Claude
|
|
64
65
|
context: Optional context to provide
|
|
65
|
-
|
|
66
|
+
|
|
66
67
|
Returns:
|
|
67
68
|
Response from the other Claude instance
|
|
68
69
|
"""
|
|
69
70
|
logger.info(f"Bridge {self.config.instance_id}: Received chat request")
|
|
70
|
-
|
|
71
|
+
|
|
71
72
|
# Record in conversation history
|
|
72
|
-
self.conversation_history.append(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
self.conversation_history.append(
|
|
74
|
+
{
|
|
75
|
+
"from": self.config.source_instance,
|
|
76
|
+
"to": self.config.target_instance,
|
|
77
|
+
"message": message,
|
|
78
|
+
"context": context,
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
|
|
79
82
|
# Simulate response (in production, this would make actual API call)
|
|
80
83
|
response = await self._forward_to_claude(message, context)
|
|
81
|
-
|
|
82
|
-
self.conversation_history.append(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
|
|
85
|
+
self.conversation_history.append(
|
|
86
|
+
{
|
|
87
|
+
"from": self.config.target_instance,
|
|
88
|
+
"to": self.config.source_instance,
|
|
89
|
+
"response": response,
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
|
|
88
93
|
return response
|
|
89
|
-
|
|
94
|
+
|
|
90
95
|
@self.tool()
|
|
91
96
|
async def ask_claude_to_review(
|
|
92
|
-
code: str,
|
|
93
|
-
description: str,
|
|
94
|
-
focus_areas: Optional[List[str]] = None
|
|
97
|
+
code: str, description: str, focus_areas: Optional[List[str]] = None
|
|
95
98
|
) -> Dict[str, Any]:
|
|
96
99
|
"""Ask another Claude to review code.
|
|
97
|
-
|
|
100
|
+
|
|
98
101
|
Args:
|
|
99
102
|
code: Code to review
|
|
100
103
|
description: Description of what the code does
|
|
101
104
|
focus_areas: Specific areas to focus on (e.g., ["security", "performance"])
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
Returns:
|
|
104
107
|
Review feedback from the other Claude
|
|
105
108
|
"""
|
|
106
109
|
logger.info(f"Bridge {self.config.instance_id}: Code review request")
|
|
107
|
-
|
|
110
|
+
|
|
108
111
|
review_prompt = self._build_review_prompt(code, description, focus_areas)
|
|
109
112
|
review = await self._forward_to_claude(review_prompt)
|
|
110
|
-
|
|
113
|
+
|
|
111
114
|
return {
|
|
112
115
|
"reviewer": f"claude_{self.config.instance_id}",
|
|
113
116
|
"role": self.config.role,
|
|
114
117
|
"feedback": review,
|
|
115
|
-
"focus_areas": focus_areas or ["general"]
|
|
118
|
+
"focus_areas": focus_areas or ["general"],
|
|
116
119
|
}
|
|
117
|
-
|
|
120
|
+
|
|
118
121
|
@self.tool()
|
|
119
122
|
async def delegate_to_claude(
|
|
120
|
-
task: str,
|
|
121
|
-
requirements: List[str],
|
|
122
|
-
constraints: Optional[List[str]] = None
|
|
123
|
+
task: str, requirements: List[str], constraints: Optional[List[str]] = None
|
|
123
124
|
) -> Dict[str, Any]:
|
|
124
125
|
"""Delegate a task to another Claude instance.
|
|
125
|
-
|
|
126
|
+
|
|
126
127
|
Args:
|
|
127
128
|
task: Task description
|
|
128
129
|
requirements: List of requirements
|
|
129
130
|
constraints: Optional constraints
|
|
130
|
-
|
|
131
|
+
|
|
131
132
|
Returns:
|
|
132
133
|
Task completion result from the other Claude
|
|
133
134
|
"""
|
|
134
135
|
logger.info(f"Bridge {self.config.instance_id}: Task delegation")
|
|
135
|
-
|
|
136
|
-
delegation_prompt = self._build_delegation_prompt(
|
|
136
|
+
|
|
137
|
+
delegation_prompt = self._build_delegation_prompt(
|
|
138
|
+
task, requirements, constraints
|
|
139
|
+
)
|
|
137
140
|
result = await self._forward_to_claude(delegation_prompt)
|
|
138
|
-
|
|
141
|
+
|
|
139
142
|
return {
|
|
140
143
|
"delegated_to": f"claude_{self.config.instance_id}",
|
|
141
144
|
"role": self.config.role,
|
|
142
145
|
"task": task,
|
|
143
146
|
"result": result,
|
|
144
|
-
"status": "completed"
|
|
147
|
+
"status": "completed",
|
|
145
148
|
}
|
|
146
|
-
|
|
149
|
+
|
|
147
150
|
@self.tool()
|
|
148
151
|
async def get_claude_opinion(
|
|
149
152
|
question: str,
|
|
150
153
|
options: Optional[List[str]] = None,
|
|
151
|
-
criteria: Optional[List[str]] = None
|
|
154
|
+
criteria: Optional[List[str]] = None,
|
|
152
155
|
) -> Dict[str, Any]:
|
|
153
156
|
"""Get another Claude's opinion on a decision.
|
|
154
|
-
|
|
157
|
+
|
|
155
158
|
Args:
|
|
156
159
|
question: The question or decision to get opinion on
|
|
157
160
|
options: Optional list of options to choose from
|
|
158
161
|
criteria: Optional evaluation criteria
|
|
159
|
-
|
|
162
|
+
|
|
160
163
|
Returns:
|
|
161
164
|
Opinion and reasoning from the other Claude
|
|
162
165
|
"""
|
|
163
166
|
logger.info(f"Bridge {self.config.instance_id}: Opinion request")
|
|
164
|
-
|
|
167
|
+
|
|
165
168
|
opinion_prompt = self._build_opinion_prompt(question, options, criteria)
|
|
166
169
|
opinion = await self._forward_to_claude(opinion_prompt)
|
|
167
|
-
|
|
170
|
+
|
|
168
171
|
return {
|
|
169
172
|
"advisor": f"claude_{self.config.instance_id}",
|
|
170
173
|
"role": self.config.role,
|
|
171
174
|
"question": question,
|
|
172
175
|
"opinion": opinion,
|
|
173
176
|
"options_considered": options,
|
|
174
|
-
"criteria_used": criteria
|
|
177
|
+
"criteria_used": criteria,
|
|
175
178
|
}
|
|
176
|
-
|
|
179
|
+
|
|
177
180
|
@self.tool()
|
|
178
181
|
async def share_context_with_claude(
|
|
179
|
-
key: str,
|
|
180
|
-
value: Any,
|
|
181
|
-
description: Optional[str] = None
|
|
182
|
+
key: str, value: Any, description: Optional[str] = None
|
|
182
183
|
) -> bool:
|
|
183
184
|
"""Share context with another Claude instance.
|
|
184
|
-
|
|
185
|
+
|
|
185
186
|
Args:
|
|
186
187
|
key: Context key
|
|
187
188
|
value: Context value
|
|
188
189
|
description: Optional description of the context
|
|
189
|
-
|
|
190
|
+
|
|
190
191
|
Returns:
|
|
191
192
|
Success status
|
|
192
193
|
"""
|
|
193
194
|
logger.info(f"Bridge {self.config.instance_id}: Sharing context '{key}'")
|
|
194
|
-
|
|
195
|
+
|
|
195
196
|
self.shared_context[key] = {
|
|
196
197
|
"value": value,
|
|
197
198
|
"description": description,
|
|
198
199
|
"shared_by": self.config.source_instance,
|
|
199
|
-
"shared_with": self.config.target_instance
|
|
200
|
+
"shared_with": self.config.target_instance,
|
|
200
201
|
}
|
|
201
|
-
|
|
202
|
+
|
|
202
203
|
return True
|
|
203
|
-
|
|
204
|
+
|
|
204
205
|
@self.tool()
|
|
205
206
|
async def get_shared_context(key: Optional[str] = None) -> Dict[str, Any]:
|
|
206
207
|
"""Get shared context from Claude network.
|
|
207
|
-
|
|
208
|
+
|
|
208
209
|
Args:
|
|
209
210
|
key: Optional specific key to retrieve
|
|
210
|
-
|
|
211
|
+
|
|
211
212
|
Returns:
|
|
212
213
|
Shared context data
|
|
213
214
|
"""
|
|
214
215
|
if key:
|
|
215
216
|
return self.shared_context.get(key, {})
|
|
216
217
|
return self.shared_context
|
|
217
|
-
|
|
218
|
+
|
|
218
219
|
@self.tool()
|
|
219
220
|
async def brainstorm_with_claude(
|
|
220
|
-
topic: str,
|
|
221
|
-
num_ideas: int = 5,
|
|
222
|
-
constraints: Optional[List[str]] = None
|
|
221
|
+
topic: str, num_ideas: int = 5, constraints: Optional[List[str]] = None
|
|
223
222
|
) -> List[str]:
|
|
224
223
|
"""Brainstorm ideas with another Claude.
|
|
225
|
-
|
|
224
|
+
|
|
226
225
|
Args:
|
|
227
226
|
topic: Topic to brainstorm about
|
|
228
227
|
num_ideas: Number of ideas to generate
|
|
229
228
|
constraints: Optional constraints
|
|
230
|
-
|
|
229
|
+
|
|
231
230
|
Returns:
|
|
232
231
|
List of brainstormed ideas
|
|
233
232
|
"""
|
|
234
233
|
logger.info(f"Bridge {self.config.instance_id}: Brainstorming request")
|
|
235
|
-
|
|
234
|
+
|
|
236
235
|
brainstorm_prompt = f"""
|
|
237
236
|
Please brainstorm {num_ideas} ideas about: {topic}
|
|
238
237
|
|
|
@@ -240,19 +239,19 @@ class ClaudeBridge(FastMCP):
|
|
|
240
239
|
|
|
241
240
|
Provide creative and practical ideas.
|
|
242
241
|
"""
|
|
243
|
-
|
|
242
|
+
|
|
244
243
|
response = await self._forward_to_claude(brainstorm_prompt)
|
|
245
|
-
|
|
244
|
+
|
|
246
245
|
# Parse response into list (simplified)
|
|
247
246
|
ideas = response.split("\n")
|
|
248
247
|
ideas = [idea.strip() for idea in ideas if idea.strip()]
|
|
249
|
-
|
|
248
|
+
|
|
250
249
|
return ideas[:num_ideas]
|
|
251
|
-
|
|
250
|
+
|
|
252
251
|
@self.tool()
|
|
253
252
|
async def get_claude_status() -> Dict[str, Any]:
|
|
254
253
|
"""Get status of the connected Claude instance.
|
|
255
|
-
|
|
254
|
+
|
|
256
255
|
Returns:
|
|
257
256
|
Status information
|
|
258
257
|
"""
|
|
@@ -261,11 +260,12 @@ class ClaudeBridge(FastMCP):
|
|
|
261
260
|
"role": self.config.role,
|
|
262
261
|
"status": "available",
|
|
263
262
|
"conversation_count": len(self.conversation_history),
|
|
264
|
-
"shared_context_keys": list(self.shared_context.keys())
|
|
263
|
+
"shared_context_keys": list(self.shared_context.keys()),
|
|
265
264
|
}
|
|
266
|
-
|
|
267
|
-
def _build_review_prompt(
|
|
268
|
-
|
|
265
|
+
|
|
266
|
+
def _build_review_prompt(
|
|
267
|
+
self, code: str, description: str, focus_areas: Optional[List[str]]
|
|
268
|
+
) -> str:
|
|
269
269
|
"""Build a code review prompt."""
|
|
270
270
|
prompt = f"""
|
|
271
271
|
Please review the following code:
|
|
@@ -277,10 +277,10 @@ class ClaudeBridge(FastMCP):
|
|
|
277
277
|
{code}
|
|
278
278
|
```
|
|
279
279
|
"""
|
|
280
|
-
|
|
280
|
+
|
|
281
281
|
if focus_areas:
|
|
282
282
|
prompt += f"\n\nPlease focus particularly on: {', '.join(focus_areas)}"
|
|
283
|
-
|
|
283
|
+
|
|
284
284
|
prompt += """
|
|
285
285
|
|
|
286
286
|
Provide constructive feedback on:
|
|
@@ -290,11 +290,12 @@ class ClaudeBridge(FastMCP):
|
|
|
290
290
|
4. Security concerns
|
|
291
291
|
5. Suggestions for improvement
|
|
292
292
|
"""
|
|
293
|
-
|
|
293
|
+
|
|
294
294
|
return prompt
|
|
295
|
-
|
|
296
|
-
def _build_delegation_prompt(
|
|
297
|
-
|
|
295
|
+
|
|
296
|
+
def _build_delegation_prompt(
|
|
297
|
+
self, task: str, requirements: List[str], constraints: Optional[List[str]]
|
|
298
|
+
) -> str:
|
|
298
299
|
"""Build a task delegation prompt."""
|
|
299
300
|
prompt = f"""
|
|
300
301
|
Please complete the following task:
|
|
@@ -304,54 +305,57 @@ class ClaudeBridge(FastMCP):
|
|
|
304
305
|
Requirements:
|
|
305
306
|
{chr(10).join(f"- {req}" for req in requirements)}
|
|
306
307
|
"""
|
|
307
|
-
|
|
308
|
+
|
|
308
309
|
if constraints:
|
|
309
310
|
prompt += f"""
|
|
310
311
|
|
|
311
312
|
Constraints:
|
|
312
313
|
{chr(10).join(f"- {con}" for con in constraints)}
|
|
313
314
|
"""
|
|
314
|
-
|
|
315
|
+
|
|
315
316
|
prompt += """
|
|
316
317
|
|
|
317
318
|
Provide a complete solution that meets all requirements.
|
|
318
319
|
"""
|
|
319
|
-
|
|
320
|
+
|
|
320
321
|
return prompt
|
|
321
|
-
|
|
322
|
-
def _build_opinion_prompt(
|
|
323
|
-
|
|
322
|
+
|
|
323
|
+
def _build_opinion_prompt(
|
|
324
|
+
self, question: str, options: Optional[List[str]], criteria: Optional[List[str]]
|
|
325
|
+
) -> str:
|
|
324
326
|
"""Build an opinion request prompt."""
|
|
325
327
|
prompt = f"""
|
|
326
328
|
I need your opinion on the following:
|
|
327
329
|
|
|
328
330
|
Question: {question}
|
|
329
331
|
"""
|
|
330
|
-
|
|
332
|
+
|
|
331
333
|
if options:
|
|
332
334
|
prompt += f"""
|
|
333
335
|
|
|
334
336
|
Options to consider:
|
|
335
337
|
{chr(10).join(f"{i+1}. {opt}" for i, opt in enumerate(options))}
|
|
336
338
|
"""
|
|
337
|
-
|
|
339
|
+
|
|
338
340
|
if criteria:
|
|
339
341
|
prompt += f"""
|
|
340
342
|
|
|
341
343
|
Please evaluate based on these criteria:
|
|
342
344
|
{chr(10).join(f"- {crit}" for crit in criteria)}
|
|
343
345
|
"""
|
|
344
|
-
|
|
346
|
+
|
|
345
347
|
prompt += """
|
|
346
348
|
|
|
347
349
|
Provide your recommendation with clear reasoning.
|
|
348
350
|
"""
|
|
349
|
-
|
|
351
|
+
|
|
350
352
|
return prompt
|
|
351
|
-
|
|
352
|
-
async def _forward_to_claude(
|
|
353
|
+
|
|
354
|
+
async def _forward_to_claude(
|
|
355
|
+
self, prompt: str, context: Optional[str] = None
|
|
356
|
+
) -> str:
|
|
353
357
|
"""Forward a request to the target Claude instance.
|
|
354
|
-
|
|
358
|
+
|
|
355
359
|
In production, this would make an actual API call to the Claude instance.
|
|
356
360
|
For now, it returns a simulated response.
|
|
357
361
|
"""
|
|
@@ -359,16 +363,18 @@ class ClaudeBridge(FastMCP):
|
|
|
359
363
|
full_prompt = prompt
|
|
360
364
|
if context:
|
|
361
365
|
full_prompt = f"Context: {context}\n\n{prompt}"
|
|
362
|
-
|
|
366
|
+
|
|
363
367
|
# Log the forwarding
|
|
364
|
-
logger.info(
|
|
368
|
+
logger.info(
|
|
369
|
+
f"Forwarding from instance {self.config.source_instance} to {self.config.target_instance}"
|
|
370
|
+
)
|
|
365
371
|
logger.debug(f"Prompt: {full_prompt[:200]}...")
|
|
366
|
-
|
|
372
|
+
|
|
367
373
|
# In production, this would:
|
|
368
374
|
# 1. Connect to the target Claude instance API
|
|
369
375
|
# 2. Send the prompt
|
|
370
376
|
# 3. Receive and return the response
|
|
371
|
-
|
|
377
|
+
|
|
372
378
|
# Simulated response based on role
|
|
373
379
|
if self.config.role.startswith("critic"):
|
|
374
380
|
return f"""
|
|
@@ -402,33 +408,33 @@ class ClaudeBridge(FastMCP):
|
|
|
402
408
|
|
|
403
409
|
async def run_bridge_server(config: BridgeConfig):
|
|
404
410
|
"""Run the MCP bridge server.
|
|
405
|
-
|
|
411
|
+
|
|
406
412
|
Args:
|
|
407
413
|
config: Bridge configuration
|
|
408
414
|
"""
|
|
409
415
|
# Configure logging
|
|
410
416
|
logging.basicConfig(
|
|
411
417
|
level=logging.INFO,
|
|
412
|
-
format=
|
|
418
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
413
419
|
)
|
|
414
|
-
|
|
420
|
+
|
|
415
421
|
logger.info(f"Starting MCP Bridge for Claude instance {config.instance_id}")
|
|
416
422
|
logger.info(f"Role: {config.role}")
|
|
417
423
|
logger.info(f"Target port: {config.target_port}")
|
|
418
|
-
|
|
424
|
+
|
|
419
425
|
# Create and run the bridge
|
|
420
426
|
bridge = ClaudeBridge(config)
|
|
421
|
-
|
|
427
|
+
|
|
422
428
|
# Run the stdio server
|
|
423
429
|
async with stdio_server() as (read_stream, write_stream):
|
|
424
430
|
await bridge.run(
|
|
425
431
|
read_stream=read_stream,
|
|
426
432
|
write_stream=write_stream,
|
|
427
|
-
InitializationOptions(
|
|
433
|
+
initialization_options=InitializationOptions(
|
|
428
434
|
server_name=bridge.name,
|
|
429
435
|
server_version="1.0.0",
|
|
430
|
-
capabilities=bridge.get_capabilities()
|
|
431
|
-
)
|
|
436
|
+
capabilities=bridge.get_capabilities(),
|
|
437
|
+
),
|
|
432
438
|
)
|
|
433
439
|
|
|
434
440
|
|
|
@@ -441,38 +447,38 @@ def main():
|
|
|
441
447
|
"--target-port",
|
|
442
448
|
type=int,
|
|
443
449
|
required=True,
|
|
444
|
-
help="Port of the target Claude instance"
|
|
450
|
+
help="Port of the target Claude instance",
|
|
445
451
|
)
|
|
446
452
|
parser.add_argument(
|
|
447
453
|
"--instance-id",
|
|
448
454
|
type=int,
|
|
449
455
|
required=True,
|
|
450
|
-
help="ID of the target Claude instance"
|
|
456
|
+
help="ID of the target Claude instance",
|
|
451
457
|
)
|
|
452
458
|
parser.add_argument(
|
|
453
459
|
"--role",
|
|
454
460
|
type=str,
|
|
455
461
|
required=True,
|
|
456
|
-
help="Role of the target instance (primary, critic_1, etc.)"
|
|
462
|
+
help="Role of the target instance (primary, critic_1, etc.)",
|
|
457
463
|
)
|
|
458
|
-
|
|
464
|
+
|
|
459
465
|
args = parser.parse_args()
|
|
460
|
-
|
|
466
|
+
|
|
461
467
|
# Get source/target from environment
|
|
462
468
|
source_instance = int(os.environ.get("SOURCE_INSTANCE", "0"))
|
|
463
469
|
target_instance = int(os.environ.get("TARGET_INSTANCE", args.instance_id))
|
|
464
|
-
|
|
470
|
+
|
|
465
471
|
config = BridgeConfig(
|
|
466
472
|
target_port=args.target_port,
|
|
467
473
|
instance_id=args.instance_id,
|
|
468
474
|
role=args.role,
|
|
469
475
|
source_instance=source_instance,
|
|
470
|
-
target_instance=target_instance
|
|
476
|
+
target_instance=target_instance,
|
|
471
477
|
)
|
|
472
|
-
|
|
478
|
+
|
|
473
479
|
# Run the bridge
|
|
474
480
|
asyncio.run(run_bridge_server(config))
|
|
475
481
|
|
|
476
482
|
|
|
477
483
|
if __name__ == "__main__":
|
|
478
|
-
main()
|
|
484
|
+
main()
|