Skip to main content
Glama

mcp-apps-lab

One FastMCP app server (Python) โ€” a single MCP server that hosts four interactive Prefab apps (quiz, weather, news, English Duo) plus MCP resources and prompts. Each app tool returns a Prefab UI (buttons, cards, tabs, progress) instead of raw JSON; any MCP host renders them, and the LLM sees a text summary.

Apps

App

UI tool

Backend tool

What it demonstrates

Quiz

take_quiz

submit_answer

Multi-turn state: the LLM generates questions, the user answers via buttons, each click grades through a backend tool, the final score is sent back to the conversation

Weather

weather_app

get_weather

Live forecast from the Open-Meteo API: free-text location input geocodes ANY city name (no fixed table โ€” โ€œbekasiโ€ works), shows current conditions with the city's local time (๐Ÿ• 20:31 WIB), region/country, and a 5-day forecast; unknown names fall back to Jakarta, sample data offline (LIVE/SAMPEL badge); lookups go through the host's tools/call proxy (hashed tool names โ€” the proxy never sees the mapping)

News Curator

news_curator

get_feed

Live RSS feeds (Bloomberg Markets, CNBC, The Guardian Business, BBC Business) fetched through the backend tool on tab click / refresh โ€” parsed with the stdlib, sample-data fallback when offline (LIVE/SAMPLE badge); compiles a markdown briefing and sends it back to the conversation

English Duo

duo_english, duo_flashcards

grade_answer, get_profile, add_word

A Duolingo-style English learning app: CEFR-graded vocabulary (A1-B2), FSRS-6 spaced-repetition cards per word, and game mechanics โ€” XP + combo bonus, 5 hearts (mistakes cost one, daily refill), daily streak ๐Ÿ”ฅ, and a Bronzeโ†’Diamond level ladder. Due reviews + new words drive each lesson; answers are graded by the backend tool which reschedules the word's card and updates the profile in SQLite. duo_english cycles five exercise types (MC, fill, typing, sentence builder, flashcards); duo_flashcards is a pure flip-card review session (Again/Hard/Good/Easy โ†’ FSRS) with no quiz questions

