{"id":"86c23086-7eb3-473f-acea-1940091349c6","slug":"flexi","kind":"mcp","name":"flexi","summary":"Open-source back-office and AI system for Shoptet e-shops: Shoptet API client, Postgres mirror, stuck order alerts, product feeds and an MCP server for Claude. Built by Flexity.","owner":"flexity-git","repoUrl":"https://github.com/flexity-git/flexi","license":"Apache-2.0","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-10-11T07:22:27.000Z","addedAt":"2026-10-21T05:17:57.928Z","logoUrl":"https://avatars.githubusercontent.com/u/173707969?u=f0fff961cfda0a67689326c6863ae7cf7abbf044&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["databases","developer-tools","cloud-infra"],"tags":["ai-agents","back-office","claude","claude-code","ecommerce","google-merchant","heureka","postgres"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-27T00:53:30.107Z","sample":false,"url":"https://conduits.dev/tools/flexi","language":"TypeScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# flexi\n\n**Open-source back-office and AI system for Shoptet e-shops.**\n\nflexi connects your Shoptet stores to Postgres, Slack and Claude. It mirrors orders and\nproducts, tells you when an order is stuck, builds product feeds, and gives Claude safe,\nscoped access to your shop data through an MCP server.\n\nIt was extracted from the internal system that runs [Flexity](https://www.flexity.sk/): five\nShoptet stores, about 4,500 product variants and more than 14,000 orders a year, operated by a\ncore team of four. Read the [case study](docs/case-study.md).\n\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)\n![Node 20+](https://img.shields.io/badge/node-%3E%3D20.19-339933)\n![Status: v0.1](https://img.shields.io/badge/status-v0.1-orange)\n\n[Česky](README.cs.md) · [Case study](docs/case-study.md) · [Architecture](docs/ARCHITECTURE.md) ·\n[Skills](skills/README.md) · [Contributing](CONTRIBUTING.md)\n\n---\n\n## What works today\n\n| Part | What it does |\n|---|---|\n| [`@flexity/shoptet`](packages/shoptet) | Shoptet Private API client. Stays within Shoptet's limits (3 concurrent requests per token, waits on 429), retries safely, and never stops paging silently. |\n| [`@flexity/mcp`](packages/mcp) | MCP server for Claude Code and Claude Desktop. Live Shoptet tools, read-only SQL over your mirror, per-person tokens with scopes, audit log, preview-then-confirm writes. |\n| [`mirror`](modules/mirror) | Copies orders, items, customers, products, variants, categories and statuses of all your stores into Postgres. Compares stores against your primary store. |\n| [`stuck-orders`](modules/stuck-orders) | Slack alert when an order sits in a status longer than your rule allows, counted in business hours. Checks the mirror is fresh first, so it does not cry wolf. |\n| [`merchant-feed`](modules/merchant-feed) | Google Merchant, Heureka and Zboží.cz feeds from the mirror, with validation, rules and a circuit breaker that keeps the old file when the item count suddenly drops. |\n| [Skills](skills) | 8 Claude Code skills with what we learned running Shoptet stores: API pitfalls, stuck order triage, feed checks, multi-store consistency, storefront HTML traps. |\n\nEverything above has tests (400+), runs on Node 20 and Postgres (tested on 17), and needs nothing but\nyour own Shoptet Private API token. There is no hosted service and no account to create.\n\n## Two-minute start: connect Claude to your store\n\nYou need Node 20.19+, a Shoptet store with Private API access (Shoptet admin, Connections,\nPrivate API) and Claude Code.\n\n```sh\ngit clone https://github.com/flexity-git/flexi.git && cd flexi && npm install\n\nclaude mcp add flexi \\\n  --env FLEXI_STORES=main \\\n  --env SHOPTET_TOKEN_MAIN=<your token> \\\n  -- \"$PWD/node_modules/.bin/tsx\" \"$PWD/packages/mcp/src/bin.ts\"\n```\n\nThen ask Claude something like *\"Which orders came in today?\"* or *\"Show me product\nPB-25 with its stock and availability.\"* These live tools only read. Personal data of\ncustomers stays hidden unless you grant the `data:read:customers` scope.\n\n## Full setup: mirror, alerts and feeds\n\n```sh\ncp .env.example .env        # stores, tokens, FLEXI_DATABASE_URL, Slack webhooks\nset -a; . ./.env; set +a\n\nnpm run flexi -- doctor     # checks config, database and modules; never prints tokens\nnpm run flexi -- migrate    # creates the tables\nnpm run flexi -- run mirror:sync-statuses\nnpm run flexi -- run mirror:sync-products\nnpm run flexi -- run mirror:sync-orders --since=2026-01-01T00:00:00+0100\nnpm run flexi -- run stuck-orders:check --dry-run\nnpm run flexi -- run merchant-feed:generate --feed=google --store=main --out=./feeds/google.xml\n```\n\nflexi does not ship a scheduler. Run the tasks from cron, systemd timers, Coolify scheduled\ntasks or GitHub Actions. The [`flexi-setup`](skills/flexi-setup/SKILL.md) skill has examples\nfor each, and Claude can walk you through it.\n\nflexi reads `FLEXI_DATABASE_URL`, never `DATABASE_URL`. Developer shells often export\n`DATABASE_URL` for other projects, and flexi must not connect to one of those by accident.\n\n## How it fits together\n\n```\n Shoptet stores ──API──▶ mirror ──▶ Postgres ──▶ stuck-orders ──▶ Slack\n   (your tokens)                       │     └──▶ merchant-feed ──▶ feed files\n                                       ▼\n            Claude ◀──MCP── flexi-mcp (scopes, SQL guard, audit log)\n```\n\nEach capability is a module: a folder with SQL migrations, tasks you can run, and a list of\ntables it exposes to the MCP server with the scope needed to read them. Adding a carrier, a\nbank, a feed format or an alert means adding a module, not changing the core. See\n[ARCHITECTURE.md](docs/ARCHITECTURE.md).\n\n## Security\n\nflexi holds your API tokens and, with the mirror, your customers' data. The defaults are\nstrict:\n\n- The MCP SQL tool accepts one `SELECT` over allowlisted tables, with an allowlist of plain\n  functions, inside a read-only transaction. The guard walks the whole query and rejects\n  anything it does not recognise.\n- The database is the real boundary: `flexi-mcp db-roles` generates read-only login roles\n  that can see only the allowlisted tables, and a separate one for customer data. HTTP mode\n  refuses to start without them.\n- Database errors are never passed to the caller, only a reference into the audit log.\n- Every MCP tool call is written to the audit log, including rejected ones, with e-mails and\n  tokens masked.\n- HTTP mode needs a bearer token per person. Tokens are stored only as hashes and can be\n  revoked.\n- Write tools are off by default. When enabled, a change is previewed first and applied only\n  with a short-lived confirm token, then read back to verify.\n- Module code is loaded only from the project flexi is installed in.\n\nFound a problem? Please report it privately, see [SECURITY.md](SECURITY.md).\n\n## Roadmap\n\nThese exist in Flexity's internal system and are candidates for extraction. They are not in\nflexi yet.\n\n- Availability rules and a restock date widget for the storefront\n- Supplier availability import and purchase order suggestions from sales velocity\n- Bank statement pairing (Fio, Barion) with paid status written back to Shoptet\n- Shoptet invoices and credit notes\n- More feeds (Árukereső, Compari, Ceneje) and comparison site category mapping\n- Order status history, for exact time in status\n- npm packages, so flexi can be installed without cloning\n\nIf you need one of these, open an issue. If you want to build one, even better.\n\n## Contributing\n\nThe easiest contribution is a skill: one markdown file with something you learned running a\nShoptet store. Modules, fixes and translations are welcome too. Start with\n[CONTRIBUTING.md](CONTRIBUTING.md).\n\nflexi is maintained by a small team that also runs a business. Reviews can take a few days,\nand small focused pull requests get merged fastest.\n\n## Built by\n\nflexi is built by [Tomáš Sokol](https://www.linkedin.com/in/sokoltomas/), founder of\n[Flexity](https://www.flexity.sk/), a Bratislava-based pilates and wellness company. Flexity\nsells pilates and wellness equipment through its own Shoptet stores in Slovakia, Czechia,\nHungary, Croatia and Romania, and runs reformer and barre studios in Bratislava and Poprad.\n\nTomáš is not a full-time developer. He built Flexity's internal system with Claude Code as\nhis main coding partner, and talks about it at Reshoper 2026 in Prague:\n*\"Čtyři lidé, práce za čtrnáct: Jak nám AI pomohla postavit vlastní systém\"*.\n\nIf flexi saves you time, a star helps other Shoptet merchants find it. If you write about it,\nsee [CITATION.cff](CITATION.cff).\n\n## License\n\nApache-2.0. See [LICENSE](LICENSE) and [NOTICE](NOTICE).\n\n\"Shoptet\" is a trademark of its owner. flexi is an independent project and is not affiliated\nwith or endorsed by Shoptet.\n"}