Skip to content

fix: keep money tools off the MCP server by default; release mcp 0.2.1 and cli 0.4.2 - #33

Merged
sonpiaz merged 3 commits into
mainfrom
fix/mcp-safe-tools
Oct 12, 2026
Merged

sonpiaz merged 3 commits into
mainfrom
fix/mcp-safe-tools

Conversation

@sonpiaz

@sonpiaz sonpiaz commented Oct 12, 2026

Copy link
Copy Markdown
Member

Two releases, prepared but not published (publishing to npm is approved separately).

@affitor/mcp 0.2.1 — money tools off by default

affitor_track_sale creates a real sale and commission and affitor_track_refund reverses one. In 0.2.0 both were offered to every agent that loaded the server, with no annotations, so an agent exploring its tools could move money.

0.2.0 0.2.1
Tools without config 7, incl. sale/refund 5 (readiness, lead, click, integration plan, verification)
AFFITOR_MCP_WRITE=1 — adds sale + refund
Annotations none every tool: readOnlyHint, destructiveHint, idempotentHint, openWorldHint; sale/refund destructive
testMode — sale: additional_data.test_mode → is_test sale, no commission (direct POST, the SDK has no field for it); lead: test lead; refund: dry run, no call (the API has no test refunds)

Behavior change: an agent that calls affitor_track_sale today must add AFFITOR_MCP_WRITE=1 to the server's env. Called out in CHANGELOG.md and the README.

affitor 0.4.2 — publish what main already has

npm still serves the 0.4.1 build from 15/06. Main has since gained the secrets-file permission + safe login URL fix (#26), key-rotation warnings and retired-key errors (#27, #28, #30), exit-code fixes (#29: whoami --json logged out now exits 1) and docs links (#32). This PR only bumps the version and adds CHANGELOG.md.

npm version also fixed package-lock.json, whose workspace entries were stale (cli 0.3.1, mcp 0.1.0, recipes spec *).

Verification

  • npm run build|lint|test --workspaces: build ok, tsc --noEmit clean, tests 19 + 113 + 16 passed.
  • New MCP tests: default server lists 5 tools and refuses affitor_track_sale; with the flag, 7 tools and every tool annotated (sale/refund destructive, readiness/plan read-only); testMode sale goes to the test path and never the real trackSale; refund dry run calls nothing; lead sends test_mode; postTestSale wire body (snake_case, additional_data.test_mode, no undefined keys) and its error shape.
  • Mutation: registering the write tools unconditionally fails the listing test.
  • Built dist probed over stdio: server reports 0.2.1; 5 tools by default, 7 with AFFITOR_MCP_WRITE=1.

Follow-ups (not here)

One error envelope shared by API, CLI and MCP; parseAsync so a failed API call does not print a stack trace; answering tools/list without a key; --dry-run everywhere (see the CLI/MCP standards research).

🤖 Generated with Claude Code

sonpiaz and others added 3 commits October 12, 2026 15:52
…1 and cli 0.4.2

@affitor/mcp 0.2.1
- affitor_track_sale and affitor_track_refund create real sales and reverse
  commissions, and were offered to every agent that loaded the server. They
  are now registered only with AFFITOR_MCP_WRITE=1; by default the server
  offers 5 tools, none of which moves money.
- Every tool carries MCP annotations (readOnlyHint, destructiveHint,
  idempotentHint, openWorldHint); the two money tools are destructive.
- testMode: on track_sale it posts the sale with additional_data.test_mode
  (an is_test sale, no commission; the SDK has no field for it, so the call
  is made directly like the verification chain); on track_lead it sends a
  test lead; on track_refund it is a dry run that calls nothing, because the
  API has no test refunds.

affitor 0.4.2: version bump for the fixes on main since the 0.4.1 publish
(15/06), including the secrets-file permission fix (#26). CHANGELOG.md
added to both packages. npm version also corrected the stale workspace
versions in package-lock.json (it still said cli 0.3.1, mcp 0.1.0).

Nothing is published by this commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review r1 (codex): a test sale sent the real invoiceId as transaction_id, and
the API's duplicate check does not skip test rows, so the real sale with that
invoice would answer 409 and never create its commission. Test sales now use
test_<invoiceId>. Empty invoiceId is refused on sale and refund (the tools
declare idempotentHint). affitor_readiness is openWorldHint: the check fetches
the brand's site.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review r2 (codex) P2: the stubs threw when called, and runCall turns a throw
into isError, so the assertion passed even without the min(1) validation.
The tests now count trackSale, trackRefund and trackTestSale calls (with
and without testMode) and expect zero; dropping .min(1) fails 4 of them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@sonpiaz
sonpiaz merged commit ba97fd6 into main Oct 12, 2026
1 check passed
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