Skip to main content
Glama

estimate-maestro

Ein persönlicher MCP-Server und ein Kommandozeilen-Tool zum Aufzeichnen von Schätzungen und tatsächlicher Zeit, damit Schätzungen schließlich gegen Ergebnisse statt gegen Gefühle geprüft werden können.

Dies ist ein Datenerfassungswerkzeug zur Schätzkalibrierung, kein Schätzer. Es schätzt nie etwas für dich. Es zeichnet auf, wie du ein Stück Arbeit geschätzt hast, wie sich der Plan tatsächlich entwickelt hat und wie viel tatsächliche Zeit die Arbeit in Anspruch genommen hat. Was du mit dieser Aufzeichnung machst – vergleichen, Abweichungen bemerken, feststellen, dass du bei einer bestimmten Art von Arbeit durchweg optimistisch warst – liegt bei dir und bei dem, was den Speicher später liest. Die Aufgabe des Tools endet beim ehrlichen Aufzeichnen.

Das Modell

Vier Arten von Dingen werden aufgezeichnet:

  • Effort – ein Stück Arbeit, das es wert ist, eigenständig verfolgt zu werden: ein Pull Request, ein Mega-PR, alles mit einem Plan und einer Größe. Ein Effort existiert von dem Moment an, in dem er ein Plan-Artefakt (eine Spezifikation, eine .PR.md, was auch immer der Plan enthält) und eine erste Schätzung hat. Vor diesem Zeitpunkt gibt es noch nichts aufzuzeichnen.

  • Slice – ein Teil eines Efforts, normalerweise ein Sub-PR. Slices werden hinzugefügt, gegen einen Pull Request geschlossen, verworfen oder umbenannt. Ein Slice, der vor dem Start des Efforts hinzugefügt wird, gehört zum ursprünglichen Plan; einer, der danach hinzugefügt wird, ist Scope-Wachstum, und die beiden werden in der Aufzeichnung unterscheidbar gehalten.

  • Intervall – eine eingestempelte Zeitspanne, normalerweise gegen einen Slice. Intervalle werden manuell geschlossen, automatisch geschlossen, wenn eine Sitzung endet und die Uhr noch läuft, oder nachträglich aus Commit-Zeitstempeln abgeleitet, wenn überhaupt nichts eingestempelt wurde.

  • Abwesenheit – Zeit, die überhaupt nicht gearbeitet wurde: ein Feiertag, ein Termin, ein unzusammenhängendes Meeting. Abwesenheiten werden nachträglich aufgezeichnet und sind zu erwarten. Sie subtrahieren von jedem Intervall, das sie überlappen.

Related MCP server: time-tracker-ai-mcp

Schätzungen: Drei-Punkt-Tripel in Story Points

Jede Schätzung ist ein PERT-Tripel – optimistisch, wahrscheinlich, pessimistisch – in einer abstrakten Punktskala, niemals in Stunden. Der Erwartungswert und die Standardabweichung werden beim Lesen aus dem Tripel abgeleitet; nichts speichert eine einzelne Zahl „die Schätzung ist N“, weil eine bloße Zahl die Unsicherheit wegwirft, die sie zu einer Schätzung statt zu einer Tatsache machte.

Punkte werden verankert, indem man die vorliegende Arbeit mit früheren Efforts ähnlicher Form vergleicht, nicht indem man eine gefühlte Anzahl von Stunden im Kopf in Punkte umrechnet. Der ganze Sinn einer abstrakten Skala ist es, Gleiches mit Gleichem über Efforts hinweg zu vergleichen, deren tatsächliche Dauer du noch nicht kennst.

Ein Effort wird zweimal geschätzt:

  • Die erste Schätzung, die gegen den Plan, wie er ursprünglich geschrieben wurde, bei derselben Slice-Anzahl, mit der der Plan begann, erstellt wird.

  • Die endgültige Schätzung, die bei der Retrospektive gegen den Plan, wie er sich tatsächlich entwickelt hat – einschließlich jedes Slices, der unterwegs eingefügt wurde – erstellt wird. Dies ist eine kontrafaktische Schätzung: „Angesichts alles, was du jetzt darüber weißt, wie sich das tatsächlich entwickelt hat, was hättest du geschätzt?“ – niemals „Wie lange hat es gedauert?“ und niemals eine Messung von irgendetwas.

Die Aufteilung der Schätzung in zwei Durchgänge macht die zwei Arten, wie eine Schätzung falsch sein kann, nachträglich trennbar. Der erste Durchgang kann wegen Inventarfehlern falsch sein – Arbeit existierte, von der niemand wusste, oder Arbeit, von der angenommen wurde, dass sie existiert, stellte sich als nicht existent heraus. Der endgültige Durchgang, der gegen den Plan, wie er sich tatsächlich entwickelt hat, erstellt wird, isoliert Größenfehler – die Punkte, die die ganze Zeit bekannt waren und nur falsch beurteilt wurden. Eine einzelne Zahl pro Effort vermischt die beiden; zwei Zahlen, eine pro Durchgang, halten sie getrennt.

