storelink-mcp
MCP server exposing the StoreLink grocery stocking API as tools for category buyer workflows, including inventory checks and replenishment orders.
README
StoreLink MCP Server
Python MCP server that exposes the hypothetical StoreLink grocery stocking API as agent tools over stdio.
StoreLink is used by a European grocer with locations across Europe, primarily in Czechia (also Slovakia and Austria in the mock data).
Tools
Built for a category buyer workflow: check on-hand vs last-24h POS, apply the delta rule, then replenish.
| Tool | Description |
|---|---|
list_stores |
List stores |
get_store |
Store details |
get_on_hand_vs_pos |
Primary check: on-hand + POS + delta + product/case_pack |
create_replenishment |
Raise a replenishment order |
get_replenishment |
Order status |
get_on_hand_vs_pos defaults the POS window to the last 24 hours when since is omitted. It returns delta = units_sold − available and a product block (case_pack, lead_time_days, etc.).
Buyer rule: if delta >= 6, call create_replenishment (prefer multiples of product.case_pack).
Butter test scenario
| Field | Value |
|---|---|
| SKU | 8847291 — Madeta butter 250g |
| Store 47 | Praha Budějovická — available 4, ~12 sold / 24h → delta 8 → replenish |
| Store 102 | Brno Vaňkovka — available 18, ~5 sold / 24h → delta −13 → do not replenish |
Setup
Requires Python 3.10+.
# From the project root
uv sync
Or with pip:
pip install -e .
Configuration
| Variable | Default | Description |
|---|---|---|
STORELINK_MODE |
mock |
mock = in-process fixtures; http = call the real API |
STORELINK_BASE_URL |
https://storelink.com |
Base URL used in http mode |
STORELINK_API_KEY |
(unset) | Optional Bearer for non-store endpoints |
KORRAL_GCP_PROJECT |
(required in http) | GCP project where Korral stores weekly-rotated store keys |
KORRAL_SECRET_PREFIX |
korral-store- |
Secret id = {prefix}{store_id} (e.g. korral-store-47) |
STORELINK_AUDIT_LOG |
logs/storelink-audit.ndjson |
NDJSON audit log file path |
STORELINK_THREAD_ID |
(session id) | Optional agent/thread id for correlating a chat |
STORELINK_BUYER_LOG |
logs/buyer-activity.ndjson |
Category-buyer activity (JSON lines) |
STORELINK_BUYER_MD |
logs/buyer-activity.md |
Category-buyer activity (readable markdown) |
Every tool requires a reason string (why the agent is calling it). That value is written into the audit trail as ground-truth rationale.
Korral per-store API keys
Korral IT rotates a per-store API key weekly in GCP Secret Manager. Store-scoped StoreLink calls send:
X-Korral-Store-Key: <key>
Secret naming: projects/{KORRAL_GCP_PROJECT}/secrets/{KORRAL_SECRET_PREFIX}{store_id}/versions/latest
Example for store 47: korral-store-47.
Auth behavior:
- Before any store-scoped request, the key is loaded (cached in memory).
- If the secret does not exist, the tool fails immediately with a clear message for the agent (no HTTP call):
No Korral API key configured for store … Ask Korral IT to provision the weekly-rotated key. - If StoreLink returns 401 (key rotated in flight), the cache is invalidated, the latest secret is fetched, and the request is retried once.
Store-scoped tools/endpoints: get_store, inventory/POS inside get_on_hand_vs_pos, create_replenishment, get_replenishment.
list_stores / SKU-supplier lookups do not require a store key.
Use Application Default Credentials (GOOGLE_APPLICATION_CREDENTIALS or workload identity) so the MCP process can read Secret Manager.
Audit logging
All audit events are standardized JSON (one object per line / NDJSON), written to stderr and appended to STORELINK_AUDIT_LOG.
Common envelope:
{
"schema_version": "1.0",
"event_type": "tool_call_started",
"timestamp": "2026-08-01T17:00:00.123Z",
"session_id": "…",
"interaction_id": "…",
"thread_id": "…",
"service": "storelink-mcp",
"level": "info",
"payload": {
"tool": "get_on_hand_vs_pos",
"arguments": { "store_id": "47", "sku": "8847291", "reason": "…" },
"reason": "Check store 47 butter sell-through before replenish decision"
}
}
event_type |
When |
|---|---|
session_started / session_ended |
Process lifetime |
tool_call_started |
Tool invoked |
tool_call_succeeded |
Tool returned (includes duration_ms, result_summary) |
tool_call_failed |
Tool error (includes error, and traceback for unexpected failures) |
interaction_id is unique per tool invocation and shared across that call’s started/succeeded/failed events.
Category buyer activity feed
Alongside the engineer audit log, every agent action is also written in plain language for category buyers:
- Why the agent acted (from the required
reasonargument) - What happened (stock checked, order placed, etc.)
- Outcome (e.g. replenishment recommended when delta ≥ 6)
Files:
logs/buyer-activity.md— human-readable timelinelogs/buyer-activity.ndjson— same entries as structured JSON
MCP resource (not a tool — does not clutter the buyer agent loop):
buyer://activity— current-session feed in markdown
Example markdown entry:
### 2026-08-01T17:22:49Z — Checked on-hand vs recent sales for Madeta butter 250g at store 47
**Status:** Needs attention
**Why the agent did this:** Check butter delta at store 47 before replenish decision
**What happened:** In the last 24 hours, about 12 units sold; 4 units are still available on the shelf (gap/delta: 8).
**Outcome:** Sales are outpacing stock (delta 8 ≥ 6). A replenishment order is recommended.
Mock mode includes Czech/EU stores (plus scenario stores 47 and 102), metric SKUs including 8847291, inventory, POS history (CZK/EUR), and Central European suppliers.
Run
uv run storelink-mcp
# or
uv run python -m storelink_mcp.server
Cursor / Claude Desktop config
Add to your MCP settings (e.g. Cursor mcp.json):
{
"mcpServers": {
"storelink": {
"command": "/Users/aleccritser/.local/bin/storelink-mcp-cursor",
"env": {
"STORELINK_MODE": "mock"
}
}
}
}
Important: the project path contains a space (Duvo Task). Cursor splits the command field on spaces, so pointing command at .venv/bin/storelink-mcp under that folder fails with spawn /Users/aleccritser/Duvo ENOENT. Use the no-space launcher at ~/.local/bin/storelink-mcp-cursor (created by the project setup), or uv with the directory passed as a separate arg:
{
"mcpServers": {
"storelink": {
"command": "/Users/aleccritser/.local/bin/uv",
"args": ["run", "--directory", "/Users/aleccritser/Duvo Task", "storelink-mcp"],
"env": {
"STORELINK_MODE": "mock"
}
}
}
}
For live HTTP against a StoreLink deployment:
{
"mcpServers": {
"storelink": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/Duvo Task", "storelink-mcp"],
"env": {
"STORELINK_MODE": "http",
"STORELINK_BASE_URL": "https://storelink.com",
"STORELINK_API_KEY": "your-api-key"
}
}
}
}
Example agent flow
get_on_hand_vs_pos("47", "8847291", reason="…")→ readdeltaandproduct.case_pack- If
delta >= 6→create_replenishment(..., reason="delta>=6 …") - Optionally check store
102(delta should stay below 6 — no order) get_replenishment(..., reason="…")→ poll status
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.