From 518cef51bcb97825f8208e920379e2130852f7a4 Mon Sep 17 00:00:00 2001 From: adam Date: Sun, 1 Mar 2026 18:49:46 +0000 Subject: [PATCH] Improve tool descriptions for cross-model compatibility Add concrete parameter examples, negative routing guidance, and format conventions to tool descriptions. Helps Gemini with literal tool selection and GPT with over-calling prevention. --- src/index.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index b1f6e83..68c7e5d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -20,7 +20,7 @@ const server = new McpServer({ server.tool( "search_context", - "Semantic search across all homelab documentation. Returns the most relevant sections for a natural language query. Optionally filter by document type (device, infrastructure, network, automation, tool) or hostname.", + "Semantic search across all homelab documentation and projects. Returns the most relevant sections for a natural language query. Optionally filter by document type (device, infrastructure, network, automation, tool, project) or hostname. For projects, results include project name, slug, and status — use the returned slug with get_project for full details.", searchContextSchema.shape, async (input) => ({ content: [{ type: "text", text: await searchContext(searchContextSchema.parse(input)) }], @@ -47,7 +47,7 @@ server.tool( server.tool( "search_issues", - "Search for operational notes, troubleshooting info, known issues, and incident reports across all homelab documentation.", + "Search for operational problems, troubleshooting notes, known issues, and incident history across all homelab documentation. Searches the same collection as search_context but filters results to operational/issue-related content. Use search_context instead for general documentation lookup or project searches.", searchIssuesSchema.shape, async (input) => ({ content: [{ type: "text", text: await searchIssues(searchIssuesSchema.parse(input)) }], @@ -56,7 +56,7 @@ server.tool( server.tool( "upsert_context", - "Create or overwrite a homelab documentation chunk. Uses a deterministic ID based on source, section, and host so repeated upserts are idempotent.", + 'Create or overwrite a homelab documentation chunk. Uses a deterministic ID based on source, section, and host so repeated upserts are idempotent. Example: {host: "proxmox", section: "GPU Passthrough", source: "devices/proxmox.md", type: "device", text: "...", tags: ["gpu", "nvidia"]}. source uses path-like format, host is the hostname, section is a human-readable heading.', upsertContextSchema.shape, async (input) => ({ content: [{ type: "text", text: await upsertContext(upsertContextSchema.parse(input)) }], @@ -65,7 +65,7 @@ server.tool( server.tool( "update_context", - "Update metadata fields on existing homelab documentation chunk(s). Filter by host, source, section, or project. Optionally provide new text to trigger re-embedding.", + 'Update metadata fields on existing homelab documentation chunk(s). Filter fields (host, source, section, project) select which chunks to update. new_* fields set the new values. At least one filter required. Example: {host: "proxmox", section: "GPU Passthrough", new_tags: ["gpu", "nvidia", "rtx8000"]}. Optionally provide text to trigger re-embedding.', updateContextSchema._def.schema.shape, async (input) => ({ content: [{ type: "text", text: await updateContext(updateContextSchema.parse(input)) }], @@ -83,7 +83,7 @@ server.tool( server.tool( "list_projects", - "List all tracked projects. Filter by status (default: 'active', or 'all' for everything). Returns JSON array of project summaries.", + "List all tracked projects at a glance. Filter by status (default: 'active', or 'all' for everything). Returns JSON array of project summaries with slug, name, status, summary, tags, and updated. Use search_context with type: 'project' for semantic/topic search across projects instead.", listProjectsSchema.shape, async (input) => ({ content: [{ type: "text", text: await listProjects(listProjectsSchema.parse(input)) }], @@ -101,7 +101,7 @@ server.tool( server.tool( "upsert_project", - "Create or update a project. On create, 'name' is required; other fields default to empty. On update, only provided fields are changed. Relationships merge at sub-key level (hosts, software, git_repos, local_dirs).", + 'Use for initial project creation or full rewrites. Do NOT use for incremental changes like adding a single blocker or history entry — use update_project instead. On create, slug and name are required; other fields default to empty. On update, only provided fields are changed. Relationships merge at sub-key level (hosts, software, git_repos, local_dirs). Example creation: {slug: "led-dimming", name: "LED Dimming Controller", status: "planning", summary: "PWM-based LED dimming system", tags: ["hardware", "esphome"]}.', upsertProjectSchema.shape, async (input) => ({ content: [{ type: "text", text: await upsertProject(upsertProjectSchema.parse(input)) }], @@ -110,7 +110,7 @@ server.tool( server.tool( "update_project", - "Apply granular mutations to an existing project. Supports scalar updates (status, summary, current_state) and array add/remove operations (blockers, tags, key_facts, history, decisions_pending, relationships).", + 'Use for incremental mutations to existing projects. Supports adding/removing individual items without touching other fields. Do NOT use for initial creation — use upsert_project instead. Examples: add_blocker: "Waiting on PCB fab delivery", add_history: "2026-03-01: Deployed v1.0 to production", add_relationship: {category: "hosts", host: "proxmox", role: "compute node"}, add_relationship: {category: "git_repos", repo: "adamksmith/homelab-mcp", role: "source code"}, add_relationship: {category: "software", name: "ESPHome", role: "firmware framework", version: "2024.12"}, add_relationship: {category: "local_dirs", path: "/home/adam/projects/foo", role: "working directory"}, remove_relationship: {category: "hosts", host: "old-server"}.', updateProjectSchema.shape, async (input) => ({ content: [{ type: "text", text: await updateProject(updateProjectSchema.parse(input)) }],