Repository navigation
Commit 3de5160
MCP: AI assistants can request crafts and set stock rules (#201)
* Move the craft, cancel and stock-rule checks out of the routes
The MCP endpoint coming next must check what the page's routes check,
so the logic moves into functions both can call:
- commands.request_cancel(): the busy-CPU and same-job checks. The job
identity helpers (output_identity, same_output) move with it from
tracking, which imports commands, not the other way round.
- commands.craft_request_error(): the craft request's input checks.
- stock.item_from(), set_alert(), set_target() and rules(): stock rule
validation, the craftable check and the rules listing.
- planner.rules_for_user(): the stock rules a plan warns about.
No change to what the routes accept or answer, except that a craft
request's amount can no longer be true (which counted as 1).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* MCP endpoint: AI assistants can read the base
/mcp is a Model Context Protocol endpoint, so Claude Code or another MCP
client can answer questions about the base. Eleven read-only tools:
item search, item details and history, inventory changes, current
crafts, a job's held-up steps, craft history and stats, the crafting
plan, stock rules and power.
- Hand-written JSON-RPC over Streamable HTTP (gcm/mcp/protocol.py): one
JSON answer per POST, no sessions. It serves both protocol eras: the
2026-07-28 stateless requests (version in _meta, mirrored headers
checked) and initialize-based 2025-03-26..2025-11-25 clients.
- Signed in with the user's personal access token as a bearer token
(auth.bearer_required), never a session cookie; another site's Origin
is refused.
- Tools take item keys from search_items, never names, and compact their
output for a model's context.
- docs: an AI assistants section in using.md, plus README, server.md,
how-it-works.md and CONTEXT.md. dev.py prints the MCP address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* MCP: sign in from claude.ai with OAuth
claude.ai's connectors only sign in with OAuth, so the server is now its
own authorization server for /mcp:
- /mcp's 401 points at the protected resource metadata (RFC 9728),
which names this server's authorization server metadata (RFC 8414).
- Clients register themselves (RFC 7591, public clients only, unused
ones dropped after a day, capped per hour).
- /oauth/authorize is a consent page: sign in with your access token,
see which app asks and where it sends you back, Allow or Cancel. Its
own CSP lets the form's redirect reach the app's callback.
- /oauth/token trades the code (PKCE S256 only) for an hour's access
token and a 30-day refresh token. Refresh tokens rotate; one used
twice revokes the grant.
- Loopback redirect URIs match on any port, for Claude Code.
- Manage users lists each user's connected apps with Disconnect.
Revoking the login token they consented with, New token or deleting
the user disconnects them too.
- docs: using.md (claude.ai and Claude Code setup), server.md
(PUBLIC_URL, proxy paths), CONTEXT.md.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* MCP: AI assistants can request crafts and set stock rules
Seven more tools, each running the page route's own code and role check:
- set_stock_alert / remove_stock_alert: your own low-stock alerts.
- set_stock_target / remove_stock_target (operators): keep-in-stock
targets.
- request_craft (operators): works out the crafting plan first and
doesn't queue while ingredients are missing unless called again with
force. No fixed amount cap: what's sensible depends on the item. It
echoes back the name, amount, unit and stock.
- cancel_craft (operators): takes the job_id current_crafts now gives
each busy CPU, so a CPU that moved on to another job isn't cancelled.
- request_status: whether a request or cancel went through.
The tools that change the game carry destructiveHint, and they and the
server's instructions tell the model to confirm with the user first.
Viewers aren't offered operators' tools. Names lose Minecraft's colour
codes. The consent page says what an operator's app can change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* MCP: review fixes for the endpoint and read tools
- A tool that raises anything but ToolError answers as a tool error
(and is logged) instead of a 500 the client can't read, and a KeyError
inside a tool no longer reads as "Unknown tool".
- Numbers in arguments must be finite: JSON's 1e400 is infinity to
Python, which int() turned into a 500.
- inventory_changes builds the snapshot's lookup once instead of
scanning it for every changed item.
- search_items ranks by the name without Minecraft's colour codes, and
tool output drops them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* OAuth: review fixes
- The consent page only takes POSTs from its own page (Origin and
Sec-Fetch-Site): another site could post a sign-in with its own token
and sign the visitor in as someone else (login CSRF).
- A refresh token used again within 30 s of its first use gets tokens
instead of revoking the grant: that's two requests refreshing at once
or a retry after a lost answer, not a copied token.
- Registrations are capped per address (30 an hour) as well as in all
(2000), so one script can't stop everyone else connecting.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Maselkov <25772111+Maselkov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>1 parent f870f19 commit 3de5160
11 files changed
Lines changed: 618 additions & 28 deletions
File tree
- docs
- server
- gcm
- mcp
- routes
- store
- tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
36 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
819 | 819 | | |
820 | 820 | | |
821 | 821 | | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
822 | 836 | | |
823 | 837 | | |
824 | 838 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
443 | 443 | | |
444 | 444 | | |
445 | 445 | | |
446 | | - | |
447 | | - | |
448 | | - | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
449 | 450 | | |
450 | 451 | | |
451 | | - | |
452 | | - | |
| 452 | + | |
| 453 | + | |
453 | 454 | | |
454 | 455 | | |
455 | 456 | | |
| |||
482 | 483 | | |
483 | 484 | | |
484 | 485 | | |
485 | | - | |
| 486 | + | |
486 | 487 | | |
487 | 488 | | |
488 | 489 | | |
| |||
498 | 499 | | |
499 | 500 | | |
500 | 501 | | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
501 | 524 | | |
502 | 525 | | |
503 | 526 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
50 | 52 | | |
51 | 53 | | |
52 | 54 | | |
| |||
148 | 150 | | |
149 | 151 | | |
150 | 152 | | |
151 | | - | |
| 153 | + | |
152 | 154 | | |
153 | | - | |
154 | | - | |
| 155 | + | |
155 | 156 | | |
156 | 157 | | |
157 | 158 | | |
| |||
0 commit comments