Skip to main content
Glama
DhanyaHegdek

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