Improve MCP tool selection guidance
This commit is contained in:
@@ -19,6 +19,25 @@ Prompts heraus, verhindert den früher beobachteten Kontextverbrauch von über
|
||||
TinySearch und SearXNG sind interne Abhängigkeiten des Web-MCPs und werden
|
||||
nicht direkt als allgemeine Werkzeuge angeboten.
|
||||
|
||||
## Entscheidungshilfe für das Modell
|
||||
|
||||
Die Server- und Werkzeugbeschreibungen grenzen die Zuständigkeiten absichtlich
|
||||
deutlich voneinander ab. Das Modell soll pro Aufgabe zunächst genau **einen**
|
||||
passenden Server wählen:
|
||||
|
||||
| Aufgabe | Werkzeugserver | Nicht zusätzlich verwenden |
|
||||
|---|---|---|
|
||||
| Aktuelle öffentliche Informationen, Quellen, GitHub/Hugging Face, Produkte | Web | HA, ARR, Unraid |
|
||||
| Entitäten, Zustände, Historie, Automationen und Dashboards | Home Assistant | Web, Unraid |
|
||||
| Serien, Filme, fehlende Episoden und Indexer-Releases | Sonarr und Radarr | Web |
|
||||
| Lesende NAS-, Docker-, Array-, Netzwerk- und Logdiagnose | Unraid (Systemdiagnose) | MUA |
|
||||
| Ausdrücklich benötigte MUA-Verwaltungsaktion | MUA | Unraid-Diagnose nicht parallel |
|
||||
|
||||
Ein leeres Ergebnis ist kein Grund, dieselbe Frage über mehrere unpassende
|
||||
Werkzeuge oder leicht veränderte Suchbegriffe erneut auszuführen. Das Modell
|
||||
soll die Grenze transparent nennen und gezielt nachfragen, wenn eine Freigabe
|
||||
oder ein anderes Werkzeug benötigt wird.
|
||||
|
||||
## Sicherheitsmodell
|
||||
|
||||
- Kein MCP-Port wird auf eine Host-Adresse veröffentlicht.
|
||||
|
||||
@@ -92,6 +92,9 @@ services:
|
||||
# The local fork adds bounded read-only Sonarr pseudo-actions. Keep the
|
||||
# patch explicit until upstream publishes a self-contained 2.x image.
|
||||
- ${ARR_SONARR_PATCH:-./patches/mcp_sonarr.py}:/usr/local/lib/python3.13/site-packages/arr_mcp/mcp/mcp_sonarr.py:ro
|
||||
# Upstream's generic "Execute any Radarr API action" text gives small
|
||||
# models no routing boundary. This overlay changes guidance only.
|
||||
- ${ARR_RADARR_PATCH:-./patches/mcp_radarr.py}:/usr/local/lib/python3.13/site-packages/arr_mcp/mcp/mcp_radarr.py:ro
|
||||
networks: [tools, egress]
|
||||
|
||||
mcp-unraid-official:
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
"""Radarr action-routed MCP tool with model-oriented routing guidance."""
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from agent_utilities.mcp_utilities import dispatch, run_blocking
|
||||
from fastmcp import FastMCP
|
||||
from pydantic import Field
|
||||
|
||||
from arr_mcp.auth import get_radarr_client
|
||||
|
||||
|
||||
def register_radarr_tools(mcp: FastMCP) -> None:
|
||||
@mcp.tool(tags={"radarr"})
|
||||
async def radarr_action(
|
||||
action: str = Field(
|
||||
description=(
|
||||
"Choose one Radarr operation. Common read choices include get_movie for the "
|
||||
"movie library and get_system_status/get_health for Radarr diagnostics. Use "
|
||||
"list_actions only when an unusual Radarr operation is genuinely required. "
|
||||
"Never guess a modifying action and never change Radarr without explicit user approval."
|
||||
)
|
||||
),
|
||||
params_json: str = Field(
|
||||
default="{}",
|
||||
description=(
|
||||
"JSON object encoded as a string containing only parameters required by the "
|
||||
"selected Radarr action. Use \"{}\" for actions without parameters; never "
|
||||
"invent movie IDs, paths, profile IDs or monitoring settings."
|
||||
),
|
||||
),
|
||||
) -> Any:
|
||||
"""USE ONLY for movies managed by Radarr: inspect the movie library, wanted/queue/history state, releases, profiles, or Radarr health. DO NOT use for TV episodes (use Sonarr), public-web research, media playback, filesystem copying, or direct downloads. Prefer read actions; any mutation requires explicit user approval."""
|
||||
client = get_radarr_client()
|
||||
kwargs = {k: v for k, v in json.loads(params_json).items() if v is not None}
|
||||
return await run_blocking(
|
||||
dispatch, client, action, kwargs, service="arr-radarr"
|
||||
)
|
||||
@@ -411,14 +411,14 @@ def register_sonarr_tools(mcp: FastMCP) -> None:
|
||||
@mcp.tool(tags={"sonarr"})
|
||||
async def sonarr_action(
|
||||
action: str = Field(
|
||||
description="Sonarr action. Read with find_series {query}, get_season_summary {series_id, season_number}, or search_releases {series_id, season_number}. To download missing episodes, first call preview_episode_search {series_id, season_number, episode_numbers:[2,3,...]}, show its exact preview to the user, then only after explicit approval call start_episode_search with the same scope plus confirm:true and approval_ticket. Monitoring is never changed."
|
||||
description="Choose one Sonarr operation. Normal choices: find_series to resolve a TV-series name; get_season_summary to list present/missing episodes; search_releases to query Sonarr's configured indexers without downloading; preview_episode_search before any download search; start_episode_search only after the user explicitly approves that exact preview. Use list_actions only for an unusual read operation."
|
||||
),
|
||||
params_json: str = Field(
|
||||
default="{}",
|
||||
description="JSON string of parameters to pass to the action.",
|
||||
description="JSON object encoded as a string. Common forms: find_series {\"query\":\"Title\"}; get_season_summary/search_releases {\"series_id\":123,\"season_number\":2}; preview_episode_search {\"series_id\":123,\"season_number\":2,\"episode_numbers\":[2,3]}. For start_episode_search reuse the exact preview scope and add confirm:true plus approval_ticket.",
|
||||
),
|
||||
) -> Any:
|
||||
"""Query Sonarr through a server-side allowlist (read-only by default; write actions when ARR_MCP_WRITE=1)."""
|
||||
"""USE ONLY for TV-series tasks managed by Sonarr: identify a series, inspect missing episodes, search configured indexers, or start an explicitly approved missing-episode search. DO NOT use for movies (use Radarr), public-web research, media playback, filesystem copying, or direct URL downloads. Read-only by default; monitoring is never changed."""
|
||||
if action in {"list_actions", "help", "actions"}:
|
||||
return {
|
||||
"service": "sonarr",
|
||||
|
||||
Reference in New Issue
Block a user