estimate-maestro
estimate-maestro
Un servidor MCP personal y herramienta de línea de comandos para registrar estimaciones y tiempo real, de modo que las estimaciones puedan eventualmente contrastarse con resultados en lugar de con sensaciones.
Esta es una herramienta de recopilación de datos para la calibración de estimaciones, no un estimador. Nunca estima nada por ti. Registra lo que estimaste para un trabajo, en qué resultó el plan y cuánto tiempo real tomó el trabajo. Qué haces con ese registro — comparar, notar desviaciones, decidir que fuiste sistemáticamente optimista con cierto tipo de trabajo — depende de ti y de lo que lea el almacén más adelante. El trabajo de la herramienta termina en registrar con honestidad.
El modelo
Cuatro tipos de cosas se registran:
Esfuerzo — una pieza de trabajo que vale la pena seguir por sí misma: un pull request, un mega-PR, cualquier cosa con un plan y un tamaño. Un esfuerzo existe desde el momento en que tiene un artefacto de plan (una especificación, un
.PR.md, donde sea que viva el plan) y una estimación inicial. Antes de ese punto no hay nada que registrar todavía.Segmento — una pieza de un esfuerzo, normalmente un sub-PR. Los segmentos se añaden, se cierran contra un pull request, se descartan o se renombran. Un segmento añadido antes de que el esfuerzo comience es parte del plan original; uno añadido después es crecimiento de alcance, y ambos se mantienen distinguibles en el registro.
Intervalo — un período de tiempo registrado, normalmente contra un segmento. Los intervalos se cierran manualmente, se cierran automáticamente cuando una sesión termina con el reloj aún en marcha, o se derivan a posteriori de las marcas de tiempo de los commits cuando no se registró nada en absoluto.
Ausencia — tiempo que no se trabajó en absoluto: un día festivo, una cita, una reunión no relacionada. Las ausencias se registran de forma retroactiva y se espera que así sea. Restan de cualquier intervalo que solapen.
Related MCP server: time-tracker-ai-mcp
Estimaciones: triplas de tres puntos en puntos de historia
Cada estimación es una tripla PERT — optimista, probable, pesimista — dada en una escala abstracta de puntos, nunca en horas. El valor esperado y la desviación estándar se derivan de la tripla al leer; nada almacena un único número "la estimación es N", porque un número desnudo descarta la incertidumbre que la convertía en una estimación en lugar de un hecho.
Los puntos se anclan comparando el trabajo en cuestión con esfuerzos previos de forma similar, no convirtiendo un número sentido de horas en puntos en tu cabeza. El sentido de una escala abstracta es comparar cosas semejantes entre esfuerzos cuya duración real aún no conoces.
Un esfuerzo se estima dos veces:
La estimación inicial, hecha contra el plan tal como se escribió por primera vez, con el mismo número de segmentos con el que comenzó el plan.
La estimación final, hecha en la retrospectiva contra el plan tal como resultó realmente — incluyendo cada segmento insertado en el camino. Esta es una contrafactual: "dado todo lo que ahora sabes sobre cómo resultó esto realmente, ¿qué habrías estimado?" — nunca "¿cuánto tardó?", y nunca una medición de nada.
Dividir la estimación en dos pasadas es lo que hace que las dos formas en que una estimación puede fallar sean separables a posteriori. La pasada inicial puede fallar por error de inventario — existía trabajo que nadie conocía todavía, o trabajo que se asumía existente resultó no existir. La pasada final, hecha contra el plan tal como resultó realmente, aísla el error de dimensionamiento — los elementos que se conocían desde el principio y simplemente se juzgaron mal. Un único número por esfuerzo confunde ambos; dos números, uno por pasada, los mantienen separados.
También se puede registrar una estimación revisada a mitad del esfuerzo — típicamente cuando se inserta un segmento que no estaba en el plan original — sin esperar a la retrospectiva.
El modelo de tiempo: se asume un día normal
Se asume un día laboral normal por defecto, y solo se registran las desviaciones de él. Registrar entrada y salida es la excepción, no la rutina — la herramienta no espera un cronómetro corriendo ocho horas cada día. Concretamente:
El tiempo registrado manualmente cuenta en su totalidad, sean cuales sean las horas en que caiga. Tardes y fines de semana incluidos: si registraste entrada a las 22:00 un sábado, eso es tiempo real y se registra como tal, sin ajuste de horas laborales aplicado.
El modelo de horas laborales solo se aplica donde no se registró tiempo realmente. Hay exactamente dos lugares donde se usa:
Limitar un temporizador olvidado. Si una sesión termina con el reloj aún en marcha, el intervalo se cierra al final configurado del día laboral (o, fuera de los días y horas laborales configurados, se limita a una duración fija de sesión) en lugar de permanecer abierto indefinidamente o adivinarse al minuto.
Reconstruir intervalos a partir de marcas de tiempo de commits cuando nunca se registró nada para un segmento. Un grupo de commits cercanos se convierte en una sesión de trabajo derivada, usando el modelo de horas laborales para decidir cuánto del lapso entre ellos cuenta como trabajo en lugar de un hueco nocturno.
Una ausencia registrada sobre un lapso resta de cualquier intervalo — registrado o derivado — que solape, en su totalidad para un intervalo registrado manualmente y a través del modelo de horas laborales para uno derivado.
Categorías de herramientas y la regla de contaminación
Cada herramienta que expone el servidor MCP cae exactamente en una categoría:
registro —
start_effort,add_slice,close_slice,drop_slice,rename_slice,clock_in,clock_out,annotate_interval,repair_interval,record_absence,record_revision,record_final_plan,harvest_commits,record_landed_commit,remap_commits,finish_effort.estimación —
reference_efforts, que muestra esfuerzos previos para comparación mientras se hace una estimación.estado —
current, que informa de qué está registrado y desde cuándo.calibración —
effort_table,effort_detail,summary, que leen el registro acumulado.
Las herramientas de registro, estimación y estado nunca devuelven una duración o un agregado. Solo las de calibración pueden. Esto se aplica estructuralmente: cada modelo de respuesta usado por una herramienta de registro, estimación o estado se comprueba en busca de nombres de campo que contengan palabras como hours, minutes, duration, wall, average o share, y la comprobación falla si se encuentra una.
La razón no es el orden. Una estimación hecha después de ver la duración real del trabajo es un eco anclado de esa duración, no un juicio independiente — el número que producirías está contaminado por haber visto la respuesta justo antes. La regla de contaminación evita que una cifra de tiempo real aparezca en una respuesta de herramienta mientras se hace una estimación o se ejecuta un reloj, de modo que la comparación inicial-versus-final se mantenga honesta. Las herramientas de calibración están exentas porque su propósito completo es informar exactamente de esas cifras, una vez que la estimación ha terminado.
Variables de entorno
Todas son opcionales; cada una tiene un valor por defecto. Lee de src/estimate_maestro/config.py, no de esta lista, si ambos discrepan.
Variable | Valor por defecto | Significado |
|
| Ruta al directorio del almacén. |
|
| Inicio del día laboral (hora ISO 8601). |
|
| Fin del día laboral (hora ISO 8601). |
|
| Inicio de la pausa diaria de almuerzo, excluida de los segundos laborales. |
|
| Fin de la pausa diaria de almuerzo. |
|
| Días de la semana separados por comas contados como laborales (lunes |
|
| Duración máxima asignada a una sesión limitada que comienza fuera de la ventana de horas laborales. |
|
| Tiempo añadido antes del commit más temprano en una sesión derivada, para cubrir trabajo hecho antes del primer commit. |
|
| Hueco de tiempo laboral entre commits más allá del cual se considera que una sesión derivada ha terminado y ha comenzado una nueva. |
|
| Número mínimo de esfuerzos registrados antes de que |
ESTIMATE_MAESTRO_DERIVE_LEAD_IN_MINUTES no debe exceder ESTIMATE_MAESTRO_DERIVE_SESSION_GAP_MINUTES; el servidor se niega a iniciar en caso contrario.
La herramienta de línea de comandos
estimate-maestro-cli cubre las acciones de registro cotidianas que no necesitan una conversación: clock-in, clock-out, current, record-absence, effort-table y summary. Las acciones que solo tienen sentido como parte de una conversación de estimación — iniciar un esfuerzo, revisar una estimación, registrar el plan final, cosechar commits — son solo herramientas MCP, no comandos CLI, a propósito: están pensadas para ocurrir dentro de una sesión que muestre esfuerzos previos comparables, no como un comando desnudo escrito sin ese contexto.
Códigos de salida
Código | Significado |
| Éxito. |
| Ocurrió un error. |
| Solo |
Instalación
Ninguno de los siguientes pasos se ha ejecutado por ti — copia los comandos de abajo y ejecútalos tú mismo.
Registra el servidor MCP:
claude mcp add --scope user maestro-estimate -- uv --directory ~/mcp/estimate-maestro run estimate-maestroCrea un enlace simbólico de las dos habilidades en tu directorio personal de habilidades:
ln -s ~/mcp/estimate-maestro/skills/recording-work-time ~/.claude/skills/recording-work-time
ln -s ~/mcp/estimate-maestro/skills/estimating-work ~/.claude/skills/estimating-workConvierte el almacén en un repositorio git. Sus archivos son texto plano y de solo añadidura, de modo que se pueda hacer commit y viajar entre máquinas, y es la única copia superviviente de lo que registra: un número perdido o incorrecto allí no se puede reconstruir desde ningún otro lugar. Mantenlo privado: contiene nombres de proyectos, nombres de ramas y cuánto tiempo llevaron las cosas, nada de lo cual pertenece a un repositorio público.
mkdir -p ~/.local/share/estimate-maestro
git -C ~/.local/share/estimate-maestro initLa ubicación predeterminada del almacén sigue la especificación XDG Base Directory Specification y no necesita configuración. Establece ESTIMATE_MAESTRO_STORE solo si quieres el almacén en otro lugar, por ejemplo junto a tus otros repositorios personales, para que sea más fácil recordar hacer commit y push. Debe ser visible tanto para el servidor como para tu shell, así que colócalo donde ambos lo lean (normalmente tu perfil de shell):
export ESTIMATE_MAESTRO_STORE=~/somewhere/elseConecta los dos scripts de hook en ~/.claude/settings.json: hooks/session-end.sh como hook de SessionEnd (cierra un temporizador olvidado, limitado al día laborable configurado) y hooks/session-start.sh como hook de SessionStart (informa si ya hay un temporizador en ejecución):
{
"hooks": {
"SessionStart": [
{
"hooks": [
{ "type": "command", "command": "~/mcp/estimate-maestro/hooks/session-start.sh" }
]
}
],
"SessionEnd": [
{
"hooks": [
{ "type": "command", "command": "~/mcp/estimate-maestro/hooks/session-end.sh" }
]
}
]
}
}Fusiona eso en el bloque hooks existente en ~/.claude/settings.json en lugar de sobrescribirlo, si ya hay uno.
Desarrollo
uv sync --locked
uv run ruff format --check
uv run ruff check
uv run pyright
uv run pytest src/ -vAvailable Tools
21 toolsadd_sliceC
Add a slice. One added while the effort is active is scope growth.
Inputs: title (required), effort (required). Returns: recorded, identifier
annotate_intervalC
Attach meeting participants or a note to an interval after the fact.
Inputs: effort (required), interval (required), note, external, +2 more. Returns: recorded, identifier
clock_inC
Start an interval. Refused if one is already open.
Inputs: effort (required), kind, note, external, +3 more. Returns: recorded, identifier
clock_outC
Close the open interval.
Inputs: at, note. Returns: recorded, identifier
close_sliceC
Close a slice against its pull request.
Inputs: effort (required), work_slice (required), pull_request (required). Returns: recorded, identifier
currentB
What is clocked in, and since when.
Inputs: no named parameters. Returns: since, effort, interval, work_slice
drop_sliceC
Drop a slice that turned out to be unnecessary.
Inputs: effort (required), reason (required), work_slice (required). Returns: recorded, identifier
effort_detailC
One effort's full event history.
Inputs: effort (required). Returns: row, meta, slices, commits, +2 more
effort_tableC
One near-raw row per effort: estimates, wall hours, slice counts.
Inputs: no named parameters. Returns: result
finish_effortC
Mark an effort done.
Inputs: effort (required). Returns: recorded, identifier
harvest_commitsC
Copy commit metadata from a working tree into the store.
Inputs: path (required), since (required), until (required), effort (required), +1 more. Returns: recorded, identifier
record_absenceC
Declare time not spent working. Retroactive by design.
Inputs: kind (required), stop (required), start (required), note. Returns: recorded, identifier
record_final_planD
Record the final plan and the counterfactual estimate against it.
Inputs: effort (required), likely (required), plan_path (required), rationale (required), +3 more. Returns: recorded, identifier
record_landed_commitC
Record the durable commit that landed on the default branch.
Inputs: effort (required), identifier (required), repository (required), work_slice (required). Returns: recorded, identifier
record_revisionC
Record a revised estimate, typically when a slice is inserted.
Inputs: effort (required), likely (required), rationale (required), optimistic (required), +1 more. Returns: recorded, identifier
reference_effortsC
Prior efforts with their summaries and estimates, for comparison. No actuals.
Inputs: kind, limit. Returns: result
remap_commitsC
Map a rewritten commit id onto its replacement.
Inputs: new (required), old (required), effort (required), reason (required). Returns: recorded, identifier
rename_sliceD
Rename a slice.
Inputs: title (required), effort (required), work_slice (required). Returns: recorded, identifier
repair_intervalB
Correct an interval's bounds. Appends; never rewrites.
Inputs: effort (required), interval (required), stop, start. Returns: recorded, identifier
start_effortC
Create an effort from a plan artefact and an initial PERT estimate.
Inputs: kind (required), title (required), likely (required), plan_path (required), +5 more. Returns: recorded, identifier
summaryB
Aggregate calibration, or an honest refusal when there is too little data.
Inputs: no named parameters. Returns: note, efforts_counted, mean_hours_per_point, mean_inventory_growth, +2 more
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 21 tools
Every tool has a clearly distinct purpose. Even overlapping domains like commits (harvest, record, remap) and intervals (clock, annotate, repair) are separated by specific actions and targets. No two tools could be easily confused for the same operation.
The majority of tools follow a consistent verb_noun pattern (e.g., repair_interval, start_effort, add_slice). A few query tools are named as nouns (current, summary, effort_table, effort_detail), which is a minor deviation but still readable and sensible for retrieval operations.
With 21 tools, the surface is substantial but justified by the domain's complexity—covering efforts, intervals, slices, commits, estimates, and queries. Each tool adds distinct functionality, though the count is on the higher end and could feel heavy for simpler use cases.
The toolset provides comprehensive lifecycle coverage: starting and finishing efforts, managing slices (add/close/drop/rename), tracking time (clock in/out, absence), revising estimates, recording commits, and rich reporting (current, table, detail, summary). No obvious gaps or dead ends are apparent.
Maintenance
Related MCP Connectors
Personal time tracker: start timers, log time and summarize your hours by activity.
Time tracking you talk to: log, check and fix your work hours from your AI assistant.
Save and retrieve your chosen context, manage shared workspaces, and track project time.
Privacy-first work tracking with summaries, reports, coaching, and AI-ready long-term memory.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables time tracking in Tempo with automatic timesheet generation from git commits, worklog management with roles and accounts, and integration with Jira for seamless project time logging.1MIT
- AlicenseAqualityCmaintenanceEnables tracking work time with start/stop timers, logging entries, and generating reports.48 npm28 PyPIMIT
- FlicenseNot gradedqualityBmaintenanceEnables tracking worked hours by client, project, and task, with monthly/daily reports and natural language interaction through Claude.-
- AlicenseNot gradedqualityCmaintenanceEnables local-first time tracking with timers and time entries stored in a SQLite database that sync to Intervals in the background, with local-only reporting and queries.23 npmMIT