estimate-maestro
estimate-maestro
個人的なMCPサーバー兼コマンドラインツールで、見積もりと実経過時間を記録し、見積もりを最終的に「感覚」ではなく「結果」と照合できるようにするためのものです。
これは見積もりキャリブレーションのためのデータ収集ツールであり、見積もりツールではありません。 何かの見積もりを自動で行うことは一切ありません。記録するのは、ある作業に対してあなたが立てた見積もり、計画が実際にどうなったか、そしてその作業に実際にかかった実時間です。その記録をどう使うか(比較する、ずれに気づく、ある種の作業について一貫して楽観的だったと判断するなど)は、あなた自身と、後でストアを読み出すものに委ねられています。このツールの役割は、正直に記録するところまでで終わりです。
モデル
記録されるものは4種類あります。
Effort(エフォート) — 単独で追跡する価値のある作業のかたまり。プルリクエスト、メガPR、計画と規模を持つものすべてが該当します。エフォートは、計画アーティファクト(仕様書、
.PR.md、計画が置かれているもの)と初期見積もりが存在した時点から存在します。それ以前は、まだ記録すべきものはありません。Slice(スライス) — エフォートの一部で、通常はサブPRです。スライスは追加、プルリクエストに対するクローズ、破棄、リネームが行われます。エフォート開始前に追加されたスライスは当初計画の一部であり、開始後に追加されたものはスコープの拡大であり、この2つは記録上区別可能なまま保持されます。
Interval(インターバル) — クロックインされた時間の区間で、通常はスライスに対して行われます。インターバルは手動でクローズされるか、セッション終了時に時計がまだ動いている場合は自動的にクローズされるか、何もクロックインされていなかった場合はコミットタイムスタンプから事後的に導出されます。
Absence(欠勤) — まったく作業しなかった時間。休日、予定、無関係な会議などです。欠勤は事後的に記録され、それが想定されています。欠勤は重なるインターバルから差し引かれます。
Related MCP server: time-tracker-ai-mcp
見積もり: ストーリーポイントによる3点見積もり
すべての見積もりはPERTトリプル(楽観値、最頻値、悲観値)であり、抽象的なポイントスケールで与えられ、時間単位では決してありません。期待値と標準偏差は読み出し時にトリプルから導出されます。「見積もりはNである」という単一の数値はどこにも保存されません。なぜなら、裸の数値は、それが事実ではなく見積もりであることを示す不確実性を捨て去ってしまうからです。
ポイントは、手元の作業を同様の形状の過去のエフォートと比較することでアンカーされ、頭の中で感じた時間数をポイントに変換するのではありません。抽象スケールの要点は、実際の期間がまだわからないエフォート同士を、同種のもの同士で比較することにあります。
エフォートは2回見積もられます。
初期見積もりは、最初に書かれた計画に対して、計画が開始したときと同じスライス数で行われます。
最終見積もりは、レトロスペクティブで、実際に結果として得られた計画(途中で挿入されたすべてのスライスを含む)に対して行われます。これは反事実的なものです。「これが実際にどう転んだかを今すべて知っているとしたら、あなたは何と見積もっただろうか?」という問いであり、「どれだけ時間がかかったか?」でも、何かの測定でもありません。
見積もりを2回に分けることで、見積もりが間違う2つの方法を事後に分離できるようになります。初期パスは在庫エラーによって間違う可能性があります。つまり、まだ誰も知らない作業が存在した、または存在すると想定された作業が実際には存在しなかった、という場合です。実際に結果として得られた計画に対して行われる最終パスは、サイズエラーを分離します。つまり、最初から知られていた項目を単に誤って判断した場合です。エフォートごとに単一の数値ではこの2つが混同されますが、パスごとに2つの数値があれば、それらを分離できます。
また、エフォート途中で改訂見積もりを記録することもできます(通常は当初計画にないスライスが挿入されたとき)。レトロスペクティブを待つ必要はありません。
時間モデル: 通常の1日が想定される
通常の勤務日がデフォルトで想定され、そこからの逸脱のみが記録されます。 クロックインとクロックアウトは例外であり、日常的なものではありません。このツールは毎日8時間ストップウォッチが動いていることを想定していません。具体的には:
手動でクロックされた時間は、それが何時であろうと全額カウントされます。 夜間や週末も含みます。土曜日の22:00にクロックインしたなら、それは実際の時間であり、そのまま記録され、勤務時間の調整は適用されません。
勤務時間モデルは、実際に時間が記録されなかった場所にのみ適用されます。 使用されるのは正確に2か所です:
忘れられたタイマーのクランプ。 セッションが時計がまだ動いたまま終了した場合、インターバルは設定された勤務日の終了時刻(または設定された勤務日・時間外では、固定のセッション長に上限)でクローズされ、無期限に開いたままになったり、分単位で推測されたりすることはありません。
コミットタイムスタンプからのインターバル再構築。 スライスに対して何もクロックインされなかった場合。近接したコミットのクラスターは導出された作業セッションになり、勤務時間モデルを使用して、それらの間のスパンのうちどれだけが作業としてカウントされ、どれだけが一晩のギャップとしてカウントされるかを決定します。
記録された欠勤は、それが重なる任意のインターバル(クロックされたもの、導出されたもの)から差し引かれます。手動でクロックされたインターバルでは全額、導出されたインターバルでは勤務時間モデルを通じて差し引かれます。
ツールカテゴリと汚染ルール
MCPサーバーが公開するすべてのツールは、正確に1つのカテゴリに分類されます:
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。見積もりを作成している間、比較用に過去のエフォートを表示します。status(ステータス) —
current。何がクロックインされていて、いつからかを報告します。calibration(キャリブレーション) —
effort_table、effort_detail、summary。蓄積された記録を読み出します。
recording、estimation、statusツールは、期間や集計値を返すことはありません。calibrationツールのみが返すことができます。 これは構造的に強制されます。recording、estimation、statusツールで使用されるすべてのレスポンスモデルは、hours、minutes、duration、wall、average、shareなどの単語を含むフィールド名がないかチェックされ、見つかった場合はチェックが失敗します。
その理由は整理整頓のためではありません。実際の作業時間を見た後に行われた見積もりは、その時間のアンカーされたエコーであり、独立した判断ではありません。あなたが生成する数値は、ちょうど答えを見たばかりであるために汚染されています。汚染ルールにより、見積もりが作成されている間や時計が実行されている間、壁時計の数値がツールのレスポンスに表示されることは決してなく、初期対最終の比較が正直に保たれます。calibrationツールは、見積もりが完了した後に、まさにそれらの数値を報告することが目的であるため、免除されます。
環境変数
すべてオプションです。すべてにデフォルトがあります。このリストと矛盾する場合は、src/estimate_maestro/config.pyを参照してください。
変数 | デフォルト | 意味 |
|
| ストアディレクトリへのパス。 |
|
| 勤務日の開始時刻(ISO 8601形式)。 |
|
| 勤務日の終了時刻(ISO 8601形式)。 |
|
| 毎日の昼休みの開始時刻。勤務秒数から除外されます。 |
|
| 毎日の昼休みの終了時刻。 |
|
| 勤務日としてカウントされる曜日をカンマ区切りで指定(月曜 |
|
| 勤務時間外に開始されたクランプされたセッションに与えられる最大長。 |
|
| 導出されたセッションの最初のコミットの前に追加される時間。最初のコミット前の作業をカバーします。 |
|
| コミット間の作業時間のギャップ。これを超えると、導出されたセッションは終了し、新しいセッションが開始されたと見なされます。 |
|
|
|
ESTIMATE_MAESTRO_DERIVE_LEAD_IN_MINUTESはESTIMATE_MAESTRO_DERIVE_SESSION_GAP_MINUTESを超えてはなりません。そうでない場合、サーバーは起動を拒否します。
コマンドラインツール
estimate-maestro-cliは、会話を必要としない日常的な記録アクションをカバーします: clock-in、clock-out、current、record-absence、effort-table、summary。見積もり会話の一部としてのみ意味を持つアクション(エフォートの開始、見積もりの改訂、最終計画の記録、コミットの収穫)は、意図的にMCPツールのみであり、CLIコマンドではありません。それらは、比較可能な過去のエフォートを表示するセッション内で行われることを意図しており、そのコンテキストなしで入力される裸のコマンドではありません。
終了コード
コード | 意味 |
| 成功。 |
| エラーが発生しました。 |
|
|
インストール
以下のいずれもあなたのために実行されていません。以下のコマンドをコピーして自分で実行してください。
MCPサーバーを登録します:
claude mcp add --scope user maestro-estimate -- uv --directory ~/mcp/estimate-maestro run estimate-maestro2つのスキルを個人スキルディレクトリにシンボリックリンクします:
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ストアをgitリポジトリにします。そのファイルはプレーンテキストで追記専用のため、コミットしてマシン間を移動でき、記録された内容の唯一の生き残りコピーとなります。そこで失われたり誤ったりした数値は、他のどこからも再構築できません。プライベートに保ってください。プロジェクト名、ブランチ名、所要時間が含まれており、いずれも公開リポジトリに置くべきものではありません。
mkdir -p ~/.local/share/estimate-maestro
git -C ~/.local/share/estimate-maestro initデフォルトのストア場所はXDG Base Directory Specificationに従い、設定は不要です。ストアを別の場所に置きたい場合のみESTIMATE_MAESTRO_STOREを設定してください。たとえば他の個人リポジトリと並べて、コミットとプッシュを忘れないようにしやすくするためです。サーバーとシェルの両方から見える必要があるため、両方が読み取る場所(通常はシェルプロファイル)に置いてください。
export ESTIMATE_MAESTRO_STORE=~/somewhere/else2つのフックスクリプトを~/.claude/settings.jsonに配線します。hooks/session-end.shをSessionEndフックとして(忘れられたタイマーを閉じ、設定された勤務日にクランプ)、hooks/session-start.shをSessionStartフックとして(タイマーがすでに実行中かどうかを報告):
{
"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" }
]
}
]
}
}すでにhooksブロックがある場合は、~/.claude/settings.jsonの既存のhooksブロックに上書きではなくマージしてください。
開発
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