MCP server and CLI for Grocy with workflow tools, planning helpers, and household automation surfaces
Project description
grocy-mcp
Python MCP server and CLI for Grocy.
grocy-mcp lets AI agents and terminal users work with Grocy through one shared codebase. It exposes stock, shopping lists, recipes, chores, batteries, equipment, calendar exports, file groups, print helpers, workflow preview/apply helpers, discovery tools, and generic entity management through:
- an MCP server for tools like Claude Desktop, Claude Code, and other MCP clients
- a
grocyCLI for direct command-line use
Choose your path
- Want to connect Grocy to Claude, ChatGPT, or another MCP client? Install
grocy-mcp, run the MCP server, and point your client at it. - Want to manage Grocy from the terminal? Install the package and use the
grocyCLI directly. - Want to build chat, OCR, or photo-driven flows? Normalize items outside this repo, then call the workflow preview/apply tools here.
If you only want the fastest possible first run, this is enough:
pip install grocy-mcp
export GROCY_URL="https://grocy.example.com"
export GROCY_API_KEY="your-api-key-here"
grocy stock overview
Why this project
Grocy already has a solid REST API, but most day-to-day interactions still require either:
- clicking through the Grocy UI
- writing one-off API scripts
- wiring ad hoc automations around numeric IDs
grocy-mcp packages those API capabilities into a cleaner operator experience:
- human-friendly names instead of IDs for common flows
- a reusable MCP surface for AI agents
- a mirrored CLI for shell workflows and scripting
- one shared implementation for both interfaces
Features
- 80+ MCP tools across stock, shopping, recipes, chores, locations, tasks, meal plans, batteries, equipment, calendar, files, print, discovery, workflow helpers, and system operations
- Full Typer CLI with grouped subcommands under
grocy - Global
--jsonmode for machine-readable output on the supported list/view/reporting commands - Top-level CLI config overrides via
--urland--api-key - Name-based resolution for products, recipes, chores, locations, batteries, and equipment
- Stable workflow-oriented JSON contracts for preview/apply flows driven by chat, OCR, or vision clients
- Batch preview/apply helpers for product matching, stock intake, and shopping-list reconciliation
- First-class catalog helpers for shopping metadata, quantity metadata, task categories, meal-plan sections, and price-history views
- First-class household helpers for batteries, equipment, calendar summaries, file groups, print actions, and discovery
- Streamable HTTP and stdio MCP transports
- Async client layer with retry handling for transient server errors
- Generic entity access for Grocy resources outside the dedicated commands
- Test suite built with
pytest,pytest-asyncio, andrespx
Current status
This project is in active development and the current published version is 0.2.0.
- Python:
3.11+ - Grocy:
v4.4.1+ - Packaging: PyPI package with
grocy-mcpandgrocyentry points
Installation
Install from PyPI:
pip install grocy-mcp
Or run without a permanent install:
uvx grocy-mcp --transport stdio
Quick start
1. Configure access to Grocy
Use whichever option fits your environment best.
Bash / zsh:
export GROCY_URL="https://grocy.example.com"
export GROCY_API_KEY="your-api-key-here"
PowerShell:
$env:GROCY_URL = "https://grocy.example.com"
$env:GROCY_API_KEY = "your-api-key-here"
Or create a config file:
[grocy]
url = "https://grocy.example.com"
api_key = "your-api-key-here"
Expected config path:
- Linux:
~/.config/grocy-mcp/config.toml - macOS:
~/Library/Application Support/grocy-mcp/config.toml - Windows: platform-specific
grocy-mcp/config.tomlconfig dir viaplatformdirs
2. Pick your path
If you want to use an MCP client such as Claude Desktop or Claude Code, start the server:
Local stdio clients:
grocy-mcp --transport stdio
HTTP transport:
grocy-mcp --transport streamable-http --host 0.0.0.0 --port 8000 --path /mcp
If you just want the CLI, run a command immediately:
grocy stock overview
grocy shopping view
grocy recipes list
grocy chores overdue
If you want structured output for scripts or LLM clients:
grocy --json stock overview
grocy --json workflow match-products-preview '[{"label":"whole milk","quantity":2}]'
MCP usage
Example Claude Desktop / Claude Code-style MCP configuration:
{
"mcpServers": {
"grocy": {
"command": "grocy-mcp",
"args": ["--transport", "stdio"],
"env": {
"GROCY_URL": "https://grocy.example.com",
"GROCY_API_KEY": "your-api-key-here"
}
}
}
}
The MCP server currently supports:
stdiostreamable-http- 80+ registered tools in the current implementation
Architecture split
grocy-mcp intentionally stays on the Grocy side of the boundary.
- This repo handles Grocy-aware matching, preview/apply flows, CLI commands, and MCP tools.
- Raw images, OCR payloads, and model-specific prompting stay outside this repo.
- ChatGPT, Claude, or another client should first turn receipts, photos, or chat into normalized JSON items, then call the workflow tools here.
That keeps the project easier to test, safer for mutations, and usable by any model or automation stack.
Stable workflow contracts
The workflow layer is designed for multi-step, confirmation-first flows.
Normalized input items are used for preview only:
{
"label": "whole milk",
"quantity": 2,
"unit_text": "cartons",
"barcode": "5000112637922",
"note": "organic"
}
Preview results return matched, ambiguous, or unmatched plus candidate Grocy products:
{
"input_index": 0,
"label": "whole milk",
"status": "matched",
"matched_product_id": 12,
"matched_product_name": "Whole Milk",
"candidates": [{"product_id": 12, "name": "Whole Milk"}],
"suggested_amount": 2,
"unit_text": "cartons"
}
Apply steps accept explicit IDs only:
{
"product_id": 12,
"amount": 2,
"note": "organic"
}
Matching policy for preview tools:
- exact barcode match
- exact normalized product-name match
- case-insensitive substring match
If a stage returns multiple plausible products, the result is ambiguous and should be confirmed before any apply step.
Agent workflow examples
These are practical multi-step workflows an AI agent can perform by chaining grocy-mcp tools together:
"What can I cook tonight?"
recipes_list_tool— see all available recipesrecipe_fulfillment_tool("Spaghetti Bolognese")— check if ingredients are in stock- If fulfillable:
recipe_consume_tool("Spaghetti Bolognese")— deduct ingredients - If not:
recipe_add_to_shopping_tool("Spaghetti Bolognese")— add missing items to shopping list
"Restock after a grocery run"
shopping_list_view_tool— see what was on the list- For each purchased item:
stock_add_tool("Milk", 2)— add to stock shopping_list_remove_tool(item_id)— clear purchased items from the list
"Weekly kitchen check"
stock_expiring_tool— find expiring or below-minimum productschores_overdue_tool— find overdue household choresshopping_list_add_missing_tool— auto-add understocked products to shopping list- For each overdue chore:
chore_execute_tool("Vacuum living room")— mark as done
"Add a new recipe from a description"
stock_search_tool("flour")— find product IDs for ingredientsrecipe_create_tool("Banana Bread", "Easy banana bread", '[{"product_id": 3, "amount": 2}, ...]')— create the reciperecipe_fulfillment_tool("Banana Bread")— check if you can make it right away
Workflow-oriented chat and vision examples
These flows use the workflow surface instead of asking an LLM to mutate Grocy directly.
Receipt text -> preview -> confirm -> apply
- External client extracts normalized items from a receipt:
[
{"label": "whole milk", "quantity": 2, "unit_text": "cartons"},
{"label": "bananas", "quantity": 6},
{"label": "oat milk", "quantity": 1}
]
- Call
workflow_match_products_preview_tool(...)or:
grocy --json workflow match-products-preview '[{"label":"whole milk","quantity":2},{"label":"bananas","quantity":6}]'
- Confirm any
ambiguousorunmatchedlines with the user. - Apply confirmed stock additions:
grocy --json workflow stock-intake-apply '[{"product_id":12,"amount":2},{"product_id":44,"amount":6}]'
- Preview shopping reconciliation:
grocy --json workflow shopping-reconcile-preview '[{"product_id":12,"amount":2},{"product_id":44,"amount":6}]'
- Apply only the explicit actions returned by the preview.
Grocery photo interpreted by an LLM -> preview -> confirm -> apply
- ChatGPT or Claude looks at a grocery-bag photo and produces normalized JSON items.
- Call
workflow_stock_intake_preview_tool(...). - Review the proposed product matches and quantities.
- Confirm explicit
product_idvalues. - Call
workflow_stock_intake_apply_tool(...).
Pantry photo -> read-only audit preview
- External model describes visible pantry items as normalized JSON.
- Call
workflow_match_products_preview_tool(...). - Use the preview as a read-only audit to compare what the model sees against Grocy product names.
- Do not apply anything until quantities and matches are confirmed.
Sample prompts for ChatGPT and Claude
Use prompts like these outside grocy-mcp to produce normalized items before calling MCP/CLI workflow commands:
Read this grocery receipt and return only JSON.
Return an array of objects with:
- label
- quantity
- unit_text
- barcode
- note
Do not guess Grocy product IDs.
If quantity is unclear, use 1.
Look at this grocery photo and list the likely purchased items as JSON only.
Use this schema for each item:
{"label":"string","quantity":number,"unit_text":"string|null","barcode":"string|null","note":"string|null"}
Do not include commentary.
Do not invent product IDs.
Look at this pantry photo and return the visible products as JSON only.
Keep the output read-only and approximate if needed, but do not invent Grocy IDs.
Use the same normalized item schema as above.
CLI usage
Top-level command groups:
grocy stock ...
grocy shopping ...
grocy recipes ...
grocy chores ...
grocy locations ...
grocy tasks ...
grocy meal-plan ...
grocy catalog ...
grocy batteries ...
grocy equipment ...
grocy calendar ...
grocy files ...
grocy print ...
grocy discover ...
grocy workflow ...
grocy system ...
grocy entity ...
Use grocy --help or grocy <group> --help to explore the full surface. The examples below focus on the highest-value day-to-day commands.
Example commands
# Stock and shopping
grocy stock overview
grocy stock info Milk
grocy stock add Milk 2
grocy shopping view --list-id 1
grocy shopping add "Oat Milk" --amount 2 --list-id 2 --note "for breakfast"
# Recipes and chores
grocy recipes list
grocy recipes details "Spaghetti Bolognese"
grocy recipes add-to-shopping "Spaghetti Bolognese"
grocy chores overdue
grocy chores execute "Vacuum living room"
# Workflow preview/apply
grocy --json workflow match-products-preview '[{"label":"whole milk","quantity":2}]'
grocy --json workflow stock-intake-preview '[{"label":"whole milk","quantity":2}]'
grocy --json workflow stock-intake-apply '[{"product_id":12,"amount":2}]'
grocy --json workflow shopping-reconcile-preview '[{"product_id":12,"amount":2}]'
# Catalog, planning, and discovery
grocy --json catalog list shopping-lists
grocy --json batteries list
grocy --json meal-plan summary --from 2026-04-01 --to 2026-04-07
grocy --json calendar summary --from 2026-04-01 --to 2026-04-07
grocy --json discover search products milk
Project structure
src/grocy_mcp/
client.py async HTTP client for the Grocy REST API
config.py environment/config loading
exceptions.py typed error hierarchy
models.py pydantic models
workflow_models.py stable workflow JSON contracts
core/ shared business logic for MCP and CLI
core/batteries.py battery views and charge-cycle actions
core/calendar.py combined planning summaries and iCal helpers
core/equipment.py equipment views with linked battery context
core/files.py file-group download/upload/delete and print helpers
core/reference_data.py first-class metadata/discovery helpers
core/workflows.py preview/apply workflow helpers
mcp/server.py FastMCP entry point
cli/app.py Typer CLI entry point
tests/
unit tests for client, core modules, MCP entry point, and CLI
Development
Clone and install for local development:
git clone https://github.com/moustafattia/grocy-mcp
cd grocy-mcp
pip install -e ".[dev]"
Run checks:
pytest -v
ruff check src/ tests/
ruff format --check src/ tests/
Run a specific test:
pytest tests/test_stock.py -v
pytest tests/test_stock.py::test_stock_overview -v
Troubleshooting
"Grocy URL not configured"
Set GROCY_URL via environment variable, config file, or --url flag. The URL
should be the base URL of your Grocy instance (e.g. https://grocy.example.com),
not the API endpoint.
"Auth failed (401)"
Your API key is invalid or expired. Generate a new one in Grocy under
Settings → Manage API keys. Pass it via GROCY_API_KEY, config file, or --api-key.
"Connection failed" or timeouts Check that the Grocy URL is reachable from the machine running grocy-mcp. Common causes: wrong port, firewall rules, Grocy behind a reverse proxy without proper forwarding.
"No products found matching '...'"
The name resolver uses case-insensitive substring matching. Check grocy stock search
to see available product names. You can also pass numeric IDs directly.
"Multiple products match '...'" Be more specific with the name, or use the numeric ID shown in the error message.
MCP server not connecting in Claude Desktop
Make sure the command in your MCP config points to the grocy-mcp executable
and that GROCY_URL and GROCY_API_KEY are set in the env block. Check
Claude Desktop logs for error details.
Documentation
Contributing
See CONTRIBUTING.md for setup instructions, code style, and guidelines.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file grocy_mcp-0.2.0.tar.gz.
File metadata
- Download URL: grocy_mcp-0.2.0.tar.gz
- Upload date:
- Size: 99.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66fed7123b8015c17adf3df5bf0223157f799d1dc1772bbfb8c2138d0bb212b8
|
|
| MD5 |
1aa6393921de3424449b7688095b17c5
|
|
| BLAKE2b-256 |
cd4ed9893bec08840605d2c6b8ef90b90c9b3c82edcce7f8b6a5d42a8dd12cf8
|
Provenance
The following attestation bundles were made for grocy_mcp-0.2.0.tar.gz:
Publisher:
release.yml on moustafattia/grocy-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grocy_mcp-0.2.0.tar.gz -
Subject digest:
66fed7123b8015c17adf3df5bf0223157f799d1dc1772bbfb8c2138d0bb212b8 - Sigstore transparency entry: 1205253042
- Sigstore integration time:
-
Permalink:
moustafattia/grocy-mcp@085945f3057b667d4aee6c009af7a76cbb7d020c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/moustafattia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@085945f3057b667d4aee6c009af7a76cbb7d020c -
Trigger Event:
release
-
Statement type:
File details
Details for the file grocy_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: grocy_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 56.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ac73a6c99720adc62b2e6f3e9738c5b283c3300a8b2ef60ab5600fa994a0429c
|
|
| MD5 |
70f404f83d42f6744cebeb2686f9afc5
|
|
| BLAKE2b-256 |
9549497a1247a94059b9d66de76acc7fc0a900030c695a80c5933be21e596929
|
Provenance
The following attestation bundles were made for grocy_mcp-0.2.0-py3-none-any.whl:
Publisher:
release.yml on moustafattia/grocy-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
grocy_mcp-0.2.0-py3-none-any.whl -
Subject digest:
ac73a6c99720adc62b2e6f3e9738c5b283c3300a8b2ef60ab5600fa994a0429c - Sigstore transparency entry: 1205253046
- Sigstore integration time:
-
Permalink:
moustafattia/grocy-mcp@085945f3057b667d4aee6c009af7a76cbb7d020c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/moustafattia
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@085945f3057b667d4aee6c009af7a76cbb7d020c -
Trigger Event:
release
-
Statement type: