fix: store original MCP tool name, make close_mcp public
This commit is contained in:
parent
54d5f637e7
commit
52cf1da30a
36
README.md
36
README.md
@ -16,7 +16,7 @@
|
||||
|
||||
⚡️ Delivers core agent functionality in just **~4,000** lines of code — **99% smaller** than Clawdbot's 430k+ lines.
|
||||
|
||||
📏 Real-time line count: **3,536 lines** (run `bash core_agent_lines.sh` to verify anytime)
|
||||
📏 Real-time line count: **3,656 lines** (run `bash core_agent_lines.sh` to verify anytime)
|
||||
|
||||
## 📢 News
|
||||
|
||||
@ -683,6 +683,40 @@ That's it! Environment variables, model prefixing, config matching, and `nanobot
|
||||
</details>
|
||||
|
||||
|
||||
### MCP (Model Context Protocol)
|
||||
|
||||
> [!TIP]
|
||||
> The config format is compatible with Claude Desktop / Cursor. You can copy MCP server configs directly from any MCP server's README.
|
||||
|
||||
nanobot supports [MCP](https://modelcontextprotocol.io/) — connect external tool servers and use them as native agent tools.
|
||||
|
||||
Add MCP servers to your `config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"tools": {
|
||||
"mcpServers": {
|
||||
"filesystem": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Two transport modes are supported:
|
||||
|
||||
| Mode | Config | Example |
|
||||
|------|--------|---------|
|
||||
| **Stdio** | `command` + `args` | Local process via `npx` / `uvx` |
|
||||
| **HTTP** | `url` | Remote endpoint (`https://mcp.example.com/sse`) |
|
||||
|
||||
MCP tools are automatically discovered and registered on startup. The LLM can use them alongside built-in tools — no extra configuration needed.
|
||||
|
||||
|
||||
|
||||
|
||||
### Security
|
||||
|
||||
> For production deployments, set `"restrictToWorkspace": true` in your config to sandbox the agent.
|
||||
|
||||
@ -229,7 +229,7 @@ class AgentLoop:
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
|
||||
async def _close_mcp(self) -> None:
|
||||
async def close_mcp(self) -> None:
|
||||
"""Close MCP connections."""
|
||||
if self._mcp_stack:
|
||||
try:
|
||||
|
||||
@ -14,7 +14,7 @@ class MCPToolWrapper(Tool):
|
||||
|
||||
def __init__(self, session, server_name: str, tool_def):
|
||||
self._session = session
|
||||
self._server = server_name
|
||||
self._original_name = tool_def.name
|
||||
self._name = f"mcp_{server_name}_{tool_def.name}"
|
||||
self._description = tool_def.description or tool_def.name
|
||||
self._parameters = tool_def.inputSchema or {"type": "object", "properties": {}}
|
||||
@ -33,9 +33,7 @@ class MCPToolWrapper(Tool):
|
||||
|
||||
async def execute(self, **kwargs: Any) -> str:
|
||||
from mcp import types
|
||||
result = await self._session.call_tool(
|
||||
self._name.removeprefix(f"mcp_{self._server}_"), arguments=kwargs
|
||||
)
|
||||
result = await self._session.call_tool(self._original_name, arguments=kwargs)
|
||||
parts = []
|
||||
for block in result.content:
|
||||
if isinstance(block, types.TextContent):
|
||||
|
||||
@ -405,7 +405,7 @@ def gateway(
|
||||
except KeyboardInterrupt:
|
||||
console.print("\nShutting down...")
|
||||
finally:
|
||||
await agent._close_mcp()
|
||||
await agent.close_mcp()
|
||||
heartbeat.stop()
|
||||
cron.stop()
|
||||
agent.stop()
|
||||
@ -473,7 +473,7 @@ def agent(
|
||||
with _thinking_ctx():
|
||||
response = await agent_loop.process_direct(message, session_id)
|
||||
_print_agent_response(response, render_markdown=markdown)
|
||||
await agent_loop._close_mcp()
|
||||
await agent_loop.close_mcp()
|
||||
|
||||
asyncio.run(run_once())
|
||||
else:
|
||||
@ -515,7 +515,7 @@ def agent(
|
||||
console.print("\nGoodbye!")
|
||||
break
|
||||
finally:
|
||||
await agent_loop._close_mcp()
|
||||
await agent_loop.close_mcp()
|
||||
|
||||
asyncio.run(run_interactive())
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user