Docs: MCP local clones and tool profiles
Document local-cloned MCP server layout, docker mounts, tool-call JSON protocol for local providers, profile routing behavior, and common gotchas. Add a brief pointer from the multi-bot Docker guide. Made-with: Cursor
This commit is contained in:
parent
7050e032e8
commit
4b808f9a30
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,6 +5,8 @@
|
||||
dist/
|
||||
build/
|
||||
docs/
|
||||
!docs/*.md
|
||||
!docs/**/*.md
|
||||
*.egg-info/
|
||||
*.egg
|
||||
*.pyc
|
||||
|
||||
@ -95,6 +95,16 @@ nanobot/
|
||||
- Environment variables (from Docker env files)
|
||||
- Config file: `/root/.nanobot/config.json` (mounted from host)
|
||||
|
||||
### MCP servers + tool profiles (local LLM note)
|
||||
|
||||
If you’re using a local LLM provider with a **low tool limit** (often ~20 tools), MCP servers (which can register 30+ tools) can exceed the limit unless you use tool profiles carefully.
|
||||
|
||||
See `docs/mcp_local_clone_and_tool_profiles.md` for:
|
||||
- Local-clone MCP layout (`./mcp-servers` → `/app/mcp-servers`)
|
||||
- How MCP env vars like `$NANOBOT_GITLE_TOKEN` are expanded into server env
|
||||
- Tool-call JSON protocol for local providers
|
||||
- Profile routing behavior and when MCP servers disconnect
|
||||
|
||||
---
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
95
docs/mcp_local_clone_and_tool_profiles.md
Normal file
95
docs/mcp_local_clone_and_tool_profiles.md
Normal file
@ -0,0 +1,95 @@
|
||||
# MCP local clones + tool profiles (local LLM friendly)
|
||||
|
||||
This documents the MCP/tool-profile work done to make MCP servers usable with local LLM providers that have **low tool limits** (e.g. ~20 tools) and/or unreliable native function-calling.
|
||||
|
||||
## What we changed
|
||||
|
||||
- **Local-clone policy for MCP servers**
|
||||
- MCP servers are cloned/built locally under `./mcp-servers/` (not installed from npm/PyPI at runtime).
|
||||
- Repo gitignore keeps the clones out of git while keeping `mcp-servers/README.md` and `.gitkeep`.
|
||||
- Added `scripts/setup-mcp-servers.sh` to clone/build the Gitea MCP server (`mcp-servers/gitea-mcp/`) into a runnable binary.
|
||||
|
||||
- **Docker mounts for local MCP servers**
|
||||
- Multi-bot compose files mount `./mcp-servers` into containers at `/app/mcp-servers:ro`.
|
||||
- This makes config entries like `/app/mcp-servers/gitea-mcp/gitea-mcp` work inside the container.
|
||||
|
||||
- **MCP env var expansion**
|
||||
- `nanobot/agent/tools/mcp.py` expands `$VARS` in MCP server `env` using the container environment, so configs can safely reference secrets without duplicating them:
|
||||
- Example: `"GITEA_ACCESS_TOKEN": "$NANOBOT_GITLE_TOKEN"`
|
||||
|
||||
- **Local-provider tool calling reliability**
|
||||
- `nanobot/agent/context.py` now includes a strict JSON tool-call protocol for providers that don’t do native function calling.
|
||||
- `nanobot/providers/custom_provider.py` was improved to parse tool calls when the model returns:
|
||||
- Embedded JSON tool calls in content, or
|
||||
- A message that is *only* a JSON object (`{"name": "...", "parameters": {...}}`)
|
||||
|
||||
- **Tool profile routing improvements**
|
||||
- `nanobot/agent/tool_routing.py` includes a heuristic fast-path to pick an MCP-capable profile (e.g. `workspace_mcp`) when the user intent includes PRs/issues/repos/Gitea terms.
|
||||
- The LLM router still applies for general cases; this heuristic prevents obvious “forge” intents from being routed to a no-MCP profile.
|
||||
|
||||
- **LLM empty-response retry**
|
||||
- `nanobot/agent/loop.py` retries once if the provider returns an empty final message, nudging the model to either call a tool or respond with text.
|
||||
|
||||
## Where MCP servers live (host vs container)
|
||||
|
||||
- **Host repo path**: `./mcp-servers/`
|
||||
- Example: `./mcp-servers/gitea-mcp/`
|
||||
- **Inside the nanobot container**: `/app/mcp-servers/` (mounted read-only)
|
||||
- Example: `/app/mcp-servers/gitea-mcp/gitea-mcp`
|
||||
|
||||
## Minimal Gitea MCP setup
|
||||
|
||||
1. Build the local server (host):
|
||||
|
||||
```bash
|
||||
./scripts/setup-mcp-servers.sh gitea
|
||||
```
|
||||
|
||||
2. Add to per-bot config (host) `~/.nanobot-user1/config.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"tools": {
|
||||
"mcpServers": {
|
||||
"gitea": {
|
||||
"command": "/app/mcp-servers/gitea-mcp/gitea-mcp",
|
||||
"args": ["-t", "stdio", "--host", "http://10.0.30.169:3000", "-r"],
|
||||
"env": {
|
||||
"GITEA_ACCESS_TOKEN": "$NANOBOT_GITLE_TOKEN"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Ensure your compose file mounts the local MCP servers directory:
|
||||
- `./mcp-servers:/app/mcp-servers:ro`
|
||||
|
||||
## Tool profiles: what they do (and what they don’t)
|
||||
|
||||
- **Built-in tools** are registered once at gateway startup and do not “shut down”; profiles only control **exposure to the LLM per turn**.
|
||||
- **MCP tools/servers** are connected lazily and can be **connected/disconnected per turn** based on the selected profile.
|
||||
|
||||
### When MCP servers disconnect
|
||||
|
||||
- **On a later message**, if a new profile is selected whose `mcpServers` set does not include a previously-connected server, nanobot disconnects that MCP server.
|
||||
- On **gateway shutdown**, nanobot disconnects all MCP servers.
|
||||
- `/new` **does not** disconnect MCP servers; it only clears session history and triggers memory consolidation.
|
||||
|
||||
## Common gotchas
|
||||
|
||||
- **Router picked `workspace` (no MCP)**
|
||||
- If the router selects a profile with `"mcpServers": []`, MCP tools are hidden even if the servers are configured.
|
||||
- Either improve routing, or (if acceptable) allowlist the specific MCP server in that profile (`"mcpServers": ["gitea"]`).
|
||||
|
||||
- **Tool count limits on local models**
|
||||
- A single MCP server can register 30+ tools (Gitea MCP: ~30), which can exceed local providers’ tool limits.
|
||||
- If you must stay under ~20 tools, prefer:
|
||||
- Narrow profiles, or
|
||||
- A “dispatcher tool” approach (one tool per MCP server) instead of registering every MCP tool individually.
|
||||
|
||||
- **Repo owner/repo mismatch**
|
||||
- Errors like `GetUserByName` commonly mean the `owner` string doesn’t exist or the token cannot see it.
|
||||
- Resolve the canonical `owner/repo` first (search/list repos), then call list PRs with the correct pair.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user