
Intro
Dneska dodělávám redesign webu a portuju data z dřív nahardkóděných sekcí, jako jsou případový studie, členové týmu, nebo kariéra, do updated CMS SaaS systému, který to umožňuje všechno ovládat z admin konzole. To je naše vlastní tvorba taková, pěkně serverless, představím jindy.
Většinou to docela odsejpalo, protože toho nebylo hodně, ale teď jsem se dostal ke kariérní sekci. Měl jsem před sebou 16 pracovních nabídek, které jsem potřeboval přetáhnout do CMSka. Vyplnit formulář. Opiš název, opiš popis, nastav lokalitu, nastav typ úvazku... krát šestnáct. Na to jsem neměl :)
A v tu chvíli mě napadlo - ty jo, to SaaSko naše je přece API-first, tak nechám nějakýho agenta, ať to tam naposílá přes curl. Ale musel by na to buď napsat nějaký skript, nebo trefit dlouhý Bearer token copy paste, a ani jedno se mi moc nelíbilo.
Tak rovnou uděláme na CMS MCPčko, ne? :) No a když už dělám MCP, tak ať je použitelný pro ostatní. Takže žádný lokální stdio server s hardcoded heslem, ale komplet HTTPS server s OAuth 2.0, dynamickými oprávněními a serverless deploymentem na AWS Lambda. Tady je příběh o tom, jak jsme se tam dostali – a počítání chyb, které nám na cestě zkomplikovaly den.
Co je to vlastně MCP?
MCP (Model Context Protocol) je otevřený standard od Anthropic, který "umožňuje" AI modelům komunikovat s externími systémy. Že jo, LLMko vám chroupe text a vždycky vrátí nějaký text; nemá oči, ruce, nebo možnost si proklikávat webové stránky. MCP je jen předem domluvený trýček, který převádí to, co by pro člověka byly senzorické vstupy do textové podoby, aby to mohlo LLM zpracovat, a naopak text, který LLM vrátí, převedl do akcí, které je potřeba udělat. A "MCP" není jediný způsob, jak to udělat, ale je to uznávaný standard, takže když všichni mluví jazykem MCP kmene, tak všichni rozumí všem a svět je krásný.
Jednoduše řečeno: MCP je způsob, jak říct Gemini nebo Claudovi tady máš nástroje – a on s nimi v rámci konverzace skutečně pracuje.
Architektura je přímočará. Na jedné straně stojí MCP server (program, který nabízí nástroje a data), na druhé straně MCP klient (Claude.ai, Cursor, VS Code...), který tyto nástroje volá. Každý nástroj je popsaný JSON schématem: co přijímá, co vrací, jestli data jen čte nebo mění. Klient si před konverzací stáhne seznam nástrojů a pak je autonomně volá podle toho, co mu uživatel říká.
Lokální server: skvělý proof of concept, ale nestačí
Nejrychlejší způsob, jak MCP vyzkoušet, je spustit si ho lokálně. Nastavíte v Claudu cestu k Node nebo Python skriptu, ten se spustí jako podproces přes standardní vstup výstup, a hotovo – Claude má přístup k nástrojům. Funguje to skvěle na vývojářském stroji.
Problém nastane, jakmile chcete něco skutečného.
- Lokální server běží jen na vašem počítači – jiní uživatelé k němu nemají přístup.
- Přihlašování funguje přes hardcoded heslo přímo v konfiguráku. To se nedá škálovat ani zabezpečit.
- Každý nový uživatel by potřeboval přístup k vašemu stroji. To ne.
Byl jasný cíl: HTTPS MCP server. Takový, ke kterému se kdokoliv s oprávněním přihlásí přes standardní OAuth 2.0 a dostane přesně ty nástroje, ke kterým má přístup – a nic víc.
AWS Lambda: proč serverless dává pro MCP perfektní smysl

Jasně, mohl bych postavit klasický server s Dockerem, nginxem a celým cirkusem. Ale proč?
MCP server je ze své podstaty stateless. Každý požadavek od LLMka je samostatný: vypiš mi články, vytvoř nový článek, smaž obrázek. Žádné trvalé spojení (stačí ukázat klíč, že jo, fakt mám právo si číst tady články), žádný stav mezi požadavky. To je přesně to, pro co jsou Lambda funkce na AWSku stvořené.
Výhody jsou stejné jako u každého serverless řešení:
- Platíte jen za reálné použití. Claude zavolá nástroj, Lambda se spustí, vrátí výsledek a zase se vypne. Žádný server, který platí za sebe 24/7, i když ho nikdo nepoužívá.
- Škáluje automaticky. Jeden uživatel nebo tisíc – funguje to stejně bez jediné změny v kódu.
- Žádná údržba. Žádné patche, servisní okna ani pondělní telefonáty.
Byl tu ale jeden technický zádrh. FastMCP (Python knihovna pro MCP servery, která za nás dělá 90% práce při jejich stavbě) interně potřebuje asyncio task group, která musí být inicializovaná před zpracováním požadavků. Lambda ale nespouští trvalou ASGI aplikaci – každé volání je izolované.
Řešením byl Mangum. To je ASGI adaptér pro Lambdu. S nastavením lifespan='auto' při každém volání Mangum spustí startup celé ASGI aplikace (včetně inicializace task group), obslouží požadavek a všechno uklidí. Pro stateless MCP server ideální chování. A protože celý server umíme stavět programaticky za běhu – podle toho, kdo se přihlásil – každá Lambda invokace dostane přesně tu sadu nástrojů, která danému uživateli náleží. Někdo třeba smí jen upravovat články, někdo zase zpracovávat případové studie a spravovat partnery :-) Umíme.
OAuth 2.0: přihlášení po vzoru profesionálů
Aby se ke cloudovému MCP serveru mohl přihlásit Claude, Gemini, nebo Cursor, potřebujeme standardní OAuth 2.0 Authorization Code flow s PKCE. Je to stejný princip, jako když se přihlásíte přes Google nebo GitHub – klient vás přesměruje na přihlašovací stránku, vy se přihlásíte, dostanete token, a s ním pak komunikujete.
V praxi to vypadá takto:
- Claude.ai přesměruje uživatele na
/authorizeendpoint naší API. - Ten ho přesměruje na přihlašovací stránku AWS Cognito.
- Uživatel se přihlásí, Cognito vystaví autorizační kód.
- Claude.ai si za kód vymění přístupový token.
- Při každém volání MCP serveru pošle token v
Authorizationhlavičce (to je to ukázání klíče). - Lambda authorizer token ověří a přidá k requestu informaci o oprávněních uživatele.
Díky poslednímu bodu AI pomocník každého uživatele vidí jen ty nástroje, ke kterým má přiřazená oprávnění. Uživatel s přístupem jen k článkům nevidí nástroje pro správu partnerů nebo pracovních pozic. To je fakt nutný - model nesmí vidět tooly, které nemá právo volat, protože to víte, že je zkusí zavolat, a bude smutnej, že mu to nefunguje, a bude to zkoušet klidně třicetkrát po sobě, a než se vrátíte z coffee breaku, tak zjistíte, že vám stihl propálit tokeny na týden dopředu.
Co to znamená pro klienty?

Tohle jsou hezké technické detaily, ale v čem je to zajímavé pro byznys?
Vezměme si konkrétní příklad. Klient má web s CMS – blog. Dříve to vypadalo tak, že obsah buď spravoval sám přes admin rozhraní, nebo nám posílal texty e-mailem a my je vkládali za něj. Uf.
Teď klientovi přidáme NTIT Console jako konektor do jeho Clauda. A klient mu napíše:
Potřebuji článek o nové kolekci, tady jsou klíčové body, tady jsou fotky. Chtělo by to ještě obecný vizuál, ale ten já nemám, tak najdi něco vhodného na internetu. Publikuj ho jako draft a připrav mi návrh i v angličtině.
Claude článek napíše, uloží do draftu, a klient si ho schválí. Žádné kopírování, žádné přepínání aplikací.
Nebo: Vypiš mi všechny nepublikované články a pro každý mi řekni, co by mu chybělo k dokončení.
Nebo: Přidej na web tuhle pracovní pozici a nastav popis podle přiloženého PDF.
Tohle není futurismus. Tohle je produkce.
Závěr
Myslím, že MCP bude za pár let vypadat jako REST API dnes – samozřejmost, o které nepřemýšlíme. Dnes to ještě vypadá jako cool integrace pro tech nadšence. Brzy to bude standardní způsob, jak AI přistupuje k systémům firem.
Cesta z lokálního stdio MCP na HTTPS server s OAuth, dynamickými oprávněními a serverless deploymentem nebyla přímočará. Nejzajímavějšími zastávkami byly 307 redirect z ASGI routeru, 502 z neinicializované task group a ladění Cognito Managed Login pro každého nového OAuth klienta. Ale výsledek je elegantní: jeden Python balíček v Lambda funkci, žádné servery, žádná složitá správa.
A ten moment, kdy Claude poprvé sám zavolal create_article a na webu se mi objevil hotový draft k revizi? Nebo koukat, jak tam těch šestnáct něco jobů postupně naskakuje? Yep, všechno se to vyplatilo, spánek je pro slabochy :)