Eine überarbeitete Schätzung kann auch mitten im Effort aufgezeichnet werden – typischerweise wenn ein Slice eingefügt wird, der nicht im ursprünglichen Plan war – ohne auf die Retrospektive zu warten.

Das Zeitmodell: Ein normaler Tag wird angenommen

Ein normaler Arbeitstag wird standardmäßig angenommen, und nur Abweichungen davon werden aufgezeichnet. Ein- und Ausstempeln ist die Ausnahme, nicht die Routine – das Tool erwartet keine Stoppuhr, die acht Stunden am Tag läuft. Konkret:

  • Manuell gestempelte Zeit zählt vollständig, egal in welche Stunden sie fällt. Abende und Wochenenden eingeschlossen: Wenn du um 22:00 Uhr an einem Samstag eingestempelt hast, ist das echte Zeit und wird als solche aufgezeichnet, ohne Anpassung an Arbeitszeiten.

  • Das Arbeitszeitenmodell wird nur dort angewendet, wo keine Zeit tatsächlich aufgezeichnet wurde. Es gibt genau zwei Stellen, an denen es verwendet wird:

    • Begrenzung einer vergessenen Uhr. Wenn eine Sitzung endet und die Uhr noch läuft, wird das Intervall am konfigurierten Ende des Arbeitstages geschlossen (oder, außerhalb der konfigurierten Arbeitstage und -stunden, auf eine feste Sitzungslänge begrenzt), anstatt offen zu bleiben oder auf die Minute genau geraten zu werden.

    • Rekonstruktion von Intervallen aus Commit-Zeitstempeln, wenn für einen Slice nie etwas eingestempelt wurde. Ein Cluster nahe beieinanderliegender Commits wird zu einer abgeleiteten Arbeitssitzung, wobei das Arbeitszeitenmodell entscheidet, wie viel der Spanne zwischen ihnen als Arbeit zählt und nicht als nächtliche Lücke.

Eine Abwesenheit, die über eine Spanne aufgezeichnet wird, subtrahiert von jedem Intervall – gestempelt oder abgeleitet – das sie überlappt, vollständig für ein manuell gestempeltes Intervall und über das Arbeitszeitenmodell für ein abgeleitetes.

Tool-Kategorien und die Taint-Regel

Jedes Tool, das der MCP-Server bereitstellt, fällt in genau eine Kategorie:

  • recording – 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.

  • estimation – reference_efforts, das frühere Efforts zum Vergleich zeigt, während eine Schätzung erstellt wird.

  • status – current, das meldet, was eingestempelt ist und seit wann.

  • calibration – effort_table, effort_detail, summary, die die angesammelte Aufzeichnung wieder auslesen.

Recording-, Estimation- und Status-Tools geben niemals eine Dauer oder einen Aggregatwert zurück. Nur Calibration-Tools dürfen das. Dies wird strukturell durchgesetzt: Jedes Antwortmodell, das von einem Recording-, Estimation- oder Status-Tool verwendet wird, wird auf Feldnamen geprüft, die Wörter wie hours, minutes, duration, wall, average oder share enthalten, und die Prüfung schlägt fehl, wenn eines gefunden wird.

Der Grund ist nicht Ordnungsliebe. Eine Schätzung, die nach dem Ansehen der tatsächlichen Dauer der Arbeit erstellt wird, ist ein verankertes Echo dieser Dauer, kein unabhängiges Urteil – die Zahl, die du produzieren würdest, ist kontaminiert, weil du gerade die Antwort gesehen hast. Die Taint-Regel verhindert, dass eine tatsächliche Zeitangabe jemals in einer Tool-Antwort auftaucht, während eine Schätzung erstellt oder eine Uhr betrieben wird, damit der Vergleich zwischen erster und endgültiger Schätzung ehrlich bleibt. Calibration-Tools sind ausgenommen, weil ihr gesamter Zweck darin besteht, genau diese Zahlen zu melden, sobald das Schätzen abgeschlossen ist.

Umgebungsvariablen

Alle sind optional; jede hat einen Standardwert. Lies aus src/estimate_maestro/config.py, nicht aus dieser Liste, falls die beiden jemals abweichen.

Variable

Standard

Bedeutung

ESTIMATE_MAESTRO_STORE

$XDG_DATA_HOME/estimate-maestro, fallback auf ~/.local/share/estimate-maestro

Pfad zum Speicherverzeichnis.

ESTIMATE_MAESTRO_DAY_START

09:00

Beginn des Arbeitstages (ISO-8601-Zeit).

ESTIMATE_MAESTRO_DAY_END

17:00

Ende des Arbeitstages (ISO-8601-Zeit).

