simple-job
mcp-simple-job
Pasa una subtarea a un modelo local en otra máquina y verifica el resultado antes de devolverlo.
Construido para una forma concreta de problema: el asistente capaz y medido se ejecuta en la máquina ante la que estás sentado, mientras una caja con GPU perfectamente buena permanece inactiva en un rincón. Leer cuarenta archivos, resumir una página larga, descargar un conjunto de datos — nada de eso necesita el modelo caro, y hacerlo en el contexto del asistente gasta el único recurso que es genuinamente escaso.
Medido en la configuración del autor, frente a hacer los mismos cuatro trabajos en contexto: ~2,7 veces más rápido, y 6,1 veces menos contexto gastado, porque las páginas en bruto nunca entran en él.
La única regla
Un trabajo debe venir con una verificación. Una tarea que no pueda decir cómo se sabría que ha funcionado es rechazada — no advertida, rechazada.
Esto no es desconfianza del modelo local. Es que el que llama no puede saberlo. Cuando el asistente delega un resumen y recibe cuatrocientas palabras confiadas, no tiene ninguna forma independiente de saber si esas palabras describen el documento o algo más. Delegar sin una verificación añade un segundo punto donde una luz verde no significa nada.
Las verificaciones son deliberadamente aburridas: nonempty, contains, regex, json_keys,
line_count, shell (tu argv, salida 0 pasa, salida canalizada a stdin) y summary_of
(más corto que la fuente y no una copia de ella).
Related MCP server: Forgehand
Las cuatro subtareas
tool | qué hace | dónde ocurre el trabajo |
| una solicitud sencilla con tu propia verificación | el host del modelo |
| texto, o URL(s) obtenidas primero | máquina trabajadora (obtención + modelo) |
| buscar, leer las páginas principales, resumir | la búsqueda alterna hosts, el resto en la máquina trabajadora |
| obtener un archivo, informar bytes + sha256 | máquina trabajadora por defecto, cualquier host configurado |
simple_job_stats informa de cómo han ido realmente todos ellos, a partir de una fila del registro escrita
para cada trabajo.
Poniéndolo en marcha
Requisitos
Node 18+ en la máquina que ejecuta el servidor MCP.
Un endpoint de chat compatible con OpenAI.
llama-serverde llama.cpp, Ollama, vLLM, LM Studio o una API alojada: cualquier cosa que responda aPOST /v1/chat/completions.Python 3.9+ en cualquier máquina que haga la obtención. Solo biblioteca estándar; sin pip install, sin node, sin beautifulsoup.
Autenticación por clave SSH a la segunda máquina, si usas una. Es opcional (ver más abajo).
Cómo está conectado en las máquinas del autor
Dos ordenadores:
Un Mac mini — la estación de trabajo diaria. 16 GB, normalmente unos pocos gigabytes en swap. Ejecuta Claude Desktop y, por tanto, este servidor MCP.
Una máquina Pop!_OS con una RTX 5070 Ti — el laboratorio. Ejecuta un modelo de 35B llamado ornith bajo
llama-serveren el puerto 8080, y está inactiva la mayor parte del día.
Un túnel SSH hace que el modelo remoto parezca local para el Mac:
ssh -N -o ServerAliveInterval=30 -L 127.0.0.1:8081:127.0.0.1:8080 pop-ospop-os es un alias de ~/.ssh/config con una clave y IdentitiesOnly yes, de modo que el servidor puede
alcanzarlo de forma no interactiva con BatchMode=yes.
La entrada del cliente MCP es simplemente:
{ "mcpServers": { "simple-job": { "command": "node", "args": ["/path/to/mcp-simple-job/index.js"] } } }Los valores por defecto hacen el resto: el modelo en 127.0.0.1:8081, la máquina trabajadora en pop-os y
el registro en un ~/Code/harness/ existente, si lo hay.
Nada se llama nunca a mano. El asistente elige la herramienta — que es un problema más difícil de lo que parece, y se cubre más abajo.
Ejecutándolo en las tuyas
Dos máquinas, una que ejecuta el cliente y otra que ejecuta el modelo:
{
"mcpServers": {
"simple-job": {
"command": "node",
"args": ["/path/to/mcp-simple-job/index.js"],
"env": {
"ORNITH_URL": "http://127.0.0.1:8081/v1/chat/completions",
"ORNITH_MODEL": "your-model-name",
"POP_HOST": "your-ssh-alias"
}
}
}
}Una sola máquina — todo local, sin SSH en ningún sitio:
{
"env": {
"ORNITH_URL": "http://127.0.0.1:11434/v1/chat/completions",
"ORNITH_MODEL": "qwen3:8b",
"SEARCH_HOSTS": "mac"
}
}SEARCH_HOSTS=mac es el interruptor que dice «no hay segunda máquina». La obtención,
la descarga y la búsqueda suceden todas localmente, y la búsqueda simplemente tiene un presupuesto de frecuencia
en lugar de dos. Todo lo demás se comporta igual.
Variables de entorno
variable | valor por defecto | qué hace |
|
| el endpoint de chat |
|
| nombre del modelo enviado en la solicitud |
|
| alias SSH de la máquina trabajadora |
|
| máquinas entre las que alternar las búsquedas; establece |
|
| intervalo mínimo entre búsquedas desde una misma máquina |
|
| cuánto tiempo permanece fuera una máquina tras ser limitada |
| junto a | dónde se guarda el estado de temporización de la búsqueda |
|
| el registro SQLite |
|
| identificador de traza opcional para estampar en las filas |
El registro es opcional. Se crea en el primer uso, y si no se puede escribir los
trabajos siguen ejecutándose: el registro se hace con el mejor esfuerzo y nunca bloquea el trabajo. HARNESS_TRACE es un gancho
para la configuración de trazado del propio autor; ignóralo y las filas simplemente tendrán un identificador de traza nulo.
Conseguir que se use de verdad
Esta es la parte que la mayoría de la gente se salta, y es la parte que decide si todo lo anterior importa.
Una herramienta a la que nada enruta es invisible, por muy bien que funcione. El autor tiene un servidor MCP aparte que funciona perfectamente y tuvo cero llamadas en meses, puramente porque nada le dijo nunca al asistente que lo utilizara. Construir una capacidad y enrutar hacia ella son dos trabajos distintos, y terminar el primero se siente como terminar.
Hay tres maneras de cerrar esa brecha, la más barata primero. La mayoría de la gente quiere la segunda.
1. No hagas nada, y observa. Algunos clientes leen las descripciones de herramientas lo bastante bien como para que una solicitud suficientemente obvia — «resume estas cuarenta páginas» — encuentre la herramienta por sí sola. Vale la pena probarlo durante un día antes de añadir mecanismos. Observa si realmente se llama.
2. Pon una regla donde tu cliente guarde las instrucciones permanentes. Instrucciones de proyecto de Claude Desktop,
un CLAUDE.md para Claude Code, .cursorrules, las instrucciones de un GPT personalizado —
lo que sea que tu cliente lea en cada turno. Algo así:
Hay un modelo local disponible a través de
simple-job. Úsalo cuando el material no esté ya en contexto y el trabajo sea mecánico: resumir páginas o archivos, búsqueda web más lectura, descargar archivos, extracción y reformateo. Es gratis y no gasta contexto en la fuente.Hazlo tú mismo cuando el texto ya esté en contexto, cuando el trabajo necesite interpretación en lugar de transcripción, o cuando acertar importe más que poder verificarlo. Nunca delegues decisiones de criterio, código que deba ser correcto o edición de archivos.
Cada trabajo debe llevar una verificación: el servidor rechaza el trabajo que no puede verificar.
Dedica tantas palabras a cuándo no delegar como a cuándo hacerlo. El modo de fallo de enrutar hacia una herramienta de delegación es la sobredelegación, y un asistente que lo envía todo cuesta abajo te entregará una transcripción fiel donde querías criterio.
3. Conéctalo a un enrutador, si tienes uno. Si tu configuración ya hace corresponder situaciones con herramientas, añade una entrada para «lectura masiva u obtención de material aún no en contexto». La ventaja sobre una instrucción permanente es que es medible: puedes contar si se activó cuando debería. Una instrucción permanente o funciona o no, y nada registra cuál de las dos.
Qué no enviarle
Cualquier cosa donde «tiene buena pinta» sea la única prueba. Decisiones de criterio. Código que deba ser correcto. Editar archivos.
Y un límite encontrado por medición más que por gusto: un modelo local pequeño transcribe fielmente pero no interpreta. En las pruebas reprodujo literalmente el fraseo ambiguo de una fuente en lugar de resolver lo que significaba, y resumió el número de estrellas de un repositorio como si formara parte de un informe de error. Envíale transcripción. Conserva la interpretación.
Notas al construirlo
Todo lo que sigue es una medición, no una opinión. Los números están también en los comentarios del código.
El razonamiento está desactivado por defecto
Los modelos de razonamiento emiten su deliberación y su respuesta desde el mismo presupuesto de tokens. En un trabajo de resumen ejecutado tres veces de forma idéntica, dos de las tres veces gastaron 5.500–6.000 caracteres pensando, alcanzaron el límite y devolvieron una respuesta vacía con HTTP 200.
Subir max_tokens no lo arregló. reasoning_effort: "low" no lo arregló. Una
etiqueta de sistema /no_think no lo arregló. Solo chat_template_kwargs: {enable_thinking: false} lo hizo, y el mismo trabajo respondió entonces en 258 tokens. Pasa think: true para un trabajo
que realmente necesite deliberación, y sube max_tokens con él.
La búsqueda está racionada, y DuckDuckGo miente sobre el motivo
DuckDuckGo no limita la tasa de forma educada:
una consulta atendida es HTTP 200, ~28 KB, diez enlaces de resultados
una rechazada es HTTP 202, ~14,2 KB, y su texto dice "Please complete the following challenge... Select all squares containing a duck"
Es una marca de captcha en la IP, no un límite temporal, y espaciar no la elimina. Después de cuatro minutos de silencio, seis consultas con 30 s de separación desde una máquina y seis con 15 s desde la otra fueron 0 de 12. El sondeo cada 5 s durante un bloque no se recuperó en 162 s — reintentar la alimenta. La marca se disipó por sí sola en unos veinte minutos.
Por eso las búsquedas se espacian, se alternan entre máquinas (dos IP son dos presupuestos), y una
limitación se informa como throttled, nunca como «sin resultados». Esas dos cosas significan lo contrario.
La lectura sigue a la pregunta
Una página larga se recorta para que quepa en la ventana del modelo, y recortar desde arriba responde a la pregunta equivocada en silencio. Al preguntar por "sparse gating and load balancing" en una página de 40.063 caracteres con una ventana de 8.000 caracteres, la primera versión devolvió un resumen fluido del inicio del artículo — en el que "load balancing" nunca aparece (empieza en el carácter 16.181) y "sparse" nunca aparece (14.671).
Así que focus dirige la ventana: una cabecera para el contexto, luego los pasajes alrededor de cada término
nombrado, una ventana garantizada por término antes de que ningún término tenga una segunda. Dos versiones
anteriores no fueron suficientes: la coincidencia de subcadenas encontró "load" dentro de "download" e informó de
42 coincidencias de ruido, y tomar los pasajes en orden del documento gastó el presupuesto antes de llegar al
carácter 16.181.
Si la página nunca usa esas palabras, la llamada devuelve ok:false con focus_not_found.
Cero coincidencias es una respuesta mejor que un resumen plausible de otro material.
Una página que es mayormente script es rechazada
Un sitio sirvió 68.896 bytes que contenían 40 caracteres de texto ("Loading..."), que el
guard if not text original dejó pasar, así que el armazón entró en un resumen como material fuente
y el modelo escribió con total confianza una cifra de referencia citándolo.
Ahora hay dos pruebas, porque cada una por separado se deja engañar: un mínimo absoluto y una proporción de texto a bytes que solo condena a una página que también es corta. Un issue de GitHub son 290.000 bytes de marcado alrededor de 3.896 caracteres de discusión real, y la proporción por sí sola lo descartó.
Las citas están numeradas para poder comprobarse
search_and_summarize numera las páginas y pide [1], [2] en lugar de urls. Al pedirle urls, el modelo atribuyó una cifra que había leído en un blog a una página de documentación: el dato era real y estaba en el material, la atribución no lo era, y summary_of no puede verlo porque una viñeta mal etiquetada tiene la longitud correcta y no es una copia.
Una url es una cadena larga y opaca de copiar correctamente. Un entero no lo es, y se puede comprobar su rango contra las páginas realmente leídas, lo que el código hace, fallando la llamada si el número está fuera de rango y contando las viñetas sin ninguna fuente.
¿Qué máquina es más rápida?
Verificado con sha256 idéntico en ambos lados:
máquina cliente | máquina trabajadora | |
ida y vuelta de ssh | — | ~185 ms por llamada |
obtener 4 páginas | ~1,7 s | ~2,0 s |
descargar 20 MB | 17,5 MB/s | 12,6 MB/s |
La máquina cliente fue más rápida en ambas. La velocidad no es la razón para enviar trabajo a la trabajadora. Las razones son que contiene el modelo, que está inactiva mientras la otra máquina está en uso, y que una segunda máquina es un segundo presupuesto de búsqueda. Elige el host de una descarga según dónde se necesite el archivo, no según el rendimiento.
Pruebas
node test_e2e.mjs # 24 assertions, spawns the real server over JSON-RPC
node --test test/simple-job.test.mjs # 19 unit assertions on the checksLa suite de extremo a extremo lanza el servidor real de la misma manera que lo haría un cliente, contra un libro de contabilidad desechable. Una prueba en proceso no detectaría un error de PATH o de entorno, y esos son exactamente los que solo aparecen después de un reinicio.
Los cambios en index.js surten efecto la próxima vez que el cliente inicie el servidor. pop_agent.py se vuelve a leer en cada llamada, por lo que los cambios en la obtención, la búsqueda y la descarga se aplican de inmediato.
Available Tools
5 toolsdownloadA
Download a file to pop (default) or to this Mac. Returns the path, byte count and sha256 — a download that reports success without those is not verified. Put it on pop when pop will use it (models, datasets, anything for the GPU); put it on the mac when you will open it.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | http(s) url to download. | |
| dest | No | Directory on that machine. Default ~/Downloads. | |
| host | No | "pop" (default) or "mac". Measured 2026-08-21: the Mac is the faster of the two (17.5 vs 12.6 MB/s), so choose by where the file is needed, not by speed. | |
| max_mb | No | Refuse anything larger. Default 500. | |
| filename | No | Override the filename. | |
| overwrite | No | Replace an existing file. Default false — an existing file is an error, not a silent clobber. | |
| expect_sha256 | No | If given, the download fails unless the hash matches. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states the expected return values ('path, byte count and sha256') and adds the important caveat that success without these is not verified, which is a meaningful behavioral warning. It also implies the default host is pop. However, it does not describe failure behavior beyond the overwrite rule (which is in the parameter schema), nor does it mention whether downloads are atomic or what happens on network errors. Given the lack of annotations, this is a strong disclosure but not exhaustive, so a 4 is appropriate.
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 two sentences long, front-loaded with the primary action and destination, followed by the return-value verification note and then the host-selection guidance. Every sentence carries meaningful information; there is no filler or redundancy. It is an excellent example of concise, high-signal writing.
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 tool with 7 parameters, no output schema, and no annotations, the description covers the core aspects: what it does, where it downloads, what it returns, and how to decide between hosts. It also adds the verification requirement that guards against silently bad downloads. It does not mention edge cases like how max_mb is enforced or what happens when an existing file blocks the download (though the parameter schema covers that), but these are secondary. Overall, an agent can call this tool safely and correctly, so a 4 is suitable.
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 schema already describes all 7 parameters with 100% coverage, so the baseline is 3. The main description adds value by explaining the strategic choice of host ('Put it on pop when pop will use it...'), which reinforces the host parameter's purpose and provides context beyond its schema description. It also emphasizes the verification requirement, which ties into the expect_sha256 parameter. While the schema covers syntax, the description adds usage logic, so a 4 is justified.
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 opens with a clear verb-and-resource pair — 'Download a file' — and specifies the two possible destinations ('to pop (default) or to this Mac'), which uniquely defines the tool's action. It also distinguishes it from the sibling tools (simple_job, summarize, etc.) which are entirely unrelated, so there is no ambiguity about what this tool does.
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 description gives explicit, actionable guidance on when to use each host: 'Put it on pop when pop will use it (models, datasets, anything for the GPU); put it on the mac when you will open it.' This directly tells an agent how to choose the destination based on the intended use, and the default is also stated. No alternative tools are relevant, so this guidance is complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_and_summarizeA
Search the web (DuckDuckGo), read the top pages on pop, and have ornith summarise them — one call, no Claude context spent on the raw pages. THE ONLY SEARCH TOOL HERE, and deliberately: DuckDuckGo rate-limits hard, so searches are spaced and alternated between this Mac and pop. A throttle is reported as a throttle, never as "no results".
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | Optional. Defaults to {type:"summary_of"} against the fetched pages. | |
| count | No | How many search results to list. Default 6. | |
| focus | No | What you actually want to know, if narrower than the query. | |
| model | No | Default ornith:35b. | |
| pages | No | How many top results to read. Default 3, max 8. More pages costs seconds, not money. | |
| query | Yes | The web search query. | |
| think | No | Let ornith reason before answering. Default false. Measured 2026-08-21: with reasoning on, 2 of 3 summarise runs returned an EMPTY answer after burning the whole token budget on thinking. Turn it on only for a job that genuinely needs deliberation, and raise max_tokens with it. | |
| max_words | No | Target summary length. Default 250. | |
| max_tokens | No | Default 2048. Ornith reasons before answering; too low returns an empty answer. | |
| temperature | No | ||
| results_only | No | Skip reading and summarising; just return the search results. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility and excels: it discloses the DuckDuckGo backend, the reading and summarization pipeline, the lack of Claude context use, the spacing of requests, and the crucial behavior that throttles are reported truthfully. It even documents a known failure mode with the 'think' parameter. This is exemplary transparency.
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 front-loads the purpose but then becomes a run-on sentence mixing operational details, typos, and policy notes. While information-dense and not excessively long, it could be split into clearer sentences to improve scannability. It feels a bit stream-of-consciousness.
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 an 11-parameter tool with no output schema, the description covers the core use case, operational constraints, and a known gotcha ('think'). It doesn't describe the return value, but that's a reasonable trade-off given the already rich parameter documentation and the absence of an output schema. The description is sufficient for an agent to decide when to call this tool.
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 high (91%), so the baseline is 3. The description itself does not add parameter-level details beyond what's in the schema, and the schema already describes 10 of 11 parameters. No contradiction or gap that requires the description to compensate.
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: 'Search the web (DuckDuckGo), read the top pages... and have ornith summarise them'. It also differentiates from siblings by declaring 'THE ONLY SEARCH TOOL HERE', making it unmistakable what this tool does relative to others. The typos ('pop', 'ornith') don't obscure the core verb-resource actions.
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 description explicitly frames the tool as the only search option ('THE ONLY SEARCH TOOL HERE') and provides practical guidance on rate-limiting and throttle behavior. However, it doesn't explicitly state when *not* to use it (e.g., when you already have content to summarize, which sibling 'summarize' might handle), leaving exclusions to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
simple_jobA
Hand a plain subtask to ornith (35B, local, free) on pop and verify the result before returning it. REQUIRES a check — a task that cannot state how it would be known to have worked is refused. Good for: extraction against a schema, classifying, reformatting. Bad for: judgment calls, code that must be correct, editing files — do those yourself.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | What ornith should do. Be specific about the output format. | |
| check | Yes | How the result is verified. One of: {type:"nonempty"} | {type:"contains",text,case_sensitive?} | {type:"regex",pattern,flags?} | {type:"json_keys",required:[...]} | {type:"line_count",min?,max?} | {type:"shell",command:[argv...],timeout_ms?} (result is piped to stdin; exit 0 passes). | |
| model | No | Default ornith:35b. | |
| think | No | Let ornith reason before answering. Default false. Measured 2026-08-21: with reasoning on, 2 of 3 summarise runs returned an EMPTY answer after burning the whole token budget on thinking. Turn it on only for a job that genuinely needs deliberation, and raise max_tokens with it. | |
| context | No | Material for the task — the text, rows or code to work on. | |
| max_tokens | No | Default 2048. Ornith reasons before answering; too low returns an empty answer. | |
| temperature | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses key behaviors: it verifies the result before returning, refuses tasks without a check, and mentions limitations (bad for judgment calls, code, editing). However, it does not specify what happens if verification fails, error handling, or output format, leaving some behavioral aspects undisclosed.
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 concise and well-structured: it opens with the core action, then lists requirements and use cases. Every sentence adds value without redundancy, and the format is easy to parse.
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 there is no output schema, the description should explain the return value or error cases, but it only says 'returns it' without specifying format. It also omits details about parameter interactions (e.g., temperature affects creativity) and failure modes, leaving some operational context incomplete.
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 schema already provides descriptions for all parameters (86% coverage). The description adds little beyond the note that a check is required (which is already in the schema). No additional semantic value is provided for parameters like temperature or max_tokens.
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 function: delegating a subtask to ornith and verifying the result. It explicitly lists good and bad use cases (extraction, classification, reformatting vs. judgment calls, code, editing), making the purpose and scope unambiguous.
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 provides explicit guidance on when to use the tool: it requires a verifiable check, lists suitable tasks, and explicitly warns against unsuitable ones (e.g., judgment calls, code) with 'do those yourself.' This clearly differentiates it from the alternatives (doing it manually or using other tools).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
simple_job_statsB
How delegation has actually gone: jobs by kind, how often the check passed, and speed. Answers whether this server is earning its place.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full burden of behavioral disclosure. It implies a read-only informational tool but does not explicitly state that it performs no mutations, requires no auth, or has any other behavioral caveats. The phrasing 'answers whether this server is earning its place' is not operationally informative.
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 brief and front-loaded with the core subject, but the final clause 'Answers whether this server is earning its place' adds little operational value and is somewhat metaphorical. Still, it is concise overall with minimal waste.
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 zero-parameter statistics tool, the description gives a reasonable sense of the returned dimensions: jobs by kind, check pass rate, and speed. However, it does not clarify the output format or precisely what 'speed' refers to, and it lacks any comparison to sibling tools, leaving some ambiguity for an agent.
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 accepts zero parameters, so the schema already fully covers the input surface. The description does not need to explain parameter details, and the baseline for zero-parameter tools applies.
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 communicates that this tool reports statistics about job delegation, including breakdowns by kind, check pass rates, and speed. It is clear enough to identify the tool's purpose, though it lacks an explicit verb like 'returns' or 'computes' and does not explicitly differentiate itself from siblings.
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 no guidance on when to use this tool versus alternatives such as simple_job or summarize. No context, conditions, or exclusions are provided that would help an agent choose this tool correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
summarizeB
Summarise text with ornith on pop. Free, local, and it does not spend Claude context on the source. Pass the text directly, or a url/urls to fetch first (fetched on pop). The default check is a real one: the summary must be substantially shorter than the source and not a copy of it.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Fetch this page on pop and summarise it. | |
| text | No | The material to summarise. Either this or url/urls. | |
| urls | No | Fetch several pages on pop and summarise them together. | |
| check | No | Optional. Defaults to {type:"summary_of"} against the source text. | |
| focus | No | What the summary should be about, if not everything. e.g. "only the benchmark numbers". | |
| model | No | Default ornith:35b. | |
| style | No | "bullets" (default) or "paragraph". | |
| think | No | Let ornith reason before answering. Default false. Measured 2026-08-21: with reasoning on, 2 of 3 summarise runs returned an EMPTY answer after burning the whole token budget on thinking. Turn it on only for a job that genuinely needs deliberation, and raise max_tokens with it. | |
| max_words | No | Target length. Default 200. | |
| max_tokens | No | Default 2048. Ornith reasons before answering; too low returns an empty answer. | |
| temperature | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavior, and it does: free, local, avoids consuming Claude context, fetches URLs, and enforces a real anti-copy/shorter-than-source check. It does not cover failure modes or service dependencies, but the main behavioral traits that would affect an agent's invocation and expectation are present.
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 compact and front-loaded with the main verb and purpose. Every sentence contributes useful information, but 'on pop' appears twice without definition, slightly hurting clarity. It is appropriately sized and not padded.
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 11 parameters, a nested check object, and no output schema, the description covers the main usage and the default verification behavior but leaves gaps: return value shape, error/failure behavior with URLs, and what the check object supports beyond its default. The schema covers most parameters, but the missing output context is notable.
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 high at 91%, so the baseline is 3. The description adds a little context about text/url/urls usage and the default check, but mostly repeats what the schema already documents. It does not add meaningful detail for parameters like focus, style, model, or temperature.
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 the core action clearly with a specific verb and resource: 'Summarise text with ornith on pop.' It also clarifies the two input modes (direct text or URL/URLs) and differentiates itself via 'does not spend Claude context on the source.' However, 'on pop' is unexplained jargon, and it does not explicitly contrast with sibling search_and_summarize, so it is not 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 description explains how to invoke the tool ('Pass the text directly, or a url/urls to fetch first') but provides no guidance on when to choose this tool over its siblings. search_and_summarize is a plausible alternative for search-then-summarize use cases, yet no exclusion or comparison is mentioned.
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.
5 tool updates
v1.0.0- First observed
download - First observed
search_and_summarize - First observed
simple_job - First observed
simple_job_stats - First observed
summarize
TDQS
Scored across 5 tools
Each tool has a clear, distinct purpose: simple_job delegates a generic subtask, summarize condenses text, search_and_summarize combines web search with summarization, simple_job_stats reports on job execution, and download retrieves files. No two tools overlap in functionality.
All tool names follow a consistent lowercase_with_underscores convention, and related tools (simple_job, simple_job_stats) share a common prefix while remaining descriptive. No mixed camelCase or other styles.
With 5 tools, the server is well-scoped—neither bare nor cluttered. Each tool serves a distinct, essential function, and the count aligns with the apparent purpose of task delegation and information retrieval.
The tool set covers the core operations needed for the server's domain: executing a job, summarizing, searching and summarizing, tracking job stats, and downloading files. No obvious missing functionality for the stated purpose.
Maintenance
Related MCP Connectors
Local ML: speech to text (SRT/VTT), text embeddings, reranking, similarity, entities, zero-shot.
Hand tasks, bugs and finished work to AI coding agents, and get back a write-up with evidence.
Exact IBAN, VAT, cron, regex answers; HTML/URL to hosted PDF or screenshot; agent memory; workflows.
LLM chat, text tools, image generation, editing, batch image jobs, and asynchronous video generation
Related MCP Servers
- AlicenseBqualityCmaintenanceDelegates heavy, repetitive, and verifiable tasks like PDF extraction, code analysis, and log processing to a local LLM to reduce token consumption for frontier AI models, while keeping decision-making with the main AI.8MIT
- AlicenseAqualityAmaintenanceEnables delegating complete coding tasks to a local OpenAI-compatible model through MCP, using bounded Git worktrees and compact receipts so conversation history is not carried.4MIT
- FlicenseNot gradedqualityCmaintenanceEnables delegating mechanical or high-volume subtasks to a local LLM through an MCP tool, letting the assistant query the local model without using its own output tokens for content.-
- AlicenseAqualityAmaintenanceEnables Codex to delegate bounded, low-risk text work such as extraction, summarization, translation, and code drafts to a local WorkBuddy installation, returning small inspectable drafts for the main agent to verify.5MIT