Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Quiz App MCP server

A Python MCP (Model Context Protocol) server built with FastMCP. Exposes tools to:

  • Claude Desktop, locally, over stdio
  • claude.ai, remotely, over HTTP (deployed on Render)

Optionally backed by a MySQL database via SQLAlchemy.

Project layout

.
├── server.py           # entry point — branches on RENDER env var (stdio vs HTTP)
├── config.py            # loads .env, exposes shared SQLAlchemy engine
├── tools/
│   ├── __init__.py
│   └── quiz.py           # tool definitions — register(mcp) adds them to a FastMCP instance
├── .env                  # secrets — never commit
├── .env.example
└── requirements.txt

Setup

git clone https://github.com/sathvik1607/Quiz_mcp_server.git
cd Quiz_mcp_server
python -m venv venv
.\venv\Scripts\pip install -r requirements.txt
copy .env.example .env
# fill in .env with real DB credentials (or remove the DB_* lines if unused)

Sanity-check the DB connection before wiring this into Claude Desktop:

.\venv\Scripts\python.exe -c "from config import engine; from sqlalchemy import text; print(engine.connect().execute(text('SELECT 1')).scalar())"

This should print 1. If it hangs or errors, fix .env/DB connectivity first — don't try to debug that through Claude Desktop.

Run locally (stdio)

.\venv\Scripts\python.exe server.py

Or use the MCP inspector to call tools manually (browser UI, no Claude Desktop needed — good for checking each tool's request/response in isolation). Requires Node/npm, since it launches via npx:

.\venv\Scripts\mcp.exe dev server.py

Use the mcp.exe entry point in venv\Scripts, not python -m mcp — the mcp package has no __main__ and that form fails.

Connect to Claude Desktop

Add to %APPDATA%\Claude\claude_desktop_config.json (merge into whatever's already there — don't overwrite the file):

{
  "mcpServers": {
    "quizapp": {
      "command": "C:\\path\\to\\project\\venv\\Scripts\\python.exe",
      "args": ["C:\\path\\to\\project\\server.py"]
    }
  }
}

Use absolute paths matching wherever you cloned the repo.

Fully quit and restart Claude Desktop — close it from the system tray, not just the window. It only reloads MCP config on a full restart.

Then verify it loaded: Settings → Connectorsquizapp should be listed under "Other tools" with 5 tools (Register user, Get question, Validate answer, Generate leaderboard, Review answers).

Playing the quiz

Start a new chat and be explicit — a vague prompt like "let's start the quiz" can get misrouted to an unrelated built-in "generate a quiz" flow instead of calling this server's tools. Instead say something like:

"Use the register_user tool to register me as <name> with unique_id <id>, then start the quiz."

From there the server's own instructions (in server.py) drive the rest of the flow — one question at a time, waiting for your answer before moving on.

Deploy to Render (HTTP, for claude.ai)

  1. Push to GitHub (.env is gitignored — never commit it).

  2. Create a Render Web Service connected to the repo.

  3. Set environment variables in the Render dashboard:

    Variable Value
    RENDER true
    DB_HOST your DB host
    DB_USER your DB user
    DB_PASSWORD your DB password
    DB_NAME your DB name
  4. Start command: python server.py

  5. In server.py, update BASE_URL under the RENDER branch to your actual Render URL.

  6. In claude.ai → Settings → Connectors, add: https://your-app.onrender.com/mcp

No auth is currently configured on the HTTP endpoint — anyone with the URL can call every tool, including DB-backed ones. This was an explicit choice to keep setup simple for now; revisit before exposing anything sensitive (see Security below).

Note

OAuth was removed from the HTTP endpoint for now — we're not using claude.ai against this server's DB/tools yet, so it wasn't worth the extra complexity. Add it back later if needed.

Keep-alive

Render's free tier sleeps after 15 minutes idle, which makes the first request after sleep slow (30–60s) or time out. Mitigations already in place:

  • A background thread in server.py pings /health every 10 minutes.
  • Add an external monitor (e.g. UptimeRobot) on https://your-app.onrender.com/health every 5 minutes — not on /mcp.

Adding a new tool

Open tools/quiz.py and add a function inside register(mcp):

@mcp.tool()
def my_new_tool(param1: str, param2: int) -> dict:
    """
    One-sentence description of what this tool does.
    The agent reads this docstring to decide when to call the tool.

    Args:
        param1: What this string parameter means.
        param2: What this integer parameter means.
    """
    result = do_something(param1, param2)
    return {"result": result}

No separate registration step — register(mcp) is called for both the stdio and HTTP instances.

Security

  • .env is gitignored — never commit it.
  • Tools never return raw SQL or expose the DB schema.
  • All queries use parameterized SQL (text("... WHERE id = :id"), not string interpolation).
  • Any user-supplied table/column name should be checked against an allowlist before use in SQL.
  • The Render HTTP endpoint has no authentication — treat it as public. Don't add tools that expose sensitive data or destructive DB operations until auth is added back.
  • Whoever holds the shared DB_* credentials is pointed at the same live database — there's no separate dev/staging instance. register_user and validate_answer write directly into it, so testing locally adds real rows next to real quiz data. Use a distinctive unique_id when testing, and don't reuse these credentials past what's needed.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages