kt-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kt-mcpLog that I ate scrambled eggs and toast for breakfast"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
kt-mcp
🇨🇿 Česky · 🇬🇧 English
Self-hosted MCP server, který propojí AI agenta s vaším jídelníčkem na kaloricketabulky.cz.
Řeknete „snědl jsem 3 vejce a banán" — agent prohledá českou databázi potravin, vybere správnou porci a zapíše záznamy do vašeho skutečného jídelníčku. Oficiální aplikace zůstává zdrojem pravdy, takže prémiové funkce fungují dál.
Postaveno a otestováno s Claudem (desktop, mobil i web přes custom connector), ale server mluví standardním MCP přes HTTPS s OAuth 2.1, takže se může připojit jakýkoli agent, který podporuje vzdálené MCP servery.
Neoficiální projekt, bez vazby na Dine4Fit
kaloricketabulky.cz provozuje společnost Dine4Fit, a.s., která s tímto projektem nemá nic společného a nijak ho neschvaluje. Veřejné API neexistuje; zde použité endpointy byly vyčteny z frontendového JavaScriptu samotného webu a mohou se kdykoli bez varování změnit nebo rozbít.
Podmínky Dine4Fit udělují osobní, nekomerční licenci. Tento software je zveřejněn proto, abyste si mohli zautomatizovat přístup ke svému vlastnímu účtu — což licence dovoluje. Provozovat ho jako placenou nebo víceuživatelskou službu, případně dál šířit potravinová data, která vrací, je jiná věc a jde na váš vrub. Databáze patří Dine4Fit a je chráněna evropskými databázovými právy.
Držte frekvenci požadavků na lidské úrovni. Nestavte na tom konkurenčního klienta.
Related MCP server: Nutrition MCP
Co s tím jde dělat
Jakmile je agent připojený, přestane být zapisování jídel otravným proklikáváním vyhledávání. Pár vzorů, které v praxi fungují dobře:
Zapisujte mluvením. „K snídani jsem měl rohlík se šunkou a dvě vejce." Agent vyhledá potraviny, zvolí přirozené porce (kus (55 g) místo odhadovaných gramů) a zapíše každou položku do správného denního jídla.
Zautomatizujte rutinu. Pijete každý den dvě kávy s mlékem — proč je vypisovat? Pokud váš agent umí naplánované úlohy (Claude umí), řekněte mu to jednou: „Každý den v 9:00 mi zapiš do jídelníčku dvě espressa s mlékem." Denní konstanty se zapisují samy.
Vyfoťte talíř. Pošlete agentovi fotku oběda a zeptejte se, co na ní je. Rozpozná potraviny, odhadne reálné gramáže z obrázku, spočítá kalorie — a po potvrzení zaloguje. Odhad je odhad, ale u míchaných talířů je to lepší než nezapsat nic.
Vyfoťte recept. Vyfoťte recept z kuchařky nebo screenshot z webu a řekněte „ulož mi to jako jídlo". Agent přečte suroviny, každou najde v databázi a vytvoří uložený recept — příště zalogujete jedním záznamem. Cestou můžete upravovat: „vyměň smetanu za bílý jogurt a dej poloviční cukr."
Ptejte se, jak vám jde den. „Kolik kalorií mi dnes zbývá?" přečte denní součty přímo z jídelníčku.
Nástroje
Nástroj | Účel |
| Najde potraviny podle českého názvu nebo 13místného EAN kódu. Vrací id potraviny, které potřebují ostatní nástroje. |
| Vypíše přirozené porce potraviny ( |
| Kalorie a makra pro dané množství, přepočítané samotným webem. Pouze čtení. |
| Zapíše záznam o jídle do jídelníčku. |
| Přečte denní součty. |
| Uloží recept složený z existujících potravin. |
| Vypíše uložené recepty s jejich id a celkovou energií. |
| Zaloguje celý uložený recept jako jeden záznam. |
| Smaže uložený recept. |
Recepty
Web říká uloženému receptu jídlo (meal). create_meal ho složí
z existujících potravin, takže „3 vejce a 200 ml mléka" je jedna znovupoužitelná
položka místo dvou záznamů vypisovaných pokaždé znovu.
Množství se řídí stejným pravidlem jako log_food: amount počítá jednotky,
ne gramy. Vynecháte-li unit_id, použije se základní jednotka potraviny — gramy
u pevných potravin, mililitry u tekutin — tedy to, v čem se recepty běžně píší.
Když předáte unit_id z get_food_portions, počet ho násobí: 2 × porce (250 ml) je 500 ml. Splést se je snadné: jeden raný test zadal 100 jednotek
100 ml a potichu vytvořil recept s deseti litry mléka.
Jak to funguje
kaloricketabulky.cz je Spring MVC aplikace, kde každá routa odpoví i v JSON, když přidáte ?format=json — vrací obálku {code, data, message}. Žádné oficiální ani dokumentované API neexistuje; endpointy byly zrekonstruovány z frontendového JavaScriptu webu. Úplná mapa je v src/kt/client.ts.
Agent ──OAuth 2.1──► kt-mcp ──JSESSIONID──► kaloricketabulky.cz
──MCP/HTTPS─►Dvě hesla, každé hlídá něco jiného:
Tajemství | Hlídá |
| Kdo smí tento server připojit k agentovi. Zadáváte ho jednou v prohlížeči při OAuth souhlasu. |
| Účet na kaloricketabulky.cz, do kterého nástroje zapisují. Nikdy neopouští server. |
Co se stane při připojení
Žádný token ručně nevytváříte ani nekopírujete — OAuth to udělá za vás:
Do prostředí serveru (
.env) vložíte svůj login na kaloricketabulky.cz (KT_EMAIL/KT_PASSWORD) a přístupovou frázi, kterou si vymyslíte (MCP_AUTH_PASSWORD). Přihlašovací údaje ke kalorickým tabulkám zůstávají na vašem serveru; agent je nikdy nevidí.V agentovi přidáte URL konektoru,
https://<your-host>/mcp. Agent se u vašeho serveru zaregistruje sám (dynamická registrace klientů).Otevře se stránka v prohlížeči — obrazovka souhlasu vašeho serveru. Jednou zadáte
MCP_AUTH_PASSWORD.Váš server vygeneruje unikátní náhodný přístupový token a předá ho agentovi, který si ho uloží a automaticky obnovuje. Od té chvíle je každé volání nástroje ověřené tímto tokenem.
Protože si každý provozuje vlastní instanci, každý token patří jen jemu: váš server zná jen váš jídelníček a tokeny vydává jen tomu, kdo zná vaši frázi. Mezi instalacemi se nesdílí nic a žádná centrální služba neexistuje.
Lokální vývoj
npm install
cp .env.example .env # doplňte své údaje
npm run build
npm test
set -a; source .env; set +a
PUBLIC_URL=https://localhost:8092 node dist/index.jsGET /healthz vrací výsledný veřejný MCP endpoint — nejrychlejší způsob, jak ověřit, že PUBLIC_URL je opravdu to, co si myslíte.
Vlastní hosting
⚠️ Server by měl běžet nepřetržitě — na uspávaném PC selžou naplánované zápisy. Podrobnosti a doporučení v HOSTING.md.
Referenční nasazení používá Docker, nginx a Cloudflare Tunnel zdarma — na hostiteli ani routeru se neotvírá žádný příchozí port. Funguje ale cokoli jiného, co před kontejner postaví HTTPS hostname; tunel je jen nejlevnější bezpečná výchozí volba.
Cesta požadavku:
Cloudflare → cloudflared (host network) → 127.0.0.1:80 → nginx → kt-mcp:8092nginx poslouchá jen na loopbacku hostitele a cloudflared se připojuje ven.
Konfigurace nginx (deploy/nginx.conf.template) vypíná proxy buffering — bez
toho by Server-Sent Events čekaly na konec streamu a volání nástrojů by se
zasekávala.
1. Vytvořte tunel (jednou), v Cloudflare Zero Trust dashboardu → Networks → Tunnels:
Vytvořte tunel, zkopírujte tunnel token.
Přidejte public hostname se službou
HTTP→localhost:80.cloudflaredze stacku běží v host network módu, takželocalhost:80je nginx publikovaný na loopbacku hostitele. Obyčejnéhttp, protože TLS ukončuje tunel.
Zvolený hostname je dále označován <your-host>; funguje jakákoli doména na
vašem Cloudflare účtu a nic v kódu na ni není vázané.
2. Sestavte image, z tohoto adresáře:
docker compose build3. Nasaďte stack. deploy/stack.yml je runtime compose soubor (funguje samostatně i jako Portainer stack); nastavte tyto proměnné prostředí:
Proměnná | Hodnota |
| Váš login na kaloricketabulky.cz |
|
|
| Dlouhá přístupová fráze, kterou si zvolíte (min. 12 znaků) |
|
|
| Z kroku 1 |
Udržujte docker-compose.yml a deploy/stack.yml v souladu — první sestavuje image, druhý ho spouští.
4. Ověřte nasazení, než ho připojíte k agentovi:
./scripts/verify-deployment.sh https://<your-host>5. Připojte agenta. V Claudovi: Settings → Connectors → Add custom connector → zadejte https://<your-host>/mcp. Agent se sám zaregistruje, otevře stránku souhlasu a vy jednou zadáte MCP_AUTH_PASSWORD. Ostatní MCP klienti mají vlastní postup „přidat vzdálený MCP server" se stejnou URL.
Pozdější změna domény
Hostname není zapečený v image — shodovat se musí jen PUBLIC_URL a public
hostname tunelu. Přesun:
Přesměrujte public hostname tunelu na novou doménu (nebo vytvořte nový tunel a vyměňte
TUNNEL_TOKEN).Aktualizujte
PUBLIC_URLna stacku a znovu nasaďte.Znovu spusťte ověřovací skript, pak v agentovi konektor odeberte a přidejte znovu.
Krok 3 je nutný: PUBLIC_URL je OAuth issuer a identifikátor zdroje podle
RFC 8707, takže tokeny vydané pod starým hostname jsou po přesunu správně
odmítnuty.
Zaseklí, nebo nemáte kde hostovat?
Pokud při vlastním hostování narazíte, založte GitHub issue — rád pomůžu, od toho issue tracker je.
Vlastní hosting potřebuje stroj, který běží nepřetržitě (viz HOSTING.md), a účet u Cloudflare. Pokud nemáte kde server provozovat, ozvěte se na kt-mcp@stanwhy.me a něco vymyslíme — jen počítejte s tím, že provoz privátní instance znamená reálné náklady na server, které by šly za vámi.
Autentizace
Server je sám sobě OAuth 2.1 autorizačním serverem a implementuje, co MCP specifikace od chráněného zdroje vyžaduje:
/.well-known/oauth-protected-resource/mcp— RFC 9728 discovery/.well-known/oauth-authorization-server— RFC 8414 discovery/authorize,/token,/register,/revoke— authorization code + PKCE, dynamická registrace klientů, rotace refresh tokenů
Přístupové tokeny žijí 30 dní a persistují se do /data na volume, takže redeploy nevynutí nové připojení konektoru.
Co chrání přístupová fráze
MCP_AUTH_PASSWORD je jediná cesta k získání tokenu. Každý požadavek na /mcp
vyžaduje platný bearer token a tokeny vydává výhradně formulář souhlasu po
porovnání s frází v konstantním čase. Ověřeno auditem
(scripts/security-audit.sh): neautentizovaná volání i volání s padělaným
tokenem jsou odmítnuta, vymyšlené autorizační kódy a refresh tokeny jsou
odmítnuty, žádný veřejný endpoint nevydává credential a žádná variace metody či
cesty se k nástrojům bez tokenu nedostane.
Dvě věci jsou veřejné záměrně a bezpečně: OAuth discovery dokumenty (vyžaduje je specifikace) a dynamická registrace klientů. Registrace klienta útočníkovi nic nedá — token bez fráze stále nezíská.
Hrubou sílu omezuje limit 100 požadavků za 15 minut na /authorize. Limiter
klíčuje podle IP klienta, proto nginx přepisuje X-Forwarded-For ověřenou
hlavičkou CF-Connecting-IP od Cloudflare a aplikace věří přesně jednomu proxy
hopu. Připojování k hlavičce od klienta — nebo trust proxy: true — by útočníkovi
dovolilo vyrobit si nový bucket pro každý požadavek a limit by přestal existovat.
Zbytková rizika, o kterých je dobré vědět: kdokoli s frází má plný přístup;
jednotlivé tokeny nelze odvolat jinak než smazáním /data/oauth-state.json;
a protože registrace klientů je otevřená, phishingový odkaz na stránku souhlasu
by mohl frázi zachytit, kdybyste ji tam zadali — před autorizací zkontrolujte
jméno klienta zobrazené ve formuláři.
Omezení
Nedokumentovaný upstream. Dine4Fit tu nic negarantuje; refactoring frontendu může bez varování změnit tvary odpovědí. Klient při čemkoli nečekaném vyhodí chybu místo hádání, takže se rozbití projeví hlasitou chybou, ne špatným počtem kalorií.
md5(hesla)je ekvivalent hesla. Web hashuje heslo na klientovi, hash je tedy stejně citlivý jako heslo samotné. Podle toho sKT_PASSWORDzacházejte.Jeden účet na instanci. Server se přihlašuje k jedinému účtu kaloricketabulky.cz. Dva lidé, dva kontejnery.
Osobní použití. Automatizace zápisů do vlastního účtu je mnohem měkčí pozice než hromadný scraping, ale pořád je mimo cokoli, co Dine4Fit posvětil. Držte frekvenci požadavků na lidské úrovni a nestavte na tom konkurenčního klienta.
Čtení jednotlivých záznamů dne je nejméně ověřený endpoint;
get_day_summaryposílá odpověď webu beze změny dál, protože její tvar není plně zdokumentovaný.Část porce receptu zalogovat nejde. Formulář pro přidání jídla sice nabízí
countproti pseudo-jednotkám porce, procenta a gramy, ale server ho ignoruje a zaloguje vždy celý recept — měřeno na receptu o 249 kcal přidalo 0,5 porce i polovina váhy plných 249.log_mealproto nemá argumentportions; když snědená byla jen část receptu, zalogujte suroviny jednotlivě přeslog_food.
Licence
MIT. Databáze potravin a služba kaloricketabulky.cz patří Dine4Fit, a.s. — tato licence pokrývá pouze kód v tomto repozitáři.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceMCP server integrating Foodvisor nutrition API for food search, meal logging, daily summaries, and progress tracking via LLM agents like Claude.MIT
- Alicense-qualityBmaintenanceA filesystem-based MCP server that turns any MCP-capable AI agent into a conversational calorie and protein tracker with natural-language estimates, confidence-aware logging, daily/weekly progress, food-history search, and export, working offline with local fallback data.196MIT
- Alicense-qualityDmaintenanceA Model Context Protocol (MCP) server that connects AI assistants to your MyFitnessPal data, enabling reading food diaries, nutrition goals, weight measurements, and more via MFP's web scraping.MIT
- Flicense-qualityCmaintenanceRemote MCP server for natural-language calorie/macro and weight tracking, designed to connect to Claude.ai as a custom connector.
Related MCP Connectors
Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/stany9g/kt-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server