Also exposed server-side: live resources (news://{source}/feed, news://{source}/briefing, weather://{city}/current, duo://profile, duo://due, duo://words/{level}, duo://guide/{level}, duo://levels) and prompts (morning-briefing, daily-english).

Related MCP server: MCP + CrewAI Agentic Integration

Layout

src/mcp_apps_lab/
โ”œโ”€โ”€ server.py          # the ONE FastMCP server โ€” wires apps, tools, resources, prompts
โ”œโ”€โ”€ apps/              # the FastMCPApp UIs (LLM-facing entry points)
โ”‚   โ”œโ”€โ”€ quiz.py        #   take_quiz UI
โ”‚   โ”œโ”€โ”€ weather.py     #   weather_app UI
โ”‚   โ”œโ”€โ”€ news.py        #   news_curator UI
โ”‚   โ””โ”€โ”€ duo.py         #   duo_english UI (English Duo)
โ”œโ”€โ”€ tools/             # backend tool functions the UIs call via the tool proxy
โ”‚   โ”œโ”€โ”€ quiz.py        #   submit_answer
โ”‚   โ”œโ”€โ”€ weather.py     #   get_weather
โ”‚   โ”œโ”€โ”€ news.py        #   get_feed (live RSS fetch + offline fallback)
โ”‚   โ””โ”€โ”€ duo.py         #   grade_answer, get_profile, add_word
โ”œโ”€โ”€ duo/               # the English Duo engine
โ”‚   โ”œโ”€โ”€ store.py       #   SQLite persistence (~/.mcp-apps-lab/duo.db)
โ”‚   โ”œโ”€โ”€ scheduler.py   #   FSRS-6 spaced-repetition wrapper
โ”‚   โ”œโ”€โ”€ game.py        #   XP/combo, hearts, streak, level ladder
โ”‚   โ””โ”€โ”€ engine.py      #   lesson building + grading orchestration
โ”œโ”€โ”€ resources/         # MCP resources (news://, weather://, duo://profile, duo://due)
โ”œโ”€โ”€ prompts/           # MCP prompt templates (morning-briefing, daily-english)
โ””โ”€โ”€ data/              # feed definitions, offline fallback data, word bank

Setup

uv sync          # installs the package (editable) + fastmcp[apps] + dev tools

Configuring which tools are enabled

config.json at the repo root decides which UI apps (tools) the server advertises to the LLM. Disabled apps are not registered at all โ€” their backend tools stay hidden too.

{
  "tools": {
    "take_quiz": false,
    "weather_app": false,
    "news_curator": true,
    "duo_english": true
  }
}
  • Keys: take_quiz, weather_app, news_curator, duo_english.

  • Missing keys default to enabled; unknown keys are ignored.

  • Lookup order: MCP_APPS_LAB_CONFIG env var โ†’ ./config.json โ†’ ~/.mcp-apps-lab/config.json.

  • The checked-in config currently runs with quiz and weather disabled (English Duo + News Curator active); flip the booleans to re-enable.

Running

Plain streamable-HTTP server

uv run python -m mcp_apps_lab   # streamable HTTP at http://127.0.0.1:8090/mcp
                                # (MCP_APPS_LAB_PORT to override)

Browser dev UI (fastmcp dev apps)

uv run fastmcp dev apps src/mcp_apps_lab/server.py --mcp-port 8090
  • MCP server: http://127.0.0.1:8090/mcp (auto-reload on save)

  • Dev UI: http://localhost:8080 โ€” pick take_quiz, weather_app, news_curator, or duo_english, fill in arguments, and play the rendered app in a new tab

  • The left inspector panel shows the JSON-RPC traffic (including the hashed backend-tool calls the UIs make)

English Duo details

State lives in a SQLite database (~/.mcp-apps-lab/duo.db, override with DUO_DB_PATH):

  • AI-generated content โ€” the coach generates fresh, CEFR-appropriate vocabulary itself (personalized to the user's level/interests) and passes it via the words argument of duo_english / duo_flashcards; sessions built this way show an โœจ AI-GENERATED badge. Every generated word is saved to the bank with its own FSRS card, so it comes back in later review sessions. The built-in 120-word bank remains the fallback (and the source for due-review-only sessions).

  • Duolingo brand UI โ€” Nunito typeface, Duolingo palette (green #58CC02, blue #1CB0F6, yellow #FFC800, red #FF4B4B), rounded cards, 3D-press buttons, and green/red feedback banners โ€” distinct from the generic quiz UI.

  • Spaced repetition โ€” one FSRS-6 card per word (fsrs package, the algorithm modern Anki uses). Correct โ†’ Good, wrong โ†’ Again; due reviews are served first in every lesson, new words fill the rest. An explicit level (e.g. duo_flashcards(level="b1")) is honored strictly: only that level's due reviews and new words are served, never other levels. The masthead shows the active level.

  • Game mechanics โ€” 10 XP per correct answer + combo bonus (capped), โค๏ธ 5 hearts (a mistake costs one; refill daily), ๐Ÿ”ฅ streak (once per day per completed lesson), levels 1-10 with Bronzeโ†’Diamond leagues.

  • Exercise types โ€” five, cycling through each lesson so it never feels like one quiz:

    • mc โ€” โ€œWhat does X mean?โ€ multiple choice

    • fill โ€” pick the word that fits a sentence blank

    • type โ€” TYPE the missing word (no choices at all)

    • order โ€” build the sentence by tapping scrambled word tiles (with a clear/undo button)

    • flip โ€” flashcard: flip the card, then self-rate Again / Hard / Good / Easy โ€” mapped straight onto the FSRS ratings, so reviews get a real difficulty signal and XP (0/8/10/12) instead of just right/wrong

    • For a pure flashcards session (no quiz questions), the duo_flashcards UI serves flip cards only โ€” flip to reveal the definition, self-rate, and the FSRS schedule updates per card

  • Resources/prompts โ€” duo://profile and duo://due give the assistant live stats. The AI-generation reference resources: duo://guide/{level} (the per-level generation prompt โ€” learner profile, word scope, definition/example rules, output format), duo://words/{level} (existing words at a level, to match style and avoid duplicates), and duo://levels (overview + word counts). The daily-english prompt wires everything into a daily routine.

Wiring into the ai-backend-lab agent

One server, one entry โ€” the agent sees all three UI tools plus the resources and prompt:

{
  "mcp-apps-lab": {
    "url": "http://127.0.0.1:8090/mcp",
    "transport": "streamable_http"
  }
}

Then ask the agent something like "give me a quiz about Python", "show me the weather in Tokyo", "curate today's financial news", or "let's do my daily English practice" โ€” it calls the UI tool, and the agent's reply streams a structured tool event the frontend renders as the interactive app.

How it's structured

# server.py โ€” one server, apps filtered by config.json, plus resources & prompts
mcp = build_server()   # providers = apps enabled in config.json
register_resources(mcp)   # news://{source}/feed, weather://{city}/current, duo://profile, ...
register_prompts(mcp)     # morning-briefing, daily-english

# apps/weather.py โ€” the UI app owns its backend tool
app = FastMCPApp("Weather")
app.add_tool(get_weather)          # from mcp_apps_lab.tools โ€” hashed to this app

@app.ui()                          # LLM-facing entry point โ€” returns a PrefabApp
def weather_app(city: str) -> PrefabApp: ...
  • @app.ui() tools are the only ones advertised to the LLM; their result is a Prefab UI the host renders (the model sees a text summary).

  • Backend tools (tools/) are plain functions registered with app.add_tool(...): the renderer calls them over the MCP server under a hashed name (<sha256(app+tool)>_<tool>), so the UI can grade, look up, or compile without the LLM being in the loop โ€” and the tool proxy never sees the mapping.

  • providers=[...] lets one server host several apps; resources and prompts are registered server-side and shared.

Adding to the lab

  1. App: create apps/<name>.py (a FastMCPApp with an @app.ui() entry point), register its backend tool(s) from tools/, and add the app to providers=[...] in server.py.

  2. Backend tool: add a plain function to tools/<name>.py; register it with app.add_tool(...) in the owning app.

  3. Resource / prompt: add a register(mcp) function in resources/<name>.py / prompts/<name>.py and call it from the corresponding register_* in server.py.

  4. Keep it lint-clean and tested: uv run ruff check . and uv run pytest (smoke tests live in tests/test_server.py).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    FastMCP is a comprehensive MCP server allowing secure and standardized data and functionality exposure to LLM applications, offering resources, tools, and prompt management for efficient LLM interactions.
    3
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A FastMCP-based server providing tools for weather queries, random number generation, and real-time stock market data retrieval. It enables AI models to interact with external data and perform specific tasks through the Model Context Protocol.
    -