Add Claude Code conductor commands, MCP server, MMA exec scripts, and implement py_get_var_declaration / py_set_var_declaration which were registered in dispatch and tool specs but had no function bodies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
"""
|
|
MCP server exposing Manual Slop's custom tools (mcp_client.py) to Claude Code.
|
|
|
|
All 26 tools from mcp_client.MCP_TOOL_SPECS are served, plus run_powershell.
|
|
Delegates to mcp_client.dispatch() for all tools except run_powershell,
|
|
which routes through shell_runner.run_powershell() directly.
|
|
|
|
Usage (in .claude/settings.json mcpServers):
|
|
"command": "uv", "args": ["run", "python", "scripts/mcp_server.py"]
|
|
"""
|
|
|
|
import asyncio
|
|
import os
|
|
import sys
|
|
|
|
# Add project root to sys.path
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
import mcp_client
|
|
import shell_runner
|
|
|
|
from mcp.server import Server
|
|
from mcp.server.stdio import stdio_server
|
|
from mcp.types import Tool, TextContent
|
|
|
|
# run_powershell is handled by shell_runner, not mcp_client.dispatch()
|
|
# Define its spec here since it's not in MCP_TOOL_SPECS
|
|
RUN_POWERSHELL_SPEC = {
|
|
"name": "run_powershell",
|
|
"description": (
|
|
"Run a PowerShell script within the project base directory. "
|
|
"Returns combined stdout, stderr, and exit code. "
|
|
"60-second timeout. Use for builds, tests, and system commands."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"script": {
|
|
"type": "string",
|
|
"description": "PowerShell script content to execute."
|
|
}
|
|
},
|
|
"required": ["script"]
|
|
}
|
|
}
|
|
|
|
server = Server("manual-slop-tools")
|
|
|
|
|
|
@server.list_tools()
|
|
async def list_tools() -> list[Tool]:
|
|
tools = []
|
|
for spec in mcp_client.MCP_TOOL_SPECS:
|
|
tools.append(Tool(
|
|
name=spec["name"],
|
|
description=spec["description"],
|
|
inputSchema=spec["parameters"],
|
|
))
|
|
# Add run_powershell
|
|
tools.append(Tool(
|
|
name=RUN_POWERSHELL_SPEC["name"],
|
|
description=RUN_POWERSHELL_SPEC["description"],
|
|
inputSchema=RUN_POWERSHELL_SPEC["parameters"],
|
|
))
|
|
return tools
|
|
|
|
|
|
@server.call_tool()
|
|
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
try:
|
|
if name == "run_powershell":
|
|
script = arguments.get("script", "")
|
|
result = shell_runner.run_powershell(script, os.getcwd())
|
|
else:
|
|
result = mcp_client.dispatch(name, arguments)
|
|
return [TextContent(type="text", text=str(result))]
|
|
except Exception as e:
|
|
return [TextContent(type="text", text=f"ERROR: {e}")]
|
|
|
|
|
|
async def main():
|
|
async with stdio_server() as (read_stream, write_stream):
|
|
await server.run(
|
|
read_stream,
|
|
write_stream,
|
|
server.create_initialization_options(),
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|