Ticket Queue MCP Server
by sanjay1110
README.md
# Ticket Queue MCP Server & Client
A production-style Model Context Protocol (MCP) solution built for the
"Build a Production MCP Server & Client" lab: a server that exposes an
internal support ticket queue as MCP tools, resources, and prompts, and a
client that discovers and invokes them, over Streamable HTTP with OAuth 2.1
authorization.
## What's here
```
server/ MCP server (FastMCP): tools, resources, prompts, OAuth AS+RS, error handling
data_store.py In-memory mock ticket DB + KB articles (stands in for a real ticketing system)
auth.py OAuth 2.1 Authorization Server configuration (scopes, DCR)
app.py The FastMCP server itself -- entry point
client/ MCP client
oauth_flow.py Scripted OAuth 2.1 + PKCE flow (headless-friendly demo client)
client_demo.py Connects, discovers, and invokes everything -- entry point
docs/
ARCHITECTURE.md Diagram + component/transport write-up
CAPABILITIES.md Full reference for every tool/resource/prompt
SECURITY.md Security design summary (Requirement #7)
demo/
run_demo.sh Starts the server, runs the client, captures output
demo_log.txt A captured successful run (discovery -> invocation -> elicitation -> errors)
```
## Quickstart
```bash
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
bash demo/run_demo.sh
```
This starts the server on `http://127.0.0.1:8000`, runs the client through
the full OAuth handshake, discovery, and invocation flow, and writes the
transcript to `demo/demo_log.txt`.
To run the pieces separately:
```bash
# terminal 1
python3 -m server.app
# terminal 2
python3 -m client.client_demo
```
## What the demo actually shows
`client/client_demo.py` runs, in order:
1. Two OAuth 2.1 + PKCE token acquisitions -- one client requesting only
`tickets:read`, one requesting `tickets:read tickets:write`.
2. Full discovery: `tools/list`, `resources/list`,
`resources/templates/list`, `prompts/list`.
3. A tool call (`search_tickets`, `get_ticket`), a resource read (a KB
article, the queue summary), and a prompt fetch (`triage_ticket`).
4. A write action (`add_comment`).
5. The high-impact `close_ticket` action, once with the elicitation
**confirmed** and once **declined**, showing both outcomes.
6. The read-only client attempting a write tool, demonstrating
least-privilege scope enforcement.
7. Both required error-handling failure modes: an invalid ticket ID, and a
simulated unreachable backing data source, both surfaced as clean,
non-leaky messages.
See `demo/demo_log.txt` for the full captured transcript, and
`docs/SECURITY.md` for the reasoning behind each of these design choices.
## Requirements coverage
| Lab requirement | Where |
|---|---|
| 1. >=3 tools | 5 tools in `server/app.py` |
| 2. >=2 resources | 3 resources in `server/app.py` |
| 3. >=1 reusable prompt | 2 prompts in `server/app.py` |
| 4. Client discovers & invokes | `client/client_demo.py`, Steps 1-8 |
| 5. Transport choice + justification | `docs/ARCHITECTURE.md` |
| 6. Client-side safety feature | Elicitation on `close_ticket`, `client/client_demo.py` Steps 8-9 |
| 7. Security design summary | `docs/SECURITY.md` |
| 8. Realistic error handling | `server/app.py` + `docs/CAPABILITIES.md` "Error Handling"; demo Steps 11-12 |
## Built with
[Model Context Protocol](https://modelcontextprotocol.io) /
[FastMCP](https://gofastmcp.com) (Python).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues