Skip to main content
Glama

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

ESTIMATE_MAESTRO_STORE

$XDG_DATA_HOME/estimate-maestro, con respaldo en ~/.local/share/estimate-maestro

Ruta al directorio del almacén.

ESTIMATE_MAESTRO_DAY_START

09:00

Inicio del día laboral (hora ISO 8601).

ESTIMATE_MAESTRO_DAY_END

17:00

Fin del día laboral (hora ISO 8601).

ESTIMATE_MAESTRO_LUNCH_START

12:00

Inicio de la pausa diaria de almuerzo, excluida de los segundos laborales.

ESTIMATE_MAESTRO_LUNCH_END

13:00

Fin de la pausa diaria de almuerzo.

ESTIMATE_MAESTRO_WORKDAYS

0,1,2,3,4

Días de la semana separados por comas contados como laborales (lunes 0 … domingo 6).

ESTIMATE_MAESTRO_OFF_HOURS_SESSION_CAP_MINUTES

240 (4 horas)

Duración máxima asignada a una sesión limitada que comienza fuera de la ventana de horas laborales.

ESTIMATE_MAESTRO_DERIVE_LEAD_IN_MINUTES

30

Tiempo añadido antes del commit más temprano en una sesión derivada, para cubrir trabajo hecho antes del primer commit.

ESTIMATE_MAESTRO_DERIVE_SESSION_GAP_MINUTES

120 (2 horas)

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.

ESTIMATE_MAESTRO_MINIMUM_EFFORTS

5

Número mínimo de esfuerzos registrados antes de que summary informe cifras en lugar de una negativa honesta.

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

0

Éxito.

1

Ocurrió un error.

3

Solo clock-out: no había nada registrado. Esperado y frecuente, no un fallo — un script que conecte clock-out a un hook automático debería tratar 3 igual que 0.

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-maestro

Crea 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-work

Convierte 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 init

La 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/else

Conecta 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/ -v

Available Tools

21 tools
add_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

    C2.8/5.0

    Scored across 21 tools

    Disambiguation5/5

    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.

    Naming Consistency4/5

    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.

    Tool Count4/5

    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.

    Completeness5/5

    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

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers