ica-mcp

ica-mcp

Enables AI agents to read and edit ICA shopping lists in natural language, using an unofficial interface to ICA's private API.

Category
访问服务器

README

ica-mcp

An MCP server for ICA — Sweden's largest grocery chain — that lets AI agents (Claude, or any Model Context Protocol client) read and edit your ICA shopping lists in natural language:

"What's on my shopping list?" · "Add coffee and bananas to the Willys list" · "Check off milk" · "Clear the checked items"

ICA has no official public API. This server talks to the same private backend the ICA mobile app uses, authenticating with your personnummer + password (no BankID required for accounts that support password login).

⚠️ Unofficial & unaffiliated. This project is not affiliated with, endorsed by, or supported by ICA. It relies on a private, undocumented API that can change or break at any time, and using it may be against ICA's terms of service. Use at your own risk, for personal use only.

Tools

Tool What it does
list_shopping_lists All your lists + how many items remain/checked
view_shopping_list Contents of a list (by name; defaults to your primary list)
add_items Add one or more free-text items to a list
check_off / uncheck Mark an item bought / undo
remove_item Remove an item entirely
clear_checked Remove all checked items (tidy up after shopping)
create_shopping_list / delete_shopping_list Create / delete a list
list_saved_recipes / get_recipe Your favourite recipes; one recipe's ingredients + steps
random_recipes Random recipes for inspiration
add_recipe_to_shopping_list Add a recipe's ingredients to a list as free-text items
list_stores / get_offers Your favourite stores; current offers for a store
get_bonus Your ICA bonus / Stammis balance

Lists, items and stores are referenced by name, so an agent can act on natural language. Omitting a list/store name targets your primary one (the Handla list / your first favourite store).

Requirements

  • Python 3.10+
  • A Swedish egress IP. ICA's API gateway (apimgw-pub.ica.se) returns HTTP 451 to non-Swedish IPs. Run this on a machine/network in Sweden — a US/DE VPS will not work.
  • An ICA account that logs in with personnummer + password (accounts locked to BankID-only are not supported).

Setup

Everything is one ica-mcp command with four subcommands:

Command What it does
ica-mcp login Log in once (personnummer + password) and cache the session
ica-mcp register Register the server with Claude Code (--scope user)
ica-mcp status Show the cache location + whether the session is valid (no login)
ica-mcp serve Run the MCP server over stdio — what your client launches

1. Install

The quickest path uses uv — one command, identical on Windows, macOS and Linux:

# (only if you don't have uv yet)
#   Windows:      winget install --id=astral-sh.uv -e
#   macOS/Linux:  curl -LsSf https://astral.sh/uv/install.sh | sh

uv tool install git+https://github.com/kanylbullen/ica-mcp
uv tool update-shell      # puts `ica-mcp` on PATH — then open a NEW terminal

<details> <summary>Fallback without uv (plain pip + venv)</summary>

git clone https://github.com/kanylbullen/ica-mcp.git
cd ica-mcp
python3 -m venv .venv
.venv\Scripts\pip install .      # Windows
.venv/bin/pip install .          # macOS / Linux

Then use the venv's ica-mcp in place of the bare command below: .venv\Scripts\ica-mcp.exe (Windows) or .venv/bin/ica-mcp (macOS/Linux). </details>

2. Log in (once)

ica-mcp login          # prompts for personnummer + password (hidden)

On success it prints your name and lists and caches the session (OAuth client + tokens) in a per-user state dir — %LOCALAPPDATA%\ica-mcp (Windows), ~/.local/state/ica-mcp (Linux), ~/Library/Application Support/ica-mcp (macOS). The short-lived access token (~15 min) is auto-refreshed via the long-lived refresh token, so you normally log in only once. Verify anytime:

ica-mcp status         # cache path + session validity, without logging in

3. Register with your MCP client

Claude Code — let the CLI do it (writes at user scope, resolving the right path):

ica-mcp register

Registering at --scope user sidesteps a Windows drive-letter project-key quirk. If the claude CLI isn't found, register prints a ready-to-paste mcp.json. The equivalent manual command is:

claude mcp add ica --scope user -- ica-mcp serve

Any other MCP client (mcp.json):

{
  "mcpServers": {
    "ica": {
      "command": "ica-mcp",
      "args": ["serve"]
    }
  }
}

If ica-mcp isn't on PATH, use the absolute path uv printed at install, or python -m ica_mcp serve.

Restart your MCP client and the tools appear. The server reads the cached session, so it needs no credentials in its environment. If the refresh token ever expires, re-run ica-mcp login — or set ICA_USER / ICA_PASS (see .env.example) so serve can re-authenticate unattended. Relocate the cache with ICA_STATE_FILE.

How authentication works

ICA migrated (around 2024) from a simple Basic-auth API to an OAuth 2.0 / OIDC flow backed by a Curity Identity Server at ims.icagruppen.se, with the data API behind an F5 gateway at apimgw-pub.ica.se. The flow is:

  1. bootstrap client-credentials token (scope=dcr)
  2. dynamic client registration (POST /register) → per-install client
  3. PKCE authorize → HTML login form
  4. POST /authn/authenticate/IcaCustomers with personnummer + password
  5. exchange the resulting code for a Bearer access/refresh token

The auth flow is a standalone port of the excellent LazyTarget/ha-ica-todo Home Assistant integration — full credit for reverse-engineering the current flow. The hardcoded DCR bootstrap client id/secret are ICA app constants (also public in that project), not user secrets.

Security & privacy

  • Tokens are cached in a per-user state dir (see Log in), outside the repo, chmod 0600 on POSIX. On Windows that only toggles the read-only bit, so the file is not OS-ACL-protected there — treat the machine account as the trust boundary. Set ICA_STATE_FILE to relocate the cache.
  • No keyring dependency by design. The Swedish-egress requirement pushes many users onto headless homelab/VPS boxes that lack a Secret Service / Credential Manager; a portable 0600 file is the deliberate choice.
  • Nothing is logged to stdout (stdout is reserved for the MCP protocol — logs go to stderr).
  • This server can modify your real ICA account (add/remove items, delete lists). Write operations were validated against throwaway lists during development.

Roadmap

Done: shopping lists (phase 1), recipes + offers + bonus (phase 2, including the composite "add a recipe's ingredients to my shopping list").

Planned next, on the same auth:

  • Recipe search by phrase (the search endpoint shape isn't nailed down yet)
  • Product / EAN lookup (productservice/v1/product/{ean})
  • Personal offers across stores

Credits

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选