Skip to content

refactor(mcp): consolidate write tools, retire resources, reads-as-tools#1872

Merged
canalesb93 merged 8 commits into
mainfrom
worktree-mcp-tool-consolidation
Jun 24, 2026
Merged

refactor(mcp): consolidate write tools, retire resources, reads-as-tools#1872
canalesb93 merged 8 commits into
mainfrom
worktree-mcp-tool-consolidation

Conversation

@canalesb93

@canalesb93 canalesb93 commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Audits and reshapes the Breadbox MCP surface. Lands in three movements (commit-by-commit).

1. Fold near-duplicate write/sugar tools

Removed Folded into
remove_ / replace_ / clear_transaction_metadata set_transaction_metadata (set / unset / replace)
set_series_type, add_series_tag, remove_series_tag update_series (type, tags_to_add, tags_to_remove)
flag_transaction, unflag_transaction update_transactions op (flagged)
count_transactions query_transactions(count_only=true)
batch_create_rules create_transaction_rule (rules[] of 1..100)

Each compound handler reuses the existing service methods, so semantics (category precedence, series collision guards / sticky type / tag provenance, rule chaining) are unchanged. The only service-layer change is a flagged step in runUpdateOpInTx so it's atomic with the rest of the op.

2. Retire MCP resources entirely

The resources/* surface (and resource templates) is gone. Resources were invisible to clients that can't resources/list (e.g. Claude.ai), so they carried no load. Deleted resources.go, registerResources, every resource/template handler, and their tests.

3. Reads as tools; get_reference serves the guidance docs

  • The seven bounded reference reads are individual tools again: get_overview, list_accounts, list_categories, list_users, list_tags, get_sync_status, list_transaction_rules.
  • get_reference is repurposed to serve the operating-guidance markdown by kindinstructions | rule-dsl | review-guidelines | report-format. That's how resource-incapable clients now reach the guidance that used to live only in breadbox:// markdown resources. instructions/review-guidelines/report-format honor app_config overrides; rule-dsl is the fixed grammar.
  • Per-entity drilldown templates are gone — reconstruct from query_transactions + list_annotations / list_accounts.

End state: 34 tools, 0 resources.

Tests / docs

  • Updated the registry-scope contract test (18 reads); rewrote the flag integration harness to drive update_transactions; deleted the resource/template tests and the resource-parity test.
  • Scrubbed every breadbox:// / get_reference(kind=<data>) / count_transactions / batch_create_rules reference across tool descriptions, input schemas, the MCP server instructions, the agent strategy prompts, the admin tool-group map, and the docs (mcp-tools-reference, mcp-server, architecture, data-model, rule-dsl, api-reference, .claude/rules/mcp.md).
  • go build + go vet + unit + internal/mcp / internal/service / internal/api integration all green.

🤖 Generated with Claude Code

canalesb93 and others added 4 commits June 15, 2026 22:52
Fold near-duplicate / sugar MCP tools into their compound siblings so an
agent reaches for one obvious tool per entity, and the registry stays small.

- metadata: set/remove/replace/clear_transaction_metadata → one
  set_transaction_metadata (set merge / unset / replace).
- series: set_series_type + add/remove_series_tag → fields on update_series
  (type, tags_to_add, tags_to_remove); each sub-change reuses the same
  service method, so collision guards / sticky type / tag provenance are
  unchanged.
- flag: flag_transaction + unflag_transaction → flagged *bool on an
  update_transactions op (reason rides in the op's comment). Adds a flag
  step to runUpdateOpInTx so it's atomic with the rest of the op.
- count: count_transactions → query_transactions(count_only=true).
- rules: batch_create_rules → create_transaction_rule now takes a rules[]
  of 1..100 specs (each may apply_retroactively).
- reference: get_overview / list_accounts / list_categories / list_users /
  list_tags / get_sync_status / list_transaction_rules → one get_reference
  (kind=…) that dispatches to the existing per-kind handlers. Filtered rule
  analysis stays in query_transaction_rules.

Updated the registry-scope contract test, rewrote the flag integration
harness to drive update_transactions, and refreshed mcp-tools-reference,
mcp-server, data-model, rule-dsl, api-reference, and the .claude/rules/mcp
rule. Build + vet + unit + mcp/service integration all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These four resources were exact duplicates of get_reference(kind=…) and,
being pure agent-facing lookup tables (not human-attach material), carried
no load on the resource surface — especially on clients that can't
resources/list. Read them via the tool instead.

Resource surface 13 → 9: kept overview / accounts / sync-status (a human
plausibly attaches those snapshots), the three static-doc resources
(rule-dsl / report-format / review-guidelines), and the three drilldown
templates.

- Drop the 4 AddResource registrations + their handlers (+ rulesResourceLimit).
- Removed TestRulesResourceShape; trimmed the resource/tool parity test to
  the three pairs that still have both surfaces.
- Scrubbed every "breadbox://{categories,tags,users,rules}" pointer in tool
  descriptions, input schemas, the MCP server instructions, the rule-dsl /
  review-guidelines prompts, and the docs → get_reference(kind=…).

Build + vet + unit + mcp integration green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
breadbox://accounts was an exact duplicate of get_reference(kind=accounts)
(where the old list_accounts tool folded). Agents read accounts via the tool;
the per-account drilldown stays as the breadbox://account/{short_id} template.

Resource surface 9 → 8: only overview + sync-status remain as data resources
(human-attachable snapshots), alongside the 3 static-doc resources and 3
drilldown templates.

- Drop the AddResource registration + handleAccountsResource.
- Trim the resource/tool parity test to the two pairs left (sync_status, overview).
- Scrub breadbox://accounts pointers from the server instructions and docs.

Build + vet + unit + mcp integration green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…es docs

A deliberate reshape of the read surface:

- Retire the MCP resources/* surface entirely (and the resource templates).
  Resources were invisible to clients that can't resources/list (e.g.
  Claude.ai), so everything is a tool now. Deleted resources.go,
  registerResources, and all resource/template handlers + their tests.
- Re-introduce the seven bounded reference reads as individual tools:
  get_overview, list_accounts, list_categories, list_users, list_tags,
  get_sync_status, list_transaction_rules (handlers already lived in
  tools_reads.go; this just registers them again).
- Repurpose get_reference to serve the operating-guidance docs by kind:
  instructions | rule-dsl | review-guidelines | report-format. Returns
  markdown; instructions/review-guidelines/report-format honor app_config
  overrides, rule-dsl is the fixed grammar. This is how resource-incapable
  clients now reach the guidance that used to live only in breadbox://
  markdown resources.

Registry: 34 tools, 0 resources. Per-entity drilldown templates are gone —
reconstruct from query_transactions + list_annotations / list_accounts.

Also scrubbed every breadbox:// / get_reference(kind=<data>) /
count_transactions / batch_create_rules reference across tool descriptions,
input schemas, the MCP instructions + agent strategy prompts, the admin
tool-group map, and the docs. Build + vet + unit + mcp/service/api
integration all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@canalesb93 canalesb93 changed the title refactor(mcp): consolidate tool surface 43 → 27 refactor(mcp): consolidate write tools, retire resources, reads-as-tools Jun 16, 2026
canalesb93 and others added 4 commits June 23, 2026 21:33
Resolves conflicts from main's rules-as-substrate merge (#1906) plus
#1871/#1874/#1876 against this PR (retire MCP resources, reads-as-tools,
get_reference for docs, write-tool consolidation).

Resolution decisions:
- Series subsystem: adopt main's model wholesale. #1906 removed
  rekey_series / split_series / review_series / explain_series_candidates
  (handlers + service methods gone) and kept add_series_tag /
  remove_series_tag as separate tools with a name/type-only update_series.
  Backed out this PR's series-tag fold into update_series accordingly and
  updated .claude/rules/mcp.md to match.
- create_transaction_rule: keep this PR's `rules` array shape (folds
  batch_create_rules) but carry main's enriched per-rule DSL
  (metadata/series/flag actions, approx/between ops, date-part fields).
  Updated the reviewer response-shape integration test to read the batch
  envelope.
- MCP resources stay retired: dropped main's re-added registerResources
  (incl. the new counterparty resource template) and the resources.go
  modifications; everything remains a tool.
- Dead prompt files deleted by #1871 (strategy-anomaly-detection /
  -initial-setup / -quick-review) accepted as deletions.
- Docs/prompts: take main for the series model + rules-substrate
  semantics (category_id direct, no category_override); keep this PR's
  tool surface (get_reference, create_transaction_rule rules array).
  Dropped a stray </content> artifact from prompts/mcp/rule-dsl.md.

Verified: go build ./..., go vet ./..., go test ./... (unit), and
integration for internal/mcp + internal/service + internal/api all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7qg4TN9ZPcHsXR714UrjG
Carry the PR's consolidation philosophy into the tools main added in the
rules-as-substrate merge (#1906), so series and counterparties mirror
each other and the transaction pattern (list/get/assign/update/unlink).

- Fold add_series_tag + remove_series_tag into update_series via
  tags_to_add / tags_to_remove (same pattern as update_transactions;
  each tag sub-change still calls AddSeriesTag/RemoveSeriesTag, so
  inheritance/provenance is unchanged).
- Fold create_counterparty into assign_counterparty: mint via
  create_if_missing, preserve strict-create as an optional
  fail_if_exists flag, and apply enrichment (website_url/logo_url/
  category_id/mcc) inline — losing no capability. Mint a bare
  counterparty by passing name + create_if_missing with no
  transaction_ids.
- Rename unlink_counterparty_transaction → unlink_counterparty_transactions
  for parity with unlink_series_transactions.

Net: 38 → 35 tools. Updated docs/mcp-tools-reference.md and
.claude/rules/mcp.md to match. Verified: go build ./..., go vet ./...,
and the full internal/mcp integration suite green on a clean DB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7qg4TN9ZPcHsXR714UrjG
Align the workflow/MCP prompts main carried in with the consolidated tool
surface — these were instructing agents to call tools that no longer exist:

- category-system.md: categorize_transaction / batch_categorize_transactions
  / reset_transaction_category / bulk_recategorize → update_transactions
  (reset via reset_category; bulk via query_transactions + batches, or a rule).
- strategy-transaction-reviewer.md, rules-curriculum.md: batch_create_rules →
  create_transaction_rule (rules array).
- rules-curriculum.md: breadbox://rule-dsl → get_reference(kind=rule-dsl);
  "one-off MCP tools" → update_transactions / assign_series / assign_counterparty.
- rule-dsl.md: flag/unflag now reference update_transactions(flagged), not the
  removed flag_transaction tool.
- report-format.md: dropped the create_session instruction (sessions are
  automatic; reason travels via tools/call._meta).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7qg4TN9ZPcHsXR714UrjG
Pull in main (#1907#1919). Two changes interact with this PR:

- #1918 fully removed series tags (AddSeriesTag/RemoveSeriesTag service
  methods gone). Reverted this PR's update_series tag fold: update_series
  is back to name/type only, and the tags_to_add/tags_to_remove input +
  handler loops are removed. Series no longer have a tag dimension.
- #1913 added four series/counterparty workflow preset prompts written
  against main's older tool surface. Scrubbed their stale refs to match
  the consolidated tools: breadbox://overview → get_overview;
  batch_create_rules → create_transaction_rule rules array; set_series_type
  / split_series / review_series / explain_series_candidates (all removed
  upstream) → update_series / unlink_series_transactions / get_series.

Resolved the docs/mcp-tools-reference.md conflict by taking main's
series-unlink description (no tags). The counterparty create→assign fold
and unlink rename from the prior commit are preserved.

Verified: go build ./..., go vet ./..., and the full internal/mcp
integration suite green on a clean DB.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7qg4TN9ZPcHsXR714UrjG
@canalesb93 canalesb93 merged commit 25cb06f into main Jun 24, 2026
8 checks passed
@canalesb93 canalesb93 deleted the worktree-mcp-tool-consolidation branch June 24, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant