LeaveManager
by DhanyaHegdek
README.md
# MCP Server Setup Guide (Windows) — Leave Management Example
This README documents the full process of building a local MCP (Model Context
Protocol) server in Python with `uv`, testing it with MCP Inspector, and
connecting it to Claude Desktop on Windows — including the gotchas that come
up along the way.
## 1. Project Setup
```powershell
cd Desktop\MCP
mkdir my-mcp-server
cd my-mcp-server
uv init .
uv add "mcp[cli]"
```
> **Gotcha:** Installing `mcp[cli]` with plain `pip install mcp[cli]` puts it
> in your **global** Python site-packages — NOT in the project's own `uv`
> virtual environment. `uv run` only sees packages installed via `uv add` (or
> `uv pip install`) inside the project. If you see:
>
> ```
> Error: typer is required. Install with 'pip install mcp[cli]'
> ```
>
> even after installing it, this is almost always the cause. Fix: run
> `uv add "mcp[cli]"` from inside the project folder.
## 2. Example `main.py`
Build your server using `FastMCP` from the `mcp` package: create an `mcp =
FastMCP("YourServerName")` instance, define functions decorated with
`@mcp.tool()` for actions the AI can call (each with a clear docstring
describing what it does — Claude uses this to decide when to call it), and
optionally `@mcp.resource("scheme://{param}")` for read-only data resources.
End the file with:
```python
if __name__ == "__main__":
mcp.run()
```
For this walkthrough, the example server was a simple in-memory
"LeaveManager" with three tools (`get_leave_balance`, `apply_leave`,
`get_leave_history`) and one resource (`greeting://{name}`).
`stdout` is reserved for the JSON-RPC protocol — any stray print() corrupts
the stream and causes cryptic JSON parse errors downstream. Use `logging`
configured to `stderr` if you need debug output.
## 3. Test with MCP Inspector (recommended before touching Claude Desktop)
MCP Inspector is a browser-based tool for calling your tools directly —
no AI, no Claude Desktop needed. Great for confirming your server actually
works before wiring it into anything else.
```powershell
uv run mcp dev main.py
```
This opens a local page (usually `http://localhost:6274`). Click **Connect**,
then go to the **Tools** tab → **List Tools** → pick a tool → fill params →
run it and check the output.
> If Connect spams `SyntaxError: Unexpected token ... is not valid JSON`
> in the History/Notifications panel, it usually means the underlying
> command errored out in plain text (e.g. the same "typer is required"
> issue above) instead of returning JSON. Read the actual error text hiding
> in the syntax error message — it tells you what broke.
## 4. Connecting to Claude Desktop
### 4a. If Claude Desktop isn't installed yet
Download from https://claude.ai/download, install, and launch it at least
once (finish sign-in) before doing anything else.
### 4b. Finding the right config file
This is the step that varies the most and caused the most confusion:
- **Standard installs** usually use:
`%APPDATA%\Claude\claude_desktop_config.json`
(i.e. `C:\Users\<you>\AppData\Roaming\Claude\claude_desktop_config.json`)
- **Packaged/Store (MSIX) installs** — recognizable by a path containing
`AppData\Local\Packages\Claude_<random-id>\...` — use a _virtualized_
config location instead, e.g.:
`...\Local\Packages\Claude_<id>\LocalCache\Roaming\Claude\claude_desktop_config.json`
Windows silently redirects the app's "AppData\Roaming\Claude" reads/writes
to this Packages folder, so editing the plain `%APPDATA%\Claude` copy does
nothing for this install type.
- **Easiest way to find the right one:** open Claude Desktop → **Settings**
→ **Developer** (under "Desktop app" section) → **Local MCP servers** →
click **Edit Config**. This always opens the file the app actually reads,
regardless of install type.
> **Dead end to avoid:** Settings → **Connectors** → **Add custom connector**
> looks like the obvious place to add a server, but it's only for **remote**
> MCP servers (ones reachable by a URL, e.g. a hosted server on the
> internet). It has no field for a local command like `uv run main.py`, so
> don't waste time there for a local stdio server — go to
> **Developer → Local MCP servers** instead.
### 4c. The config format
The file may already contain other keys (preferences, Cowork settings,
etc. on newer builds). Just add `mcpServers` as a new top-level key —
don't delete anything else:
```json
{
"mcpServers": {
"leave-manager": {
"command": "uv",
"args": [
"--directory",
"C:\\Users\\<you>\\Desktop\\MCP\\my-mcp-server",
"run",
"main.py"
]
}
}
}
```
> If `"command": "uv"` isn't found (Claude Desktop doesn't always inherit
> your terminal's PATH), use the full path instead, e.g.:
> `C:\\Users\\<you>\\AppData\\Local\\Programs\\Python\\Python314\\Scripts\\uv.exe`
### 4d. Restart and verify
1. Save the config file.
2. **Fully quit** Claude Desktop — right-click its icon in the system tray
(bottom-right, near the clock) → **Quit/Exit**. Closing the window alone
is not enough.
3. Reopen Claude Desktop.
4. Go to **Settings → Developer → Local MCP servers** — your server should
show up with a green **"running"** badge.
5. Start a new chat and ask a natural question, e.g.:
_"How many leave days does E001 have left?"_
Claude should say "Loaded tools, used `<your-server-name>` integration"
and answer using your tool's actual return value.
## 5. Quick troubleshooting checklist
| Symptom | Likely cause | Fix |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `Error: typer is required...` | `mcp[cli]` installed globally, not in project venv | `uv add "mcp[cli]"` inside the project folder |
| `Claude app not found` from `mcp install` | Claude Desktop not installed, or `mcp install`'s auto-detect is unreliable | Install the app, or skip `mcp install` and edit the config file directly |
| Inspector shows repeated JSON parse errors | Server process is printing plain text instead of JSON (crash message, or a stray `print()`) | Check the error text embedded in the parse error; fix the underlying issue |
| Settings → Developer → "No servers added" after editing config | Edited the wrong config file, or `mcpServers` key missing/malformed | Use Settings → Developer → Edit Config to find the _actual_ file in use; verify JSON is valid |
| Server shows up but Claude never calls it | Ambiguous tool descriptions, or server crashed silently | Check "View Logs" next to the server entry in Settings → Developer |
## 6. Useful commands reference
```powershell
uv init . # create a new uv project
uv add "mcp[cli]" # add MCP with CLI/dev tools as a dependency
uv run mcp dev main.py # launch MCP Inspector against your server
uv run mcp install main.py # (optional) attempt auto-install into Claude Desktop
uv run main.py # run the server standalone (useful for checking for crashes)
```
TDQS
B3.2/5.0
Scored across 3 tools
Disambiguation5/5
Each tool clearly targets a distinct function: checking balance, applying for leave, and viewing history. No overlap or ambiguity.
Naming Consistency5/5
All tools follow a consistent 'verb_leave_noun' pattern (get_leave_balance, apply_leave, get_leave_history), making the set predictable.
Tool Count4/5
Three tools is minimal but reasonable for a basic leave manager. A few more (e.g., cancel or update leave) could be helpful, but the count is not inappropriate.
Completeness2/5
The set covers basic read and create operations but lacks essential operations like cancel, update, or approve leave, leaving significant gaps for a full leave management workflow.
Maintenance
ActivitySlowing
ResponsivenessNo issues