Local AI MCP
OfficialLocal AI MCP is an MCP server for discovering, managing, benchmarking, and using local model runtimes with hardware-aware routing and local-by-default privacy.
List configured runtimes, installed models, loaded models, and model metadata.
Pull, load, unload, remove, and ensure models are ready, including background pull jobs and LRU/all eviction.
Check provider health, diagnostics, system resources, and estimate GPU/CPU fit for models at a given context length and KV-cache precision.
Benchmark real inference for time-to-first-token, generation speed, and prompt throughput.
Search an offline catalog or live Hugging Face GGUF models, and suggest best models for tasks on the current machine.
Run completions and embeddings, with JSON/JSON-Schema output, vision inputs, streaming progress, seeds, sampling controls, and context-length control.
Delegate tasks to the best local model in one call, preferring loaded/fitting models and explaining routing decisions.
Keep inference local by default; hosted providers are opt-in, and results report provider, host, and local status.
Support multiple runtimes and extra provider instances, exposed via 19 tools, resources, and prompts over stdio only.
Allows managing local Ollama models: discover installed and loaded models, pull/remove models, load/unload from memory, check hardware fit, and offload inference (completion and embedding) to local Ollama instances.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Local AI MCPlist installed models"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Local AI MCP
One MCP server for every local model runtime on your machine. It knows what fits your GPU, and it never sends a prompt to the cloud unless you tell it to.
Local AI MCP gives your agent (Claude, Cursor, VS Code, and others) one control plane for Ollama, LM Studio, llama.cpp, Docker Model Runner, MLX, vLLM and Foundry Local. Your agent can see what's installed and loaded, check what will actually fit in your VRAM, get models ready, and hand work off to the best local model with a single delegate call.
# illustrative session
You: Summarise these 40 pages of meeting notes locally, I don't want them in the cloud.
Agent: → delegate { task: "summarize", prompt: "...", contextLength: 32768 }
← routing: ollama / qwen3:14b — already loaded (no load cost); general model; fits: gpu
local: true · 412 tokens · 38 tok/sWhy use it
It knows your hardware.
fit_checksizes the KV cache from the model's actual layer architecture, adds up VRAM across GPUs, models partial GPU/CPU offload, and understands Apple Silicon unified memory. It answers "will this model run, and where?" with numbers rather than guesses.It works across runtimes. If you run Ollama and LM Studio, each call goes to the runtime that actually has the model. Lifecycle actions such as pull, load and unload affect exactly one runtime.
It keeps data local by default. Hosted providers such as Moonshot are opt-in, and a call without a
providerargument never uses one. Every result reportsprovider,hostandlocal, so you can see where inference ran.It handles operations, not just chat. Pull with progress, load with a context size, evict least-recently-used models to make room, benchmark time-to-first-token and tokens per second, and search Hugging Face for GGUF quantizations that fit your machine.
Related MCP server: Ollama MCP Server
Things to ask your agent
"What can I run for coding on this laptop?" →
suggest_model, thenensure_model"Free up my GPU." →
list_loaded, thenunload_model(or use thefree-vramprompt)"Benchmark my installed coder models and tell me which is fastest." →
benchmark { models: [...] }"Find a newer Gemma build that fits my 12 GB card." →
search_models { source: "huggingface" }"Extract the invoice fields from this text as JSON, locally." →
delegate { task: "extract", responseFormat: { type: "json_schema", ... } }"Will Llama 3.1 70B run here with 32K context?" →
fit_check { model, contextLength: 32768 }
Quick start
Install at least one runtime (Ollama, LM Studio, llama.cpp, Docker Model Runner, MLX, vLLM or Foundry Local), then add the server to your client. No configuration is needed for runtimes on their default ports.
Claude Code
claude mcp add local-ai -- npx -y @tmhs/local-ai-mcpClaude Desktop. Download the .mcpb file from the latest release and open it. You get a settings screen for hosts and no JSON to edit. Alternatively, add this to claude_desktop_config.json:
{
"mcpServers": {
"local-ai": { "command": "npx", "args": ["-y", "@tmhs/local-ai-mcp"] }
}
}Cursor / VS Code. Use the install buttons above, or add the same command/args to .cursor/mcp.json or .vscode/mcp.json (VS Code uses a top-level "servers" key instead of "mcpServers").
Windsurf, Cline, Zed and other clients. Any stdio MCP client works: the command is npx, the args are ["-y", "@tmhs/local-ai-mcp"].
Windows: a few clients can't launch
npxdirectly. If the server doesn't start, use"command": "cmd", "args": ["/c", "npx", "-y", "@tmhs/local-ai-mcp"].
Adding a hosted provider (optional). Put MOONSHOT_API_KEY in the server's env. It is only used when a tool call names provider: "moonshot", unless you also set LOCAL_AI_ALLOW_HOSTED_FALLBACK=1.
Supported runtimes
Runtime | Enabled | Default host | List / loaded | Pull | Load / unload | Remove | Embed | Notes |
Ollama | always |
| ✓ / ✓ | ✓ progress | ✓ ( | ✓ | ✓ | Native |
LM Studio | always |
| ✓ / ✓ | ✓ via | ✓ via | ✓ via | ✓ | Lifecycle needs the |
llama.cpp ( | always |
| ✓ / ✓ ( | – | – | – | ✓ | One model per server; start with |
Docker Model Runner | always |
| ✓ / – | ✓ progress | on first request | ✓ | ✓ | Enable host-side TCP support in Docker Desktop |
MLX ( |
| – | ✓ / – | – | on first request | – | – | Apple Silicon; switches models per request |
vLLM |
| – | ✓ / ✓ | – | – | – | ✓ |
|
Foundry Local |
| dynamic port | ✓ / ✓ | ✓ progress | ✓ (TTL) | – | – | Find the port with |
OpenAI-compatible (Jan, LocalAI, …) |
| – | ✓ / ✓ | – | – | – | ✓ | Local or hosted, inferred from the host |
Moonshot AI (Kimi) |
|
| ✓ / – | – | – | – | – | Hosted: never selected implicitly |
You can run more than one instance of a runtime, for example a second Ollama box on your LAN, with LOCAL_AI_PROVIDERS='[{"type":"ollama","name":"ollama-gpu2","host":"http://192.168.1.20:11434"}]'. Use LOCAL_AI_DISABLE=lmstudio,dockermodelrunner to skip probing runtimes you don't use.
Privacy model
Each provider is either local or hosted. The kind is inferred from its host: loopback, private LAN ranges,
*.local, Tailscale CGNAT andhost.docker.internalcount as local. You can override it per instance inLOCAL_AI_PROVIDERS.With no
providerargument,complete,embed,delegate,benchmark,load_modeland the other model-scoped tools only consider live local providers that have the model. If the model exists only on a hosted provider, the call fails and tells you how to opt in.Hosted providers are never probed on routine calls. Only
health_checkanddiagnosticscontact them.search_modelswithsource: "huggingface"queries the Hugging Face Hub, and only when you ask it to. SetLOCAL_AI_DISABLE_NETWORK_SEARCH=1to forbid it.The server uses stdio only. It never opens a network listener.
Tools (19)
Every tool declares MCP annotations (read-only, destructive, open-world) and an output schema, and returns structured content.
Group | Tool | What it does |
Discovery |
| Configured runtimes: kind (local/hosted), live status, capabilities |
| Installed models on each live provider | |
| Models resident in memory, with VRAM use and context length | |
| Family, size, quantization, context length and layer architecture | |
Lifecycle |
| Heavy. Downloads to one provider, streaming progress notifications. |
| Check or stop background pulls | |
| Destructive. | |
| One provider, with optional | |
| Pull (if allowed), fit check, evict others ( | |
Ops |
| Reachability, version, runtime metrics |
| Effective config (keys redacted), per-provider detection with latency and errors, speed cache, hardware probe sources. Paste it into bug reports | |
| RAM and GPUs (NVIDIA, AMD, Intel, Apple Silicon), each tagged with its data source | |
| Returns | |
| Heavy. Warmup, then N runs: time-to-first-token, generation and prompt tokens/sec. | |
Registry |
| Built-in offline catalog |
| Best models for a task on this machine: largest that fits on the GPU first, flags installed ones | |
| Live Hugging Face GGUF search with per-quantization fit and pull references ( | |
Delegation |
| Run a completion on a model you choose: system prompt, JSON / JSON-schema output (validated), seed, sampling, images, |
| Embeddings, always one vector per input | |
| One call: picks the best local model for a task (loaded, then installed and fitting, then optionally pulled; larger size tiers first, with speed measured by |
Resources: local-ai://system, local-ai://loaded (subscribable; updates when models load or unload), and local-ai://models/{provider}.
Prompts: setup, free-vram, benchmark-my-models, pick-model.
Configuration
Every setting is an environment variable, and blank means the default. See .env.example for the full annotated list.
Variable | Default | Purpose |
| standard local ports | Always-on runtimes |
| unset | Opt-in runtimes |
| unset | JSON array of extra instances |
| unset | Comma-separated types or names to skip |
| unset, | Hosted Moonshot provider |
| off | Let calls without a |
| off | Forbid Hugging Face search |
| per-user cache dir | Where |
|
| Non-streamed requests |
|
| Detection probes |
|
| Downloads ( |
|
| Abort a stream only if no token arrives for this long |
|
| Hard cap on a streamed completion ( |
|
| Detection and model-list cache |
Troubleshooting
A provider isn't detected. Run
diagnostics(orhealth_check). Check the host and port. From WSL, use the Windows host IP. From a container, usehost.docker.internal. For Docker Model Runner, enable host-side TCP support.LM Studio pull/load fails with "requires the lms CLI". Install the
lmsCLI as described in the LM Studio CLI docs so it is onPATH, then restart your MCP client.llama.cpp
embedfails. Startllama-serverwith--embeddingsand an embedding-capable model.Answers about long inputs look truncated (Ollama). Pass
contextLength(it setsnum_ctx). The result includes a warning when truncation is likely."was not found on any live local provider". The model is either not installed (check
list_models) or only available on a hosted provider. Name that provider explicitly to use it.macOS memory numbers look low.
system_resourcesreports available memory (free, inactive and purgeable pages) and the Metal working-set limit, not total RAM.
Development
npm install
npm run build # tsc -> dist/
npm test # vitest, fully offline (mocked HTTP, stubbed hardware)
npm run lint # Biome
npm run typecheck # src and tests
npm run gen:tools # regenerate mcp-tools.json after changing tools
npm run smoke # boot the built server over stdioCI runs on Linux, Windows and macOS with Node 22 (the minimum supported) and 24. A nightly workflow tests the adapters against real Ollama and llama.cpp. See CONTRIBUTING.md, including Adding a runtime adapter.
Support
Questions and ideas go in Discussions. Report bugs with the issue templates, and security problems through private reporting. If this saves you time, consider sponsoring.
License
CC-BY-NC-ND-4.0. See LICENSE. Contributions are accepted under the DCO and the inbound grant described in CONTRIBUTING.md.
Built by TMHSDigital
Available Tools
22 toolsbenchmarkBenchmarkA
HEAVY: Runs REAL inference. Measures a model on this machine with a warmup (absorbs load time) plus N streamed runs: time-to-first-token, generation tokens/sec (runtime-reported when available, else measured after the first token), and prompt-processing speed. Pass models[] to compare several models with the same prompt, ranked by generation speed.
| Name | Required | Description | Default |
|---|---|---|---|
| runs | No | Measured runs per model (default 3) | |
| model | No | Model id/name to benchmark | |
| models | No | Compare several models (ranked by median generation tokens/sec) | |
| prompt | No | Prompt (default: a short fixed prompt) | |
| warmup | No | Run a 1-token warmup first so load time is excluded (default true) | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| maxTokens | No | Tokens to generate per run (default 128) |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is not read-only, not destructive, and not open-world. The description adds important context beyond annotations: it emphasizes the operation is heavy, runs real inference, uses a warmup to absorb load time, and reports runtime-provided versus measured speeds.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the crucial 'HEAVY' warning and the core purpose, then efficiently covers metrics and the models[] comparison path. Every sentence adds practical information without unnecessary repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema and rich parameter descriptions, the description is largely complete: it explains the benchmark's measurement approach, the warmup, and multi-model comparison. It could still clarify whether a model must be loaded first or how model versus models selection should be handled, but the core behavior is clear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all seven parameters, including warmup behavior and the models[] comparison mode. The description reinforces the models[] comparison semantics and warmup purpose, but adds little beyond the schema's own parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: it runs real inference and measures a model's performance on this machine. It lists concrete metrics (time-to-first-token, generation tokens/sec, prompt-processing speed) and distinguishes itself from ordinary generation tools by framing the operation as measurement and comparison.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly signals the tool's cost profile with 'HEAVY' and explains the comparison use case via 'Pass models[] to compare several models with the same prompt.' However, it does not explicitly say when not to use it or name an alternative such as complete for normal one-off inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
completeDelegated completionARead-only
DELEGATED INFERENCE: Offload a completion to a model you choose for cost savings and privacy. Without provider, runs on the live LOCAL provider that has the model (never a hosted API unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set); the result's 'provider', 'host' and 'local' fields say where it ran. Supports system prompts, JSON / JSON-Schema output (validated 'parsed' field), seed/topP/topK, image inputs for vision models, and contextLength for long inputs. Streams tokens via MCP progress notifications when the client sends a progressToken.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for reproducible sampling | |
| stop | No | Stop sequences | |
| topK | No | ||
| topP | No | ||
| model | Yes | Model id/name to run the completion on | |
| prompt | No | Plain prompt text (alternative to messages) | |
| stream | No | Stream tokens (default true). Progress notifications are sent when the client provides a progressToken. | |
| system | No | System instruction | |
| options | No | Provider-specific extras passed through as-is | |
| messages | No | Chat messages; content may be a string or text/image parts (vision models) | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| maxTokens | No | Maximum tokens to generate | |
| temperature | No | Sampling temperature | |
| contextLength | No | Context window to run with (Ollama num_ctx). Raise it for long inputs to avoid truncation. | |
| repeatPenalty | No | ||
| repairAttempts | No | With a json_schema responseFormat: if the output fails validation, send the errors back to the same model and ask for corrected JSON, up to this many times (default 0, max 2). Token usage covers every attempt. | |
| responseFormat | No | Constrain output to JSON (json_object) or a JSON Schema (json_schema); the result includes a validated 'parsed' value |
Output Schema
| Name | Required | Description |
|---|---|---|
| host | Yes | |
| text | Yes | |
| local | Yes | |
| model | Yes | |
| parsed | No | |
| provider | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/non-destructive/closed-world, so the bar is lower, and the description still adds substantial context: where execution actually lands (`provider`, `host`, `local` fields), the local-only default and the fallback flag, schema-validated `parsed` output, and token streaming via MCP progress notifications when a progressToken is supplied. These are execution facts an agent could not recover from the annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the purpose, then the provider-resolution rule, then a compact feature list, and no sentence is pure filler. It runs long and dense as a single paragraph, which slightly hurts scanability, but the information density justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 17-parameter tool with nested message/responseFormat objects and an output schema, the description covers the behaviors an agent most needs to call it correctly: provider resolution, output locality fields, structured-output validation, vision inputs, context window, and streaming. Remaining gaps are minor since the output schema and 82% schema coverage handle return shape and most parameter detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 82%, so the baseline is 3, and the description earns above that by explaining what the schema only names: contextLength as a num_ctx window that must be raised to avoid truncation on long inputs, responseFormat's validated `parsed` field, and image content parts for vision models. Undocumented-in-prose params such as temperature, topK, stop, and repairAttempts are covered by the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource — offload a completion to a chosen model — and frames the value (cost, privacy). It is clear what the tool does, but it never distinguishes itself from the sibling `delegate` tool, despite the near-identical framing, so an agent must infer the split.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is real usage guidance for the provider parameter (omit it and the server picks a live LOCAL provider; hosted only under LOCAL_AI_ALLOW_HOSTED_FALLBACK), which tells the agent how to call it safely. But there is no explicit statement of when to choose this over `delegate`, `embed`, or `benchmark`, so routing between siblings is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delegateDelegate a task to the best local modelA
ONE CALL to offload work locally: pick the best model for a task on THIS machine, make it ready, and run it. Prefers models already loaded (no load cost), then installed models that fit your free VRAM, then (with allowPull) the best catalog model that fits. Task specialists (coder, vision, reasoning) win over general models; then larger fitting models win, grouped into size tiers (within ~20% parameter count); inside a tier, the model benchmarked fastest on this machine wins (run benchmark to record speeds; results expire after 14 days). Never uses a hosted provider unless allowHosted is true (or, when allowHosted is omitted, LOCAL_AI_ALLOW_HOSTED_FALLBACK is set), and even then any suitable local model is preferred. Models that only fit in system RAM run on CPU when nothing fits the GPU. Returns the completion plus a 'routing' block explaining the choice.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | Seed for reproducible sampling | |
| stop | No | Stop sequences | |
| task | Yes | What kind of work this is | |
| topK | No | ||
| topP | No | ||
| prompt | No | Plain prompt text (alternative to messages) | |
| stream | No | Stream tokens (default true). Progress notifications are sent when the client provides a progressToken. | |
| system | No | System instruction | |
| options | No | Provider-specific extras passed through as-is | |
| fallback | No | If the chosen model fails before producing output (load error, runtime crash, timeout), try the next ranked candidate, up to 3 attempts. Failed attempts are listed in routing.attempts (default false) | |
| messages | No | Chat messages; content may be a string or text/image parts (vision models) | |
| provider | No | Restrict to one provider. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| allowPull | No | Download a catalog model if nothing suitable is installed (default false) | |
| maxTokens | No | Maximum tokens to generate | |
| allowHosted | No | Allow hosted providers as a fallback after local ones. false always excludes them; omitted follows LOCAL_AI_ALLOW_HOSTED_FALLBACK | |
| temperature | No | Sampling temperature | |
| maxSizeBytes | No | Ignore models larger than this | |
| contextLength | No | Context window to run with (Ollama num_ctx). Raise it for long inputs to avoid truncation. | |
| repeatPenalty | No | ||
| repairAttempts | No | With a json_schema responseFormat: if the output fails validation, send the errors back to the same model and ask for corrected JSON, up to this many times (default 0, max 2). Token usage covers every attempt. | |
| responseFormat | No | Constrain output to JSON (json_object) or a JSON Schema (json_schema); the result includes a validated 'parsed' value |
Output Schema
| Name | Required | Description |
|---|---|---|
| text | Yes | |
| model | Yes | |
| routing | Yes | |
| provider | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the safety profile (not read-only, open-world, not idempotent), and the description adds substantial behavior beyond that: the full routing preference order, the no-load-cost preference, VRAM-fit and CPU-fallback behavior, the 14-day benchmark expiry, and the env var controlling hosted fallback. It also discloses that the response carries a 'routing' block, which the annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the headline 'ONE CALL' and then organized by ranking rules, hosted policy and return shape; nearly every clause carries information. Minor redundancy where allowHosted's env-var behavior is restated in both the description and the schema, and the paragraph is dense enough to be slightly hard to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 21-parameter composite tool with an output schema, the description covers the decision logic an agent needs to call it correctly, and correctly defers return-shape details to the schema. It does not note that one of prompt or messages is effectively required, which is the main remaining gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 86%, so the baseline is 3, but the description adds meaning that the schema lacks: how the task enum maps to specialist vs general model tiers, the ~20% size-tier grouping and benchmark tie-break, and the interaction between allowPull/allowHosted and local availability. Parameters such as maxSizeBytes, contextLength and repairAttempts are not elaborated beyond their schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'ONE CALL to offload work locally: pick the best model for a task on THIS machine, make it ready, and run it.' This distinguishes the composite routing tool from single-purpose siblings like complete, suggest_model, ensure_model and load_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit selection conditions for hosted vs local ('Never uses a hosted provider unless allowHosted is true...') and the allowPull gate, plus points to the benchmark sibling for recording speeds. It does not explicitly say when to prefer a sibling such as complete or suggest_model instead, leaving that to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diagnosticsDiagnosticsARead-onlyIdempotent
One read-only snapshot for troubleshooting: the effective configuration (API keys never shown, only whether one is set), every configured provider with its detection result, latency and error, the benchmark speed cache, and how hardware was probed. Paste its output into bug reports.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| config | Yes | |
| hardware | Yes | |
| providers | Yes | |
| speedCache | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered; the description adds genuinely new context by disclosing redaction behavior ('API keys never shown, only whether one is set'). It also notes the snapshot actively probes providers and hardware, implying latency cost, though it does not state how long the probe takes or how large the output is.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence whose key claim ('read-only snapshot for troubleshooting') comes first, followed by the contents and the intended use. The comma-separated inventory is dense but every clause carries information; a bulleted list would read better but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, yet it still previews the payload contents so an agent knows what it is getting. Combined with rich annotations and zero parameters, nothing an agent needs in order to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4 and there is nothing for the description to disambiguate. No misleading parameter references appear.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific deliverable ('one read-only snapshot for troubleshooting') and then enumerates exactly what it contains: effective configuration, per-provider detection result, latency and error, benchmark speed cache, and hardware probing. That enumeration clearly separates it from siblings like health_check, system_resources, and fit_check, which each cover only part of this picture.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete use context ('for troubleshooting') and an explicit next action ('paste its output into bug reports'), so an agent knows the intended scenario. It stops short of naming when-not-to-use it or pointing to alternatives such as health_check for a quick liveness probe, which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
embedDelegated embeddingsARead-onlyIdempotent
DELEGATED EMBEDDINGS: Generate embeddings for a string or an array of texts. Without provider, runs on the live local provider that has the model. Always returns one vector per input.
| Name | Required | Description | Default |
|---|---|---|---|
| input | Yes | Text or array of texts to embed | |
| model | Yes | Embedding model id/name | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| host | Yes | |
| local | Yes | |
| model | Yes | |
| provider | Yes | |
| dimensions | Yes | |
| embeddings | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, and closed-world, so safety is covered. The description adds the default routing behavior (live local provider holding the model) and a one-vector-per-input guarantee, but the routing detail is largely restated in the provider schema description, so added value is modest.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with the core capability front-loaded and no filler. The 'DELEGATED EMBEDDINGS:' prefix mildly duplicates the title but otherwise every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return shape needn't be explained, and all three parameters are fully described in the schema. The description covers routing defaults and output cardinality, leaving only minor gaps such as error behavior for unsupported models.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, including the provider enum and the meaning of omitting it, so the baseline is 3. The description adds no syntax, batching, or model-selection semantics beyond what the schema already documents.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Generate embeddings') and the accepted input shapes ('a string or an array of texts'). It is clearly distinct from siblings like complete or delegate by resource, but the description never names an alternative to contrast against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Without provider, runs on the live local provider that has the model' gives context for the optional provider path, but there is no explicit when-to-use guidance versus siblings such as complete or fit_check, and no stated exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ensure_modelEnsure model is readyAIdempotent
Make a model ready in one call: optionally pull it, check it fits current free VRAM, unload other models if needed (evict: 'lru' or 'all'), load it, and verify. Use dryRun:true to get the plan without changing anything.
| Name | Required | Description | Default |
|---|---|---|---|
| evict | No | Unload other models to make room: none (default), lru (least recently used first), all | |
| model | Yes | Model id/name | |
| dryRun | No | Return the plan only (default false) | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| allowPull | No | Download the model if it is not installed (default false) | |
| keepAlive | No | Keep-alive for the loaded model, e.g. '30m' | |
| kvCacheType | No | KV cache precision used for the fit estimate (default f16) | |
| contextLength | No | Context window to fit and load with (default 4096) |
Output Schema
| Name | Required | Description |
|---|---|---|
| fit | No | |
| plan | Yes | |
| model | Yes | |
| ready | Yes | |
| provider | Yes | |
| verified | No | false when the runtime could not be asked whether the model is loaded after loading it |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare a non-read-only but non-destructive, idempotent, open-world operation; the description adds the material detail that it may download a model, may unload OTHER loaded models (evict 'lru' or 'all'), and verifies afterward. That side effect on shared state is exactly the kind of context annotations alone would hide, especially given destructiveHint=false. It stops short of saying what happens on fit failure or whether evictions are restored.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense sentence front-loads the outcome and the pipeline in execution order, followed by a single sentence covering the safe-preview mode. There is no filler, and the ordering mirrors how the operation actually proceeds.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, full schema coverage, and rich annotations, the description only needs to convey the composite behavior and side effects, which it does. Minor gaps remain around failure modes (what if the model cannot fit even after eviction) and what the verify step returns, but nothing blocking is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter, including the evict enum and dryRun, is already documented in the schema. The description restates pull, evict values, and dryRun without adding semantics such as how kvCacheType or contextLength affect the fit estimate. Baseline 3 applies when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete outcome ('make a model ready') and enumerates the exact pipeline it composes: pull, VRAM fit check, evict, load, verify. Because those steps correspond directly to siblings like pull_model, fit_check, load_model, and unload_model, an agent can immediately tell this is the one-call orchestrator rather than any single-step tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only explicit usage guidance is 'Use dryRun:true to get the plan without changing anything,' which covers the planning case well. There is no statement of when to prefer this over the granular siblings (e.g. when you already know the model is pulled, or when you want to inspect before committing), so the agent must infer the orchestration-vs-single-step tradeoff.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fit_checkFit checkARead-onlyIdempotent
Will a model run on this machine, and where? Uses the installed model's size and exact layer architecture when the runtime exposes it (else parameter-count or catalog estimates) to size weights + KV cache for a context length, then compares with free VRAM summed across GPUs and available RAM. Returns target gpu / partial (GPU+CPU split) / cpu / none, with the numbers and how the KV estimate was made. Credits back memory the model already uses if it is loaded.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to check | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| sizeBytes | No | Explicit weight size in bytes (overrides lookup) | |
| kvCacheType | No | KV cache precision: f16 (default), q8_0, q4_0 | |
| contextLength | No | Context length for the KV-cache estimate (default 4096) | |
| parameterSize | No | Parameter size like "7B" (overrides lookup) |
Output Schema
| Name | Required | Description |
|---|---|---|
| fits | Yes | |
| note | Yes | |
| model | Yes | |
| loaded | Yes | |
| target | Yes | |
| sizeSource | Yes | |
| requiredBytes | Yes | |
| availableBytes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals complex internal behavior beyond annotations, detailing how it uses model architecture, estimates memory for weights and KV cache, and crucially, how it credits back memory for already loaded models.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite being a long paragraph, the description is highly efficient. It flows logically from the question (will it run?) to the mechanism (calculation) to the output (target resource), with no redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the technical complexity involving VRAM, KV cache, and resource allocation strategies, the description is complete. It details all necessary components of the check, including fallback mechanisms and memory accounting.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description is highly semantic, explaining exactly which parameters drive the resource calculation—for instance, referencing 'layer architecture' and 'KV cache for a context length.' This adds significant value over the 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to determine if a model will run on the machine and precisely where (GPU/CPU/Partial). It distinguishes itself by focusing on resource compatibility rather than merely listing models.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While it does not explicitly name sibling tools it replaces, its function is clearly defined as a resource pre-check prerequisite, which provides sufficient operational context for its use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
health_checkHealth checkARead-onlyIdempotent
Check whether each provider is reachable and report its version (and live metrics such as vLLM KV-cache usage). Without provider, checks every configured provider, including hosted ones.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| health | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered and the description correctly stays consistent with it. It adds that version and live metrics are reported, which is useful behavioral context. However, the claim that omitting the provider checks every configured provider 'including hosted ones' conflicts with the schema's statement that omission restricts to local providers unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set — a misleading scope claim in the description itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action and with the no-argument scope stated second; nothing is padding. The only cost is that the second sentence introduces an inaccurate scope claim rather than a needed clarification.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values, and rich annotations cover the safety profile. What an agent needs to call it correctly is present. It loses a point because the hosted-provider default is stated in a way that contradicts the schema, potentially causing wrong expectations about which providers get probed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter has a documented enum and a detailed omit-behavior note, so the schema does the heavy lifting. The description's 'Without provider...' sentence partially duplicates that note but adds nothing about the enum values themselves. Baseline 3 applies when the schema fully documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource ('check whether each provider is reachable and report its version'), which clearly separates it from sibling tools like list_providers or model_info. It also names the metrics returned (vLLM KV-cache usage), giving the agent a concrete idea of output. It stops short of explicitly naming the sibling it should be preferred over, so a 4 rather than a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The second sentence explains the no-argument behavior ('checks every configured provider'), which is about scope rather than when to call it. There is no explicit guidance such as 'use before load_model to verify a provider is up' or 'use list_providers instead when you only need configured names', so usage must be inferred from the tool name and sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_loadedList loaded modelsARead-onlyIdempotent
List models currently loaded into memory on each live provider, with VRAM use and context length where the runtime reports them.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| loaded | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only and idempotent semantics, so the description is not asked to carry the safety profile. It adds real behavioral context the annotations cannot: it is a point-in-time snapshot of live providers, and metrics are conditional ("where the runtime reports them"), warning the agent that VRAM and context length may be absent rather than zero.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence: scope first, reported metrics second, the caveat about incomplete reporting last. No filler and nothing repeated from the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not enumerate return fields, and it correctly stays out of that territory while still flagging that per-model metrics are best-effort. It stops just short of telling the agent that omitting provider aggregates across all live providers versus querying a single one.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single optional provider parameter is fully documented in the schema, including the omit-to-let-server-choose behavior and the hosted-fallback caveat. The description only echoes the result of omission with "on each live provider"; per the high-coverage baseline, 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List models") plus a scope qualifier that does real work: "currently loaded into memory on each live provider." That qualifier is what separates it from the sibling list_models, so an agent can pick between them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase "currently loaded" implies you call this when you need to know what is resident right now rather than what is available on disk, but no alternative (list_models, model_info, list_providers) is named and no when-not condition is given. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_modelsList installed modelsARead-onlyIdempotent
List models installed/available on each live provider, keyed by provider. Pass provider to query just one.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| models | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive, closed-world behavior, so the safety profile is covered. The description adds that results are keyed by provider and scoped to 'live' providers, but it does not mention other behavioral details such as error handling or the hosted-fallback caveat that appears in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no wasted words, and the main capability is front-loaded before the optional filtering note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, rich annotations, and complete parameter documentation, the description is largely sufficient. It could be slightly stronger by distinguishing this tool from list_loaded or clarifying what 'available' means relative to installed models.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the enum and provider description are already fully documented, including the hosted-fallback condition. The description's note that passing 'provider' queries just one provider adds only modest reinforcement and does not go beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('List models') and clarifies scope ('installed/available on each live provider, keyed by provider'). It is clear enough to distinguish from list_providers, but it does not explicitly contrast with the sibling list_loaded, which likely covers a related concept.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage by noting that passing 'provider' queries just one provider, which is useful guidance. However, it does not say when to use this versus list_loaded, search_available, or model_info, so the agent must infer the distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_providersList providersARead-onlyIdempotent
List configured model runtimes (Ollama, LM Studio, llama.cpp, Docker Model Runner, and any opt-in MLX / vLLM / Foundry Local / OpenAI-compatible / hosted instances) with host, kind (local or hosted), live status, and capabilities.
| Name | Required | Description | Default |
|---|---|---|---|
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| providers | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the safety guarantees provided by the annotations (readOnly, idempotent), the description specifies exactly what data points are returned (host, kind, live status, capabilities). This provides valuable structural context to the agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but efficient. Despite its length, it packs significant value into one statement by listing all supported technologies and the data elements returned, making the sentence highly functional.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is extremely comprehensive. Given the presence of an output schema (handled by contextual completeness rules), listing all potential return fields (host, kind, status, capabilities) in the description provides a complete picture of the tool's capabilities.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the baseline is high. The description adds semantic value by listing all the supported runtime types, effectively defining the universe of the `provider` enum before the agent even checks the schema structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The tool's purpose is highly specific: to list configured model runtimes. It explicitly enumerates the types of runtimes it supports (Ollama, LM Studio, vLLM, hosted instances), making its function unambiguous compared to list_models or list_loaded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While it does not explicitly state 'use this for listing infrastructure, not models,' the strong focus on 'model runtimes' provides sufficient distinction from sibling tools like list_models. Its usage scope is clearly defined, even if direct exclusionary guidelines are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_modelLoad modelAIdempotent
Load a model into memory on ONE provider so it is ready for inference. Optional keepAlive (e.g. '5m', '1h') and contextLength. Without provider, uses the live local provider that has the model.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to load | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| keepAlive | No | How long to keep the model resident, e.g. '5m' | |
| contextLength | No | Context window to load with (Ollama num_ctx, LM Studio --context-length) |
Output Schema
| Name | Required | Description |
|---|---|---|
| load | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered structurally. The description adds some context — the fallback to the 'live local provider that has the model' and residency via keepAlive — but does not say what happens if no local provider has the model (error vs. implicit download), nor that loading reserves memory and may evict existing residency. That omission matters for a non-destructive but resource-consuming mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the action and outcome, then optional parameters, then the default-provider rule. There is no filler and every clause carries information the agent needs before calling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations carry the safety profile, so the description needn't explain return values; what it does cover is targeted and sufficient for a 4-parameter tool. It falls short of 5 because the failure mode when the model is absent locally — the most likely error path given the sibling `ensure_model`/`pull_model` tools — is unaddressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a baseline of 3 applies, and the description does add meaning beyond the schema by explaining the operational consequence of omitting `provider` ('uses the live local provider that has the model') rather than just 'let the server choose'. The keepAlive and contextLength mentions largely restate the schema, so it stops short of a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Load a model into memory') plus the outcome ('ready for inference'), which tells an agent this is a load/warm-up step rather than an inference call. The 'on ONE provider' constraint scopes the operation, but the description never differentiates itself from the closely related sibling `ensure_model` (or `pull_model`), leaving the agent to guess which is appropriate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the outcome statement and by the default rule 'Without provider, uses the live local provider that has the model.' Nothing tells the agent when to prefer this over `ensure_model`, `pull_model`, or `list_loaded` first, and no preconditions (must the model already exist locally?) are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
model_infoModel infoARead-onlyIdempotent
Detailed metadata for one model (family, parameter size, quantization, context length, and layer architecture where available). Without provider, queries the live local providers that have the model.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to inspect | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| info | Yes | |
| model | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false. The description adds that provider omission queries live local providers and that some fields are available only 'where available,' but it does not cover error behavior, latency, or ambiguities beyond what annotations and schema provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core purpose and then the key provider behavior. No unnecessary repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only metadata tool with an output schema and fully described parameters, the description is largely complete. Minor gaps around not-found behavior or ambiguity handling remain, but the core invocation context is covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the schema. The description does not add syntax or semantic detail beyond the schema's provider fallback notes, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific resource (one model) and enumerates the metadata returned (family, parameter size, quantization, context length, layer architecture). It is distinct from list-style siblings, but it does not explicitly name or contrast with list_models/list_loaded.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains the provider-omission behavior ('Without provider, queries the live local providers that have the model'), which implies usage context. However, it does not explicitly say when to use this tool versus list_models, list_loaded, or other sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_cancelCancel pullAIdempotent
Stop a background pull started with pull_model { background: true }. Finished jobs are returned unchanged.
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | Yes | Job id returned by pull_model |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnly=false, idempotent=true and destructive=false, so the safety profile is covered. The description adds one useful behavioral fact — completed jobs are returned unchanged, reinforcing the idempotent semantics — but says nothing about what happens to in-flight state, partial downloads, or whether resources are freed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, zero filler, with the scoping condition (background:true) front-loaded and the edge-case behavior second. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter mutation with rich annotations and an output schema (so return values need no explanation), this is nearly complete; the only missing piece is what an agent should do if the job is already finished or unknown, and whether partially downloaded data is retained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single jobId parameter is already documented as "Job id returned by pull_model". The description reinforces the provenance of that id via the pull_model reference but adds no format, validation, or error-case semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Stop a background pull") and qualifies it with the exact originating call (pull_model { background: true }), which cleanly separates it from the sibling pull_status (which monitors rather than cancels).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear precondition for use: only pulls started with background:true are cancellable, implying foreground pulls are out of scope. It does not explicitly name an alternative (e.g. pull_status for monitoring progress) or state what to do if the job already completed, so it falls short of full when/when-not routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_modelPull modelAIdempotent
HEAVY: Download a model onto ONE provider (multiple GB, can take a long time). Streams download progress via MCP progress notifications when the client sends a progressToken. With background:true, returns a jobId immediately instead; poll pull_status and stop it with pull_cancel (use this when the client has no progress display or a short tool timeout). Without provider, uses the provider that already has the model, else the first live local provider that can pull.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to pull (e.g. qwen3:8b, hf.co/<repo>:<quant>) | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). | |
| background | No | Return a jobId at once and download in the background (default false). A second call for the same model joins the running job. |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | No | |
| pull | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description carries substantial behavior beyond the annotations: multi-GB size, long duration, streaming via MCP progress notifications gated on a progressToken from the client, an immediate jobId under background:true, and provider selection fallback (already-has-model, else first live local provider, with LOCAL_AI_ALLOW_HOSTED_FALLBACK as the hosted escape hatch). The "a second call for the same model joins the running job" note gives concrete meaning to idempotentHint:true, and nothing conflicts with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The cost warning is front-loaded as the first token ("HEAVY:"), then progress mode, then background mode, then provider resolution — an efficient ordering with no filler sentences. Every clause either sets expectations or changes how the agent should call it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a heavyweight, long-running, job-capable tool this covers the operational facts an agent needs: cost, progress mechanics, async path and its polling/cancel siblings, and provider resolution defaults. An output schema is declared, so return-value documentation is correctly omitted from the description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage the schema already explains all three parameters, so this starts at baseline 3. The description adds genuine semantics the schema does not: what happens when provider is omitted (existing-model preference, then first live local provider, hosted only under an env flag) and the deduplication behavior of repeated background calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"HEAVY: Download a model onto ONE provider" gives a specific verb and resource plus an explicit scoping constraint (single provider), and the surrounding text carves it apart from pull_status and pull_cancel by role (this one starts the download; those poll and stop it). An agent can tell immediately that this is the initiating operation rather than a status or management call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a concrete decision rule for the background mode ("use this when the client has no progress display or a short tool timeout") and names the follow-up tools to poll and cancel, which is real when-to-use guidance. It does not address when to prefer ensure_model over an explicit pull, so one obvious sibling comparison is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_statusPull statusARead-onlyIdempotent
Status of background pulls started with pull_model { background: true }: state (running, done, failed, cancelled), progress, and result or error. Without jobId, lists every job this server remembers (finished jobs are kept for an hour; jobs are forgotten on restart).
| Name | Required | Description | Default |
|---|---|---|---|
| jobId | No | Job id returned by pull_model |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the description doesn't need to restate that. It instead adds genuinely non-obvious behavior: finished jobs are retained for only an hour and all jobs are forgotten on restart, which tells the agent that a missing jobId result is not necessarily an error. It could go further on cost or size of the full listing, but the retention caveats are the important ones.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact clauses: the primary purpose and return fields first, then the no-jobId fallback and retention caveat in a parenthetical. Nothing is repeated from the schema or annotations, and no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with an output schema, the description covers the state model, the fallback listing mode, and the retention/restart limits — everything needed to interpret results correctly. The only small omission is whether a running job survives a server restart in any form, but the 'forgotten on restart' note largely implies the answer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: without jobId the call switches from a single-job lookup to a full job listing. That optionality behavior is not evident from a bare optional string field, so it earns above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource (background pulls initiated by pull_model with background: true) and enumerates exactly what is returned: state (running, done, failed, cancelled), progress, and result or error. This clearly separates it from pull_model (which starts jobs) and pull_cancel (which cancels them).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It establishes the trigger context — use this after starting a background pull — and explains the two calling modes: pass jobId for one job, omit it to list all remembered jobs. There is no explicit statement about when to prefer polling this versus other status surfaces, and pull_cancel is never mentioned, but the usage context is otherwise unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_modelRemove modelADestructive
DESTRUCTIVE: Permanently delete a model from one provider. provider is REQUIRED (no fan-out). If the client supports elicitation the user is asked to confirm directly; otherwise confirm:true is required.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to remove | |
| confirm | No | Must be true when the client cannot ask the user directly (no elicitation support) | |
| provider | Yes | Provider to delete from (required). Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| remove | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and non-idempotent behavior, but the description adds useful operational detail about permanence and the confirmation flow. However, the claim that provider is REQUIRED (no fan-out) conflicts with the schema property text saying provider may be omitted to let the server choose, which weakens the behavioral guidance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with DESTRUCTIVE and is very compact. Every clause contributes either safety, required-parameter, or confirmation behavior, with no wasted text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotations covering safety and an output schema covering return values, the description supplies the key missing context: permanence and the confirmation/elicitation fallback. It would be more complete if it resolved the provider-optional conflict and explicitly contrasted remove_model with unload_model.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already defines all three parameters. The description adds the no-fan-out requirement and clarifies confirmation behavior, but its provider-required claim conflicts with the provider property description that says omitting provider lets the server choose, making the added semantic value only partly reliable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific destructive verb and resource: permanently delete a model from one provider. It also scopes the operation to a single provider and no fan-out, which helps distinguish it from broader or memory-only sibling operations such as unload_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear usage context: this is destructive, provider is required, and confirmation is handled through elicitation or the confirm:true fallback. It does not explicitly name unload_model as the non-destructive alternative, so the when-not guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_availableSearch catalogARead-onlyIdempotent
Search the built-in curated catalog of well-known local models (Ollama tags) by name, family, or task. Offline and instant. For live results with per-quant fit, use search_models with source 'huggingface'.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Search text matched against model name, family, and tasks |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| query | Yes | |
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already cover safety and idempotency, but the description adds useful behavioral context: the catalog is built-in, local, offline, and instant. It does not detail result limits or ranking behavior, but that is a minor gap given the rich annotations and output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three tightly written sentences with no filler. The core purpose and the sibling alternative are both front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only search tool with full schema coverage, rich annotations, and an output schema, the description provides everything needed to select and invoke it correctly. The offline/curated scope and the search_models alternative are sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the query parameter is already well documented. The description reinforces that matching applies to model name, family, and tasks, but adds little beyond the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: searching the built-in curated catalog of well-known local models. It also distinguishes the tool from the sibling search_models by contrasting offline curated results with live Hugging Face results.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative search_models and the condition for choosing it: live results with per-quant fit. This gives the agent a clear routing rule between the two search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_modelsSearch models (live)ARead-onlyIdempotent
Find models to download, annotated with whether each fits this machine. source 'huggingface' searches GGUF repos on the Hugging Face Hub and returns per-quant sizes, the best quant for this hardware, and pullable references (Ollama: hf.co/:). source 'catalog' searches the offline curated list. The Ollama library has no public search API, so it is not a source.
| Name | Required | Description | Default |
|---|---|---|---|
| task | No | Catalog source only: filter by task | |
| limit | No | Max repos (default 8) | |
| query | Yes | Search text, e.g. 'qwen coder' or 'gemma 3' | |
| source | No | Default huggingface | |
| fitsOnly | No | Only return results with a quant that fits | |
| contextLength | No | Context length for fit (default 4096) |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| source | Yes | |
| results | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/idempotent, so the safety bar is low; the description still adds real behavior: live network search of GGUF repos, per-quant size returns, best-quant-for-this-hardware annotation, and pullable references in Ollama form. It does not mention latency, rate limits, or failure behavior for the remote source.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences: purpose first, then source semantics, then the negative constraint. Every sentence carries information an agent needs, and the exclusion is placed last so it doesn't bury the main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still sketches the return shape (quant sizes, best-fit quant, pullable reference), which is more than required. With annotations and full schema coverage present, nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3; the description goes beyond it by explaining that results carry fit annotations, which gives meaning to the otherwise thin fitsOnly and contextLength parameters, and by characterizing each source value. It doesn't clarify limit defaults or query matching semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Find models to download") plus the value-add of hardware-fit annotation, and defines each source mode concretely. It does not name competing siblings such as search_available or suggest_model, so an agent still has to infer which search tool to pick.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains the 'huggingface' vs 'catalog' choice with the consequence of each, and explicitly rules out a third source ("The Ollama library has no public search API, so it is not a source"), which prevents a wasted call. No guidance on when to prefer this over suggest_model or search_available.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_modelSuggest modelARead-onlyIdempotent
Recommend catalog models for a task, ranked for THIS machine: fully-on-GPU first, then partial GPU offload, then CPU-only. Within a tier the largest (most capable) model comes first unless preferSpeed is true. Flags models already installed on a live provider and explains each pick.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | The task you want a model for | |
| kvCacheType | No | KV cache precision (default f16) | |
| preferSpeed | No | Prefer smaller, faster models within each tier | |
| contextLength | No | Context length to plan for (default 4096) |
Output Schema
| Name | Required | Description |
|---|---|---|
| task | Yes | |
| suggestions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a safe, idempotent, closed-world read, so the safety profile needs no restating. The description adds real behavioral value beyond that: the exact ranking order (full GPU → partial offload → CPU), the within-tier tie-break, and that installed models are flagged on a live provider.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences, front-loaded with purpose then ranking rules then output traits. No filler and every clause carries information an agent needs to interpret results.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the description still covers the semantics of the ranking, the tie-break, and the installed-model flag. Nothing an agent needs in order to call and interpret this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the four parameters are already documented and 3 would be the baseline. The description earns one more point by explaining how preferSpeed actually interacts with tier ordering ('largest comes first unless preferSpeed is true'), which the schema's one-liner does not make explicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Recommend catalog models for a task') plus the key differentiator: ranked for THIS machine. An agent can separate this from list_models, list_available, or fit_check without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context for when to call it (you have a task and want a ranked recommendation), and the tiering rules imply it is the right tool when hardware fit matters. It never names an alternative such as fit_check or list_models, nor states exclusions, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
system_resourcesSystem resourcesARead-onlyIdempotent
Report local hardware: platform, total/available RAM, CPU count, and GPUs with total/free VRAM (NVIDIA via nvidia-smi, AMD/Intel via sysfs or the Windows registry, Apple Silicon unified memory). Each GPU names its data source.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| gpus | Yes | |
| cpuCount | Yes | |
| platform | Yes | |
| ramFreeBytes | Yes | |
| ramTotalBytes | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds genuinely new context beyond that: the per-platform discovery mechanisms (nvidia-smi, sysfs, Windows registry, Apple Silicon unified memory) and the guarantee that each GPU reports its data source, which tells the agent how much to trust the VRAM figures.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences, front-loaded with the returned fields before the platform-detection detail. Every clause carries information, though the parenthetical enumeration of OS-specific mechanisms is heavy for a definition whose output schema already documents the shape.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not describe return structure, and it still previews the key fields and the data-source provenance. For a zero-parameter, read-only inventory tool, nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly implies a parameterless call with no scoping options.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("Report") and resource ("local hardware") and enumerates exactly what is returned: platform, total/available RAM, CPU count, GPUs with total/free VRAM. This is unmistakably distinct from the sibling set, which is entirely model-management and inference tooling; no sibling could be confused with a hardware inventory read.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the tool to consult for host capacity, but the description never says when to reach for it versus siblings like health_check, fit_check, or list_providers. No exclusions or prerequisites are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unload_modelUnload modelAIdempotent
Unload a model from memory to free VRAM/RAM on ONE provider. Without provider, uses the live local provider that has it loaded.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | Model id/name to unload | |
| provider | No | Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set). |
Output Schema
| Name | Required | Description |
|---|---|---|
| unload | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover mutation safety: readOnlyHint=false, destructiveHint=false, idempotentHint=true. The description adds useful context beyond annotations by clarifying that unloading frees memory, applies to exactly ONE provider, and defaults to the live local provider that has the model loaded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, both front-loaded and substantive. The memory-freeing purpose comes first, followed by the provider default, with no wasted wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has rich annotations, full schema coverage, and an output schema, so the description need not explain return values. It is complete enough to call correctly, though it could note what happens if the model is not loaded or clarify that the model remains on disk.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter meaning is already well documented. The description still adds value by explaining the provider default more concretely: without provider, it uses the live local provider that has the model loaded, complementing the schema's server-choice wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: unloading a model from memory to free VRAM/RAM, scoped to one provider. It is clear what the tool does, though it does not explicitly differentiate itself from siblings like remove_model or load_model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'to free VRAM/RAM' implies when to use the tool, and the provider default is explained. However, there is no explicit guidance on when to choose this over remove_model, list_loaded, or load_model, nor any stated exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
7 tool updates
v0.6.1- Changed
complete1 field changed- added
Input schema / properties / repairAttemptsAdded value: +{ + "description": "With a json_schema responseFormat: if the output fails validation, send the errors back to the same model and ask for corrected JSON, up to this many times (default 0, max 2). Token usage covers every attempt.", + "maximum": 2, + "minimum": 0, + "type": "integer" +}
- Changed
delegate3 fields changed- changed
Input schema / properties / allowHosted / descriptionPrevious value: -"Allow hosted providers (default false)"New value: +"Allow hosted providers as a fallback after local ones. false always excludes them; omitted follows LOCAL_AI_ALLOW_HOSTED_FALLBACK" - added
Input schema / properties / fallbackAdded value: +{ + "description": "If the chosen model fails before producing output (load error, runtime crash, timeout), try the next ranked candidate, up to 3 attempts. Failed attempts are listed in routing.attempts (default false)", + "type": "boolean" +} - added
Input schema / properties / repairAttemptsAdded value: +{ + "description": "With a json_schema responseFormat: if the output fails validation, send the errors back to the same model and ask for corrected JSON, up to this many times (default 0, max 2). Token usage covers every attempt.", + "maximum": 2, + "minimum": 0, + "type": "integer" +}
- Added
diagnostics - Changed
ensure_model1 field changed- added
Output schema / properties / verifiedAdded value: +{ + "description": "false when the runtime could not be asked whether the model is loaded after loading it", + "type": "boolean" +}
- Added
pull_cancel - Changed
pull_model3 fields changed- added
Input schema / properties / backgroundAdded value: +{ + "description": "Return a jobId at once and download in the background (default false). A second call for the same model joins the running job.", + "type": "boolean" +} - added
Output schema / properties / jobAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "pull" -]
- Added
pull_status
19 tool updates
v0.5.0- Changed
benchmark13 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / maxTokens / descriptionPrevious value: -"Max tokens to generate (default 64)"New value: +"Tokens to generate per run (default 128)" - added
Input schema / properties / maxTokens / exclusiveMinimumAdded value: +0 - added
Input schema / properties / maxTokens / maximumAdded value: +9007199254740991 - changed
Input schema / properties / maxTokens / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / modelsAdded value: +{ + "description": "Compare several models (ranked by median generation tokens/sec)", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Input schema / properties / prompt / descriptionPrevious value: -"Optional prompt; a short default is used otherwise"New value: +"Prompt (default: a short fixed prompt)" - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - added
Input schema / properties / runsAdded value: +{ + "description": "Measured runs per model (default 3)", + "maximum": 20, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / warmupAdded value: +{ + "description": "Run a 1-token warmup first so load time is excluded (default true)", + "type": "boolean" +} - removed
Input schema / requiredRemoved value: -[ - "model" -] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "results": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "results" + ], + "type": "object" +}
- Changed
complete20 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contextLengthAdded value: +{ + "description": "Context window to run with (Ollama num_ctx). Raise it for long inputs to avoid truncation.", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / maxTokens / exclusiveMinimumAdded value: +0 - added
Input schema / properties / maxTokens / maximumAdded value: +9007199254740991 - changed
Input schema / properties / maxTokens / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / messages / descriptionPrevious value: -"Chat-style messages (alternative to prompt)"New value: +"Chat messages; content may be a string or text/image parts (vision models)" - removed
Input schema / properties / messages / items / additionalPropertiesRemoved value: -false - added
Input schema / properties / messages / items / properties / content / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "anyOf": [ + { + "properties": { + "text": { + "type": "string" + }, + "type": { + "const": "text", + "type": "string" + } + }, + "required": [ + "type", + "text" + ], + "type": "object" + }, + { + "properties": { + "data": { + "description": "Base64 image data (no data: prefix)", + "type": "string" + }, + "mimeType": { + "type": "string" + }, + "type": { + "const": "image", + "type": "string" + }, + "url": { + "description": "Image URL or data: URL", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + } + ] + }, + "type": "array" + } +] - removed
Input schema / properties / messages / items / properties / content / typeRemoved value: -"string" - added
Input schema / properties / optionsAdded value: +{ + "additionalProperties": {}, + "description": "Provider-specific extras passed through as-is", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - added
Input schema / properties / repeatPenaltyAdded value: +{ + "type": "number" +} - added
Input schema / properties / responseFormatAdded value: +{ + "anyOf": [ + { + "properties": { + "type": { + "const": "json_object", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "properties": { + "name": { + "type": "string" + }, + "schema": { + "additionalProperties": {}, + "description": "JSON Schema the output must satisfy", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": { + "const": "json_schema", + "type": "string" + } + }, + "required": [ + "type", + "schema" + ], + "type": "object" + } + ], + "description": "Constrain output to JSON (json_object) or a JSON Schema (json_schema); the result includes a validated 'parsed' value" +} - added
Input schema / properties / seedAdded value: +{ + "description": "Seed for reproducible sampling", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - changed
Input schema / properties / stream / descriptionPrevious value: -"Stream tokens from the provider (default true). Progress notifications are sent when the client provides a progressToken."New value: +"Stream tokens (default true). Progress notifications are sent when the client provides a progressToken." - added
Input schema / properties / systemAdded value: +{ + "description": "System instruction", + "type": "string" +} - added
Input schema / properties / topKAdded value: +{ + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Input schema / properties / topPAdded value: +{ + "type": "number" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "host": { + "type": "string" + }, + "local": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "parsed": {}, + "provider": { + "type": "string" + }, + "text": { + "type": "string" + } + }, + "required": [ + "provider", + "host", + "local", + "model", + "text" + ], + "type": "object" +}
- Added
delegate - Changed
embed4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "dimensions": { + "type": "number" + }, + "embeddings": { + "items": { + "items": { + "type": "number" + }, + "type": "array" + }, + "type": "array" + }, + "host": { + "type": "string" + }, + "local": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "host", + "local", + "model", + "embeddings", + "dimensions" + ], + "type": "object" +}
- Added
ensure_model - Changed
fit_check12 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / contextLength / descriptionPrevious value: -"Context length for KV-cache estimate (default 4096)"New value: +"Context length for the KV-cache estimate (default 4096)" - added
Input schema / properties / contextLength / exclusiveMinimumAdded value: +0 - added
Input schema / properties / contextLength / maximumAdded value: +9007199254740991 - changed
Input schema / properties / contextLength / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / kvCacheTypeAdded value: +{ + "description": "KV cache precision: f16 (default), q8_0, q4_0", + "enum": [ + "f16", + "q8_0", + "q4_0" + ], + "type": "string" +} - changed
Input schema / properties / parameterSize / descriptionPrevious value: -"Optional parameter size like \"7B\" or \"3.8B\" for KV estimate (overrides lookup)"New value: +"Parameter size like \"7B\" (overrides lookup)" - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Input schema / properties / sizeBytes / descriptionPrevious value: -"Optional explicit model weight size in bytes (overrides lookup)"New value: +"Explicit weight size in bytes (overrides lookup)" - added
Input schema / properties / sizeBytes / exclusiveMinimumAdded value: +0 - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "availableBytes": { + "type": "number" + }, + "fits": { + "type": "boolean" + }, + "loaded": { + "type": "boolean" + }, + "model": { + "type": "string" + }, + "note": { + "type": "string" + }, + "requiredBytes": { + "type": "number" + }, + "sizeSource": { + "type": "string" + }, + "target": { + "enum": [ + "gpu", + "partial", + "cpu", + "none" + ], + "type": "string" + } + }, + "required": [ + "model", + "fits", + "target", + "sizeSource", + "loaded", + "requiredBytes", + "availableBytes", + "note" + ], + "type": "object" +}
- Changed
health_check4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "health": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "health" + ], + "type": "object" +}
- Changed
list_loaded4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "loaded": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "loaded" + ], + "type": "object" +}
- Changed
list_models4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "models": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "models" + ], + "type": "object" +}
- Changed
list_providers4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id to filter to"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "providers": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "providers" + ], + "type": "object" +}
- Changed
load_model5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contextLengthAdded value: +{ + "description": "Context window to load with (Ollama num_ctx, LM Studio --context-length)", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "load": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "load" + ], + "type": "object" +}
- Changed
model_info4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "info": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "model": { + "type": "string" + } + }, + "required": [ + "model", + "info" + ], + "type": "object" +}
- Changed
pull_model5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / model / descriptionPrevious value: -"Model id/name to pull (download)"New value: +"Model id/name to pull (e.g. qwen3:8b, hf.co/<repo>:<quant>)" - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "pull": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "pull" + ], + "type": "object" +}
- Changed
remove_model6 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / confirm / descriptionPrevious value: -"Must be true to perform this destructive deletion"New value: +"Must be true when the client cannot ask the user directly (no elicitation support)" - changed
Input schema / properties / provider / descriptionPrevious value: -"Required provider id (delete is scoped to a single provider)"New value: +"Provider to delete from (required). Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Input schema / requiredPrevious value: -[ - "model", - "confirm", - "provider" -]New value: +[ + "model", + "provider" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "remove": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "remove" + ], + "type": "object" +}
- Changed
search_available2 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "note": { + "type": "string" + }, + "query": { + "type": "string" + }, + "results": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "query", + "note", + "results" + ], + "type": "object" +}
- Added
search_models - Changed
suggest_model5 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / contextLengthAdded value: +{ + "description": "Context length to plan for (default 4096)", + "exclusiveMinimum": 0, + "maximum": 9007199254740991, + "type": "integer" +} - added
Input schema / properties / kvCacheTypeAdded value: +{ + "description": "KV cache precision (default f16)", + "enum": [ + "f16", + "q8_0", + "q4_0" + ], + "type": "string" +} - added
Input schema / properties / preferSpeedAdded value: +{ + "description": "Prefer smaller, faster models within each tier", + "type": "boolean" +} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "suggestions": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "task": { + "type": "string" + } + }, + "required": [ + "task", + "suggestions" + ], + "type": "object" +}
- Changed
system_resources1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "cpuCount": { + "type": "number" + }, + "gpus": { + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "platform": { + "type": "string" + }, + "ramFreeBytes": { + "type": "number" + }, + "ramTotalBytes": { + "type": "number" + } + }, + "required": [ + "platform", + "ramTotalBytes", + "ramFreeBytes", + "cpuCount", + "gpus" + ], + "type": "object" +}
- Changed
unload_model4 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - changed
Input schema / properties / provider / descriptionPrevious value: -"Optional provider id"New value: +"Provider instance name. Omit to let the server choose (local providers only, unless LOCAL_AI_ALLOW_HOSTED_FALLBACK is set)." - changed
Input schema / properties / provider / enumPrevious value: -[ - "ollama", - "lmstudio", - "moonshot", - "openaicompat", - "llamacpp" -]New value: +[ + "ollama", + "lmstudio", + "llamacpp", + "dockermodelrunner" +] - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "unload": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "unload" + ], + "type": "object" +}
16 tool updates
v0.4.0- First observed
benchmark - First observed
complete - First observed
embed - First observed
fit_check - First observed
health_check - First observed
list_loaded - First observed
list_models - First observed
list_providers - First observed
load_model - First observed
model_info - First observed
pull_model - First observed
remove_model - First observed
search_available - First observed
suggest_model - First observed
system_resources - First observed
unload_model
TDQS
Scored across 22 tools
Most tools map to a distinct resource (providers, models, hardware, pulls), but several pairs overlap meaningfully: search_available is explicitly a subset of search_models (source 'catalog'), diagnostics partially duplicates health_check + system_resources, and ensure_model overlaps with the pull_model/load_model/fit_check combination. complete vs delegate is also a judgement call for an agent, since both run inference and only the description clarifies which to pick. Descriptions do a lot of work to disambiguate, keeping this above a 2.
The dominant pattern is snake_case verb_noun (pull_model, list_models, search_models, remove_model, suggest_model), but it is mixed with noun_noun (model_info, system_resources, health_check, fit_check) and bare single-word tools (complete, delegate, embed, benchmark, diagnostics). Everything is readable and there is some within-family consistency (list_*, pull_*, search_*), but the overall set does not follow one predictable convention.
22 tools is on the heavy side for a local-runtime manager, and a few do not clearly earn their place: search_available is redundant with search_models, and pull_status/pull_cancel are arguably one job-status tool. The remaining surface (lifecycle, discovery, hardware, inference) is defensible, so this sits at borderline rather than excessive.
The model lifecycle is well covered end to end: search/suggest, pull with background jobs, load/unload, fit check, benchmark, delete, plus inference (complete/delegate/embed) and hardware/diagnostics. Minor gaps remain, notably no way to add or edit provider configuration, no model copy/alias/rename, and no way to cancel long-running non-pull work such as benchmark. These are workaround-able rather than blocking.
Maintenance
Related MCP Connectors
Chat, image, video, and audio models from many vendors behind one remote MCP server and one key.
MCP server for building and testing AI agents with multi-model experimentation and insights.
An MCP server that provides an API to LLMs to manage their JumpCloud resources.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Related MCP Servers
- AlicenseAqualityBmaintenanceDiscovers local model runtimes such as Ollama, LM Studio, and LocalAI, and exposes their endpoint metadata to MCP clients like Copilot.38 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables MCP-compatible applications to interact with local and cloud-hosted LLM models for model management, text generation, chat, embeddings, and web search/fetch.897 npmAGPL 3.0
- AlicenseNot gradedqualityAmaintenanceEnables MCP-compatible clients to manage, run, and interact with local or cloud LLM models through exposed tools for listing, pulling, generating, chatting, embeddings, and web search/fetch. Supports Claude Desktop, Cline, and hybrid local/cloud setups.897 npmAGPL 3.0
- AlicenseNot gradedqualityAmaintenanceEnables MCP-compatible applications to manage and use local or cloud-hosted models, including listing, pulling, generating, chatting, embeddings, and web search/fetch through a unified tool interface.897 npmAGPL 3.0