8d5e357b57
Second half of the MCP client: the tools the manager discovers become rows in the existing act allowlist instead of a parallel capability system. An MCP tool is encoded in the columns that already exist — cmd ["mcp",<server>,<tool>], scope mcp:<server> — so no migration, and ProposeTool/EnableTool/DisableTool, tool.Matcher and the confirm turn need no changes. One branch in Executor.Exec routes such a row to the manager instead of exec, and "mcp" is never run as a binary. Discovery only ever PROPOSES. destructive comes from the inverse of the MCP readOnlyHint, so a tool that does not promise to be read-only inherits the confirm turn, and enabling stays on /tools behind step-up. Voice args are positional and MCP args are named, so CallPositional binds only what it can defend: no required properties runs bare, and a read-only tool with exactly one required string or number gets the tail. Everything else refuses with ErrNeedsArgs rather than guessing. The read-only condition was learned against the live Vikunja server: update_task requires only task_id and takes the rest as optional, so one guessed argument blanked the fields it did not mention. A partially-filled write destroys what it omits, so a mutating tool never receives a guessed argument. Also: a read-only mcp_servers IPC method and an "MCP servers" card on /tools showing transport, target and state, with the trust level of a local target spelled out. There is deliberately no call-a-tool IPC method and no run button, so mutation keeps exactly one path. Vikunja #251
84 lines
3.1 KiB
JSON
84 lines
3.1 KiB
JSON
{
|
|
"db_path": "/var/lib/maven/maven.db.enc",
|
|
"db_tmpfs": "/dev/shm/maven-plain.db",
|
|
"db_key_env": "MAVEN_DB_KEY",
|
|
"socket_path": "/run/maven/mavend.sock",
|
|
"state_dir": "/var/lib/maven",
|
|
|
|
"phraser": {
|
|
"model_path": "/opt/maven/models/llm/qwen3/Qwen3-1.7B-UD-Q4_K_XL.gguf",
|
|
"bin_path": "llama-server",
|
|
"n_gpu_layers": 99,
|
|
"n_ctx": 4096,
|
|
"timeout": "60s",
|
|
"llm_nudges": false
|
|
},
|
|
|
|
"telegram": {
|
|
"bot_token": "${TELEGRAM_BOT_TOKEN}",
|
|
"chat_id": "${TELEGRAM_CHAT_ID}"
|
|
},
|
|
|
|
"digest": {
|
|
"enabled": true,
|
|
"window": "30m",
|
|
"max_items": 5,
|
|
"severity_ceiling": 2
|
|
},
|
|
|
|
"pattern_proposals": {
|
|
"notify": false,
|
|
"cooldown": "24h"
|
|
},
|
|
|
|
"mcp": {
|
|
"timeout": "15s",
|
|
"servers": [
|
|
{
|
|
"name": "vikunja",
|
|
"url": "http://192.168.1.104:9100/mcp",
|
|
"allow_private": true,
|
|
"allow_tools": ["list_projects", "list_tasks", "get_task_details", "create_task"],
|
|
"max_tools": 6,
|
|
"enabled": false
|
|
}
|
|
]
|
|
},
|
|
|
|
"nexus": { "url": "http://nexus:9740" },
|
|
"praxis": { "url": "http://praxis:8989" },
|
|
"hexis": { "url": "http://hexis:9741" },
|
|
|
|
"voice": {
|
|
"enabled": true,
|
|
"bind": "0.0.0.0:9100",
|
|
"lang": "ru",
|
|
"stt": { "socket": "/run/maven/stt.sock", "lang": "ru" },
|
|
"tts": { "socket": "/run/maven/tts.sock", "lang": "ru" },
|
|
"embedder": {
|
|
"model_path": "/opt/maven/models/embedder/multilingual-e5-small/model_quantized.onnx",
|
|
"tokenizer_path": "/opt/maven/models/embedder/multilingual-e5-small/tokenizer.json",
|
|
"lib_path": "/opt/maven/lib/libonnxruntime.so"
|
|
},
|
|
"llm_router": true,
|
|
"query_min_score": 0.55,
|
|
"query_min_margin": 0.008,
|
|
"clarify_max_attempts": 3,
|
|
"tool_timeout": "30s",
|
|
"tools": [
|
|
{ "name": "status", "cmd": ["systemctl", "status"], "scope": "homelab", "destructive": false },
|
|
{ "name": "ps", "cmd": ["docker", "ps"], "scope": "homelab", "destructive": false },
|
|
{ "name": "uptime", "cmd": ["uptime"], "scope": "homelab", "destructive": false },
|
|
{ "name": "disk", "cmd": ["df", "-h"], "scope": "homelab", "destructive": false },
|
|
{ "name": "memory", "cmd": ["free", "-h"], "scope": "homelab", "destructive": false },
|
|
{ "name": "logs", "cmd": ["journalctl", "-n", "50", "-u"], "scope": "homelab", "destructive": false },
|
|
{ "name": "restart", "cmd": ["systemctl", "restart"], "scope": "homelab", "destructive": true },
|
|
{ "name": "stop", "cmd": ["systemctl", "stop"], "scope": "homelab", "destructive": true },
|
|
{ "name": "start", "cmd": ["systemctl", "start"], "scope": "homelab", "destructive": true },
|
|
{ "name": "docker-restart", "cmd": ["docker", "restart"], "scope": "homelab", "destructive": true },
|
|
{ "name": "docker-stop", "cmd": ["docker", "stop"], "scope": "homelab", "destructive": true },
|
|
{ "name": "reboot", "cmd": ["systemctl", "reboot"], "scope": "homelab", "destructive": true }
|
|
]
|
|
}
|
|
}
|