hanzo-mcp 0.6.13__py3-none-any.whl → 0.7.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.
Potentially problematic release.
This version of hanzo-mcp might be problematic. Click here for more details.
- hanzo_mcp/analytics/__init__.py +5 -0
- hanzo_mcp/analytics/posthog_analytics.py +364 -0
- hanzo_mcp/cli.py +3 -3
- hanzo_mcp/cli_enhanced.py +3 -3
- hanzo_mcp/config/settings.py +1 -1
- hanzo_mcp/config/tool_config.py +18 -4
- hanzo_mcp/server.py +34 -1
- hanzo_mcp/tools/__init__.py +65 -2
- hanzo_mcp/tools/agent/__init__.py +84 -3
- hanzo_mcp/tools/agent/agent_tool.py +102 -4
- hanzo_mcp/tools/agent/agent_tool_v2.py +492 -0
- hanzo_mcp/tools/agent/clarification_protocol.py +220 -0
- hanzo_mcp/tools/agent/clarification_tool.py +68 -0
- hanzo_mcp/tools/agent/claude_cli_tool.py +125 -0
- hanzo_mcp/tools/agent/claude_desktop_auth.py +508 -0
- hanzo_mcp/tools/agent/cli_agent_base.py +191 -0
- hanzo_mcp/tools/agent/code_auth.py +436 -0
- hanzo_mcp/tools/agent/code_auth_tool.py +194 -0
- hanzo_mcp/tools/agent/codex_cli_tool.py +123 -0
- hanzo_mcp/tools/agent/critic_tool.py +376 -0
- hanzo_mcp/tools/agent/gemini_cli_tool.py +128 -0
- hanzo_mcp/tools/agent/grok_cli_tool.py +128 -0
- hanzo_mcp/tools/agent/iching_tool.py +380 -0
- hanzo_mcp/tools/agent/network_tool.py +273 -0
- hanzo_mcp/tools/agent/prompt.py +62 -20
- hanzo_mcp/tools/agent/review_tool.py +433 -0
- hanzo_mcp/tools/agent/swarm_tool.py +535 -0
- hanzo_mcp/tools/agent/swarm_tool_v2.py +654 -0
- hanzo_mcp/tools/common/base.py +1 -0
- hanzo_mcp/tools/common/batch_tool.py +102 -10
- hanzo_mcp/tools/common/fastmcp_pagination.py +369 -0
- hanzo_mcp/tools/common/forgiving_edit.py +243 -0
- hanzo_mcp/tools/common/paginated_base.py +230 -0
- hanzo_mcp/tools/common/paginated_response.py +307 -0
- hanzo_mcp/tools/common/pagination.py +226 -0
- hanzo_mcp/tools/common/tool_list.py +3 -0
- hanzo_mcp/tools/common/truncate.py +101 -0
- hanzo_mcp/tools/filesystem/__init__.py +29 -0
- hanzo_mcp/tools/filesystem/ast_multi_edit.py +562 -0
- hanzo_mcp/tools/filesystem/directory_tree_paginated.py +338 -0
- hanzo_mcp/tools/lsp/__init__.py +5 -0
- hanzo_mcp/tools/lsp/lsp_tool.py +512 -0
- hanzo_mcp/tools/memory/__init__.py +76 -0
- hanzo_mcp/tools/memory/knowledge_tools.py +518 -0
- hanzo_mcp/tools/memory/memory_tools.py +456 -0
- hanzo_mcp/tools/search/__init__.py +6 -0
- hanzo_mcp/tools/search/find_tool.py +581 -0
- hanzo_mcp/tools/search/unified_search.py +953 -0
- hanzo_mcp/tools/shell/__init__.py +5 -0
- hanzo_mcp/tools/shell/auto_background.py +203 -0
- hanzo_mcp/tools/shell/base_process.py +53 -27
- hanzo_mcp/tools/shell/bash_tool.py +17 -33
- hanzo_mcp/tools/shell/npx_tool.py +15 -32
- hanzo_mcp/tools/shell/streaming_command.py +594 -0
- hanzo_mcp/tools/shell/uvx_tool.py +15 -32
- hanzo_mcp/types.py +23 -0
- {hanzo_mcp-0.6.13.dist-info → hanzo_mcp-0.7.1.dist-info}/METADATA +229 -71
- {hanzo_mcp-0.6.13.dist-info → hanzo_mcp-0.7.1.dist-info}/RECORD +61 -24
- hanzo_mcp-0.6.13.dist-info/licenses/LICENSE +0 -21
- {hanzo_mcp-0.6.13.dist-info → hanzo_mcp-0.7.1.dist-info}/WHEEL +0 -0
- {hanzo_mcp-0.6.13.dist-info → hanzo_mcp-0.7.1.dist-info}/entry_points.txt +0 -0
- {hanzo_mcp-0.6.13.dist-info → hanzo_mcp-0.7.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Clarification protocol for agent-to-mainloop communication.
|
|
2
|
+
|
|
3
|
+
This module provides a protocol for agents to request clarification
|
|
4
|
+
from the main loop without human intervention.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
from enum import Enum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ClarificationType(Enum):
|
|
14
|
+
"""Types of clarification requests."""
|
|
15
|
+
AMBIGUOUS_INSTRUCTION = "ambiguous_instruction"
|
|
16
|
+
MISSING_CONTEXT = "missing_context"
|
|
17
|
+
MULTIPLE_OPTIONS = "multiple_options"
|
|
18
|
+
CONFIRMATION_NEEDED = "confirmation_needed"
|
|
19
|
+
ADDITIONAL_INFO = "additional_info"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class ClarificationRequest:
|
|
24
|
+
"""A request for clarification from an agent."""
|
|
25
|
+
|
|
26
|
+
agent_id: str
|
|
27
|
+
request_type: ClarificationType
|
|
28
|
+
question: str
|
|
29
|
+
context: Dict[str, Any]
|
|
30
|
+
options: Optional[List[str]] = None
|
|
31
|
+
|
|
32
|
+
def to_json(self) -> str:
|
|
33
|
+
"""Convert to JSON for transport."""
|
|
34
|
+
return json.dumps({
|
|
35
|
+
"agent_id": self.agent_id,
|
|
36
|
+
"request_type": self.request_type.value,
|
|
37
|
+
"question": self.question,
|
|
38
|
+
"context": self.context,
|
|
39
|
+
"options": self.options
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
@classmethod
|
|
43
|
+
def from_json(cls, data: str) -> "ClarificationRequest":
|
|
44
|
+
"""Create from JSON string."""
|
|
45
|
+
obj = json.loads(data)
|
|
46
|
+
return cls(
|
|
47
|
+
agent_id=obj["agent_id"],
|
|
48
|
+
request_type=ClarificationType(obj["request_type"]),
|
|
49
|
+
question=obj["question"],
|
|
50
|
+
context=obj["context"],
|
|
51
|
+
options=obj.get("options")
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass
|
|
56
|
+
class ClarificationResponse:
|
|
57
|
+
"""A response to a clarification request."""
|
|
58
|
+
|
|
59
|
+
request_id: str
|
|
60
|
+
answer: str
|
|
61
|
+
additional_context: Optional[Dict[str, Any]] = None
|
|
62
|
+
|
|
63
|
+
def to_json(self) -> str:
|
|
64
|
+
"""Convert to JSON for transport."""
|
|
65
|
+
return json.dumps({
|
|
66
|
+
"request_id": self.request_id,
|
|
67
|
+
"answer": self.answer,
|
|
68
|
+
"additional_context": self.additional_context
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ClarificationHandler:
|
|
73
|
+
"""Handles clarification requests from agents."""
|
|
74
|
+
|
|
75
|
+
def __init__(self):
|
|
76
|
+
self.pending_requests: Dict[str, ClarificationRequest] = {}
|
|
77
|
+
self.request_counter = 0
|
|
78
|
+
|
|
79
|
+
def create_request(
|
|
80
|
+
self,
|
|
81
|
+
agent_id: str,
|
|
82
|
+
request_type: ClarificationType,
|
|
83
|
+
question: str,
|
|
84
|
+
context: Dict[str, Any],
|
|
85
|
+
options: Optional[List[str]] = None
|
|
86
|
+
) -> str:
|
|
87
|
+
"""Create a new clarification request.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Request ID for tracking
|
|
91
|
+
"""
|
|
92
|
+
request = ClarificationRequest(
|
|
93
|
+
agent_id=agent_id,
|
|
94
|
+
request_type=request_type,
|
|
95
|
+
question=question,
|
|
96
|
+
context=context,
|
|
97
|
+
options=options
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
request_id = f"clarify_{self.request_counter}"
|
|
101
|
+
self.request_counter += 1
|
|
102
|
+
self.pending_requests[request_id] = request
|
|
103
|
+
|
|
104
|
+
return request_id
|
|
105
|
+
|
|
106
|
+
def handle_request(self, request: ClarificationRequest) -> ClarificationResponse:
|
|
107
|
+
"""Handle a clarification request automatically.
|
|
108
|
+
|
|
109
|
+
This method implements automatic clarification resolution
|
|
110
|
+
based on context and common patterns.
|
|
111
|
+
"""
|
|
112
|
+
request_id = f"clarify_{len(self.pending_requests)}"
|
|
113
|
+
|
|
114
|
+
# Handle different types of clarification
|
|
115
|
+
if request.request_type == ClarificationType.AMBIGUOUS_INSTRUCTION:
|
|
116
|
+
# Try to clarify based on context
|
|
117
|
+
if "file_path" in request.context:
|
|
118
|
+
if request.context["file_path"].endswith(".go"):
|
|
119
|
+
answer = "For Go files, ensure you add imports in the correct format and handle both single import and import block cases."
|
|
120
|
+
elif request.context["file_path"].endswith(".py"):
|
|
121
|
+
answer = "For Python files, add imports at the top of the file after any module docstring."
|
|
122
|
+
else:
|
|
123
|
+
answer = "Add imports according to the language's conventions."
|
|
124
|
+
else:
|
|
125
|
+
answer = "Proceed with the most reasonable interpretation based on the context."
|
|
126
|
+
|
|
127
|
+
elif request.request_type == ClarificationType.MISSING_CONTEXT:
|
|
128
|
+
# Provide additional context based on what's missing
|
|
129
|
+
if "import_path" in request.question.lower():
|
|
130
|
+
answer = "Use the standard import path based on the project structure. Check existing imports in similar files for patterns."
|
|
131
|
+
elif "format" in request.question.lower():
|
|
132
|
+
answer = "Match the existing code style in the file. Use the same indentation and formatting patterns."
|
|
133
|
+
else:
|
|
134
|
+
answer = "Analyze the surrounding code and project structure to infer the missing information."
|
|
135
|
+
|
|
136
|
+
elif request.request_type == ClarificationType.MULTIPLE_OPTIONS:
|
|
137
|
+
# Choose the best option based on context
|
|
138
|
+
if request.options:
|
|
139
|
+
# Simple heuristic: choose the first option that seems most standard
|
|
140
|
+
for option in request.options:
|
|
141
|
+
if "common" in option or "standard" in option:
|
|
142
|
+
answer = f"Choose option: {option}"
|
|
143
|
+
break
|
|
144
|
+
else:
|
|
145
|
+
answer = f"Choose option: {request.options[0]}"
|
|
146
|
+
else:
|
|
147
|
+
answer = "Choose the most conventional approach based on the codebase patterns."
|
|
148
|
+
|
|
149
|
+
elif request.request_type == ClarificationType.CONFIRMATION_NEEDED:
|
|
150
|
+
# Auto-confirm safe operations
|
|
151
|
+
if "add import" in request.question.lower():
|
|
152
|
+
answer = "Yes, proceed with adding the import."
|
|
153
|
+
elif "multi_edit" in request.question.lower():
|
|
154
|
+
answer = "Yes, use multi_edit for efficiency."
|
|
155
|
+
else:
|
|
156
|
+
answer = "Proceed if the operation is safe and reversible."
|
|
157
|
+
|
|
158
|
+
else: # ADDITIONAL_INFO
|
|
159
|
+
answer = "Continue with available information and make reasonable assumptions based on context."
|
|
160
|
+
|
|
161
|
+
return ClarificationResponse(
|
|
162
|
+
request_id=request_id,
|
|
163
|
+
answer=answer,
|
|
164
|
+
additional_context={"auto_resolved": True}
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class AgentClarificationMixin:
|
|
169
|
+
"""Mixin for agents to request clarification."""
|
|
170
|
+
|
|
171
|
+
def __init__(self, *args, **kwargs):
|
|
172
|
+
super().__init__(*args, **kwargs)
|
|
173
|
+
self.clarification_handler = ClarificationHandler()
|
|
174
|
+
self.clarification_count = 0
|
|
175
|
+
self.max_clarifications = 1 # Allow up to 1 clarification per task
|
|
176
|
+
|
|
177
|
+
async def request_clarification(
|
|
178
|
+
self,
|
|
179
|
+
request_type: ClarificationType,
|
|
180
|
+
question: str,
|
|
181
|
+
context: Dict[str, Any],
|
|
182
|
+
options: Optional[List[str]] = None
|
|
183
|
+
) -> str:
|
|
184
|
+
"""Request clarification from the main loop.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
request_type: Type of clarification needed
|
|
188
|
+
question: The question to ask
|
|
189
|
+
context: Relevant context for the question
|
|
190
|
+
options: Optional list of choices
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
The clarification response
|
|
194
|
+
|
|
195
|
+
Raises:
|
|
196
|
+
RuntimeError: If clarification limit exceeded
|
|
197
|
+
"""
|
|
198
|
+
if self.clarification_count >= self.max_clarifications:
|
|
199
|
+
raise RuntimeError("Clarification limit exceeded")
|
|
200
|
+
|
|
201
|
+
self.clarification_count += 1
|
|
202
|
+
|
|
203
|
+
# Create request
|
|
204
|
+
request = ClarificationRequest(
|
|
205
|
+
agent_id=getattr(self, 'agent_id', 'unknown'),
|
|
206
|
+
request_type=request_type,
|
|
207
|
+
question=question,
|
|
208
|
+
context=context,
|
|
209
|
+
options=options
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# In real implementation, this would communicate with main loop
|
|
213
|
+
# For now, use the automatic handler
|
|
214
|
+
response = self.clarification_handler.handle_request(request)
|
|
215
|
+
|
|
216
|
+
return response.answer
|
|
217
|
+
|
|
218
|
+
def format_clarification_in_output(self, question: str, answer: str) -> str:
|
|
219
|
+
"""Format clarification exchange for output."""
|
|
220
|
+
return f"\n🤔 Clarification needed: {question}\n✅ Resolved: {answer}\n"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Clarification tool for agents to request information from main loop."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List, Optional, override
|
|
4
|
+
|
|
5
|
+
from hanzo_mcp.tools.common.base import BaseTool
|
|
6
|
+
from mcp.server.fastmcp import Context as MCPContext
|
|
7
|
+
from mcp.server import FastMCP
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ClarificationTool(BaseTool):
|
|
11
|
+
"""Tool for agents to request clarification from the main loop."""
|
|
12
|
+
|
|
13
|
+
name = "request_clarification"
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
@override
|
|
17
|
+
def description(self) -> str:
|
|
18
|
+
"""Get the tool description."""
|
|
19
|
+
return """Request clarification from the main loop (not the human user).
|
|
20
|
+
|
|
21
|
+
Use this when you encounter:
|
|
22
|
+
- Ambiguous instructions that could be interpreted multiple ways
|
|
23
|
+
- Missing context needed to complete the task
|
|
24
|
+
- Multiple valid options where you need guidance
|
|
25
|
+
- Operations that need confirmation before proceeding
|
|
26
|
+
- Need for additional information not provided
|
|
27
|
+
|
|
28
|
+
Parameters:
|
|
29
|
+
- type: Type of clarification (AMBIGUOUS_INSTRUCTION, MISSING_CONTEXT, MULTIPLE_OPTIONS, CONFIRMATION_NEEDED, ADDITIONAL_INFO)
|
|
30
|
+
- question: Clear, specific question to ask
|
|
31
|
+
- context: Relevant context (e.g., file_path, current_operation, etc.)
|
|
32
|
+
- options: Optional list of possible choices (for MULTIPLE_OPTIONS type)
|
|
33
|
+
|
|
34
|
+
You can only use this ONCE per task, so make it count!
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
request_clarification(
|
|
38
|
+
type="MISSING_CONTEXT",
|
|
39
|
+
question="What is the correct import path for the common package?",
|
|
40
|
+
context={"file_path": "/path/to/file.go", "undefined_symbol": "common"},
|
|
41
|
+
options=["github.com/luxfi/node/common", "github.com/project/common"]
|
|
42
|
+
)"""
|
|
43
|
+
|
|
44
|
+
async def call(
|
|
45
|
+
self,
|
|
46
|
+
ctx: MCPContext,
|
|
47
|
+
type: str,
|
|
48
|
+
question: str,
|
|
49
|
+
context: Dict[str, Any],
|
|
50
|
+
options: Optional[List[str]] = None
|
|
51
|
+
) -> str:
|
|
52
|
+
"""This is a placeholder - actual implementation happens in AgentTool."""
|
|
53
|
+
# This tool is handled specially in the agent execution
|
|
54
|
+
return f"Clarification request: {question}"
|
|
55
|
+
|
|
56
|
+
def register(self, server: FastMCP) -> None:
|
|
57
|
+
"""Register the tool with the MCP server."""
|
|
58
|
+
tool_self = self
|
|
59
|
+
|
|
60
|
+
@server.tool(name=self.name, description=self.description)
|
|
61
|
+
async def request_clarification(
|
|
62
|
+
ctx: MCPContext,
|
|
63
|
+
type: str,
|
|
64
|
+
question: str,
|
|
65
|
+
context: Dict[str, Any],
|
|
66
|
+
options: Optional[List[str]] = None
|
|
67
|
+
) -> str:
|
|
68
|
+
return await tool_self.call(ctx, type, question, context, options)
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""Claude Code CLI agent tool.
|
|
2
|
+
|
|
3
|
+
This tool provides integration with the Claude Code CLI (claude command),
|
|
4
|
+
allowing programmatic execution of Claude for code tasks.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional, override, final
|
|
8
|
+
from mcp.server import FastMCP
|
|
9
|
+
from mcp.server.fastmcp import Context as MCPContext
|
|
10
|
+
|
|
11
|
+
from hanzo_mcp.tools.agent.cli_agent_base import CLIAgentBase
|
|
12
|
+
from hanzo_mcp.tools.common.permissions import PermissionManager
|
|
13
|
+
from hanzo_mcp.tools.agent.code_auth import get_latest_claude_model
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@final
|
|
17
|
+
class ClaudeCLITool(CLIAgentBase):
|
|
18
|
+
"""Tool for executing Claude Code CLI."""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
permission_manager: PermissionManager,
|
|
23
|
+
model: Optional[str] = None,
|
|
24
|
+
**kwargs
|
|
25
|
+
):
|
|
26
|
+
"""Initialize Claude CLI tool.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
permission_manager: Permission manager for access control
|
|
30
|
+
model: Optional model override (defaults to latest Sonnet)
|
|
31
|
+
**kwargs: Additional arguments
|
|
32
|
+
"""
|
|
33
|
+
super().__init__(
|
|
34
|
+
permission_manager=permission_manager,
|
|
35
|
+
command_name="claude",
|
|
36
|
+
provider_name="Claude Code",
|
|
37
|
+
default_model=model or get_latest_claude_model(),
|
|
38
|
+
env_vars=["ANTHROPIC_API_KEY", "CLAUDE_API_KEY"],
|
|
39
|
+
**kwargs
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
@override
|
|
44
|
+
def name(self) -> str:
|
|
45
|
+
"""Get the tool name."""
|
|
46
|
+
return "claude_cli"
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
@override
|
|
50
|
+
def description(self) -> str:
|
|
51
|
+
"""Get the tool description."""
|
|
52
|
+
return """Execute Claude Code CLI for advanced code tasks.
|
|
53
|
+
|
|
54
|
+
This tool runs the Claude Code CLI (claude command) for code generation,
|
|
55
|
+
editing, analysis, and other programming tasks. It uses the latest
|
|
56
|
+
Claude 3.5 Sonnet model by default.
|
|
57
|
+
|
|
58
|
+
Features:
|
|
59
|
+
- Direct access to Claude's coding capabilities
|
|
60
|
+
- File-aware context and editing
|
|
61
|
+
- Interactive code generation
|
|
62
|
+
- Supports all Claude Code CLI features
|
|
63
|
+
|
|
64
|
+
Usage:
|
|
65
|
+
claude_cli(prompts="Fix the bug in main.py and add tests")
|
|
66
|
+
claude_cli(prompts="Refactor this class to use dependency injection", model="claude-3-opus-20240229")
|
|
67
|
+
|
|
68
|
+
Requirements:
|
|
69
|
+
- Claude Code CLI must be installed
|
|
70
|
+
- ANTHROPIC_API_KEY or CLAUDE_API_KEY environment variable
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
@override
|
|
74
|
+
def get_cli_args(self, prompt: str, **kwargs) -> List[str]:
|
|
75
|
+
"""Get CLI arguments for Claude.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
prompt: The prompt to send
|
|
79
|
+
**kwargs: Additional arguments (model, temperature, etc.)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
List of command arguments
|
|
83
|
+
"""
|
|
84
|
+
args = []
|
|
85
|
+
|
|
86
|
+
# Add model if specified
|
|
87
|
+
model = kwargs.get("model", self.default_model)
|
|
88
|
+
if model:
|
|
89
|
+
args.extend(["--model", model])
|
|
90
|
+
|
|
91
|
+
# Add temperature if specified
|
|
92
|
+
if "temperature" in kwargs:
|
|
93
|
+
args.extend(["--temperature", str(kwargs["temperature"])])
|
|
94
|
+
|
|
95
|
+
# Add max tokens if specified
|
|
96
|
+
if "max_tokens" in kwargs:
|
|
97
|
+
args.extend(["--max-tokens", str(kwargs["max_tokens"])])
|
|
98
|
+
|
|
99
|
+
# Add the prompt
|
|
100
|
+
args.append(prompt)
|
|
101
|
+
|
|
102
|
+
return args
|
|
103
|
+
|
|
104
|
+
@override
|
|
105
|
+
def register(self, mcp_server: FastMCP) -> None:
|
|
106
|
+
"""Register this tool with the MCP server."""
|
|
107
|
+
tool_self = self
|
|
108
|
+
|
|
109
|
+
@mcp_server.tool(name=self.name, description=self.description)
|
|
110
|
+
async def claude_cli(
|
|
111
|
+
ctx: MCPContext,
|
|
112
|
+
prompts: str,
|
|
113
|
+
model: Optional[str] = None,
|
|
114
|
+
temperature: Optional[float] = None,
|
|
115
|
+
max_tokens: Optional[int] = None,
|
|
116
|
+
working_dir: Optional[str] = None,
|
|
117
|
+
) -> str:
|
|
118
|
+
return await tool_self.call(
|
|
119
|
+
ctx,
|
|
120
|
+
prompts=prompts,
|
|
121
|
+
model=model,
|
|
122
|
+
temperature=temperature,
|
|
123
|
+
max_tokens=max_tokens,
|
|
124
|
+
working_dir=working_dir,
|
|
125
|
+
)
|