ESTIMATE_MAESTRO_LUNCH_START

12:00

Beginn der täglichen Mittagspause, ausgeschlossen von Arbeitssekunden.

ESTIMATE_MAESTRO_LUNCH_END

13:00

Ende der täglichen Mittagspause.

ESTIMATE_MAESTRO_WORKDAYS

0,1,2,3,4

Kommagetrennte Wochentage, die als Arbeitstage zählen (Montag 0 … Sonntag 6).

ESTIMATE_MAESTRO_OFF_HOURS_SESSION_CAP_MINUTES

240 (4 Stunden)

Maximale Länge, die einer begrenzten Sitzung gegeben wird, die außerhalb des Arbeitszeitenfensters beginnt.

ESTIMATE_MAESTRO_DERIVE_LEAD_IN_MINUTES

30

Zeit, die vor dem frühesten Commit in einer abgeleiteten Sitzung hinzugefügt wird, um Arbeit vor dem ersten Commit abzudecken.

ESTIMATE_MAESTRO_DERIVE_SESSION_GAP_MINUTES

120 (2 Stunden)

Arbeitszeitlücke zwischen Commits, nach der eine abgeleitete Sitzung als beendet und eine neue als begonnen gilt.

ESTIMATE_MAESTRO_MINIMUM_EFFORTS

5

Mindestanzahl aufgezeichneter Efforts, bevor summary Zahlen statt einer ehrlichen Ablehnung meldet.

ESTIMATE_MAESTRO_DERIVE_LEAD_IN_MINUTES darf ESTIMATE_MAESTRO_DERIVE_SESSION_GAP_MINUTES nicht überschreiten; der Server weigert sich sonst zu starten.

Das Kommandozeilen-Tool

estimate-maestro-cli deckt die alltäglichen Aufzeichnungsaktionen ab, die kein Gespräch benötigen: clock-in, clock-out, current, record-absence, effort-table und summary. Aktionen, die nur als Teil eines Schätzgesprächs sinnvoll sind – einen Effort starten, eine Schätzung überarbeiten, den endgültigen Plan aufzeichnen, Commits ernten – sind absichtlich nur MCP-Tools, keine CLI-Befehle: Sie sollen in einer Sitzung stattfinden, die vergleichbare frühere Efforts zeigt, nicht als bloßer Befehl, der ohne diesen Kontext getippt wird.

Exit-Codes

Code

Bedeutung

0

Erfolg.

1

Ein Fehler ist aufgetreten.

3

Nur clock-out: Es war nichts eingestempelt. Erwartet und häufig, kein Fehler – ein Skript, das clock-out in einen automatischen Hook einbindet, sollte 3 genauso behandeln wie 0.

Installation

Nichts von dem Folgenden wurde für dich ausgeführt – kopiere die untenstehenden Befehle und führe sie selbst aus.

Registriere den MCP-Server:

claude mcp add --scope user maestro-estimate -- uv --directory ~/mcp/estimate-maestro run estimate-maestro

Verknüpfe die beiden Skills mit deinem persönlichen Skills-Verzeichnis:

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

Machen Sie den Speicher zu einem Git-Repository. Seine Dateien sind reiner Text und nur anhängen, sodass es committet und zwischen Maschinen wandern kann, und es ist die einzige überlebende Kopie dessen, was es aufzeichnet: Eine Zahl, die dort verloren geht oder falsch ist, kann von keinem anderen Ort rekonstruiert werden. Halten Sie es privat – es enthält Projektnamen, Branchnamen und wie lange Dinge gedauert haben; keines davon gehört in ein öffentliches Repository.

mkdir -p ~/.local/share/estimate-maestro
git -C ~/.local/share/estimate-maestro init

Der Standardspeicherort folgt der XDG Base Directory Specification und benötigt keine Konfiguration. Setzen Sie ESTIMATE_MAESTRO_STORE nur, wenn Sie den Speicher woanders haben möchten – zum Beispiel neben Ihren anderen persönlichen Repositories, damit Sie leichter daran denken, zu committen und zu pushen. Er muss sowohl für den Server als auch für Ihre Shell sichtbar sein. Platzieren Sie ihn also dort, wo beide lesen (typischerweise in Ihrem Shell-Profil):

export ESTIMATE_MAESTRO_STORE=~/somewhere/else

Verdrahten Sie die beiden Hook-Skripte in ~/.claude/settings.json: hooks/session-end.sh als SessionEnd-Hook (schließt einen vergessenen Timer, begrenzt auf den konfigurierten Arbeitstag) und hooks/session-start.sh als SessionStart-Hook (meldet, ob bereits ein Timer läuft):

{
  "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" }
        ]
      }
    ]
  }
}

Fügen Sie das in den vorhandenen hooks-Block in ~/.claude/settings.json ein, anstatt ihn zu überschreiben, falls bereits einer vorhanden ist.

Entwicklung

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