Skip to main content
Glama
Rajes07

JSONPlaceholder MCP Server

by Rajes07
README.md
# JSONPlaceholder MCP Server (practice project)

A minimal MCP server, built with the official Python SDK's `FastMCP`
helper, that wraps the public [JSONPlaceholder](https://jsonplaceholder.typicode.com)
REST API. It's meant as a template: swap `BASE_URL` and the tool
functions for your own internal API and the shape stays the same.

## What it exposes

| MCP tool               | REST call                          |
|-------------------------|-------------------------------------|
| `list_posts`            | `GET /posts`                        |
| `get_post`               | `GET /posts/{id}`                   |
| `create_post`            | `POST /posts`                       |
| `get_comments_for_post`  | `GET /posts/{id}/comments`          |
| `get_user`               | `GET /users/{id}`                   |
| `list_users`             | `GET /users`                        |

## 1. Set up

```bash
cd jsonplaceholder-mcp
python -m venv .venv
source .venv/bin/activate       # on Windows: .venv\Scripts\activate
pip install -r requirements.txt
```

## 2. Sanity-check it runs

```bash
python server.py
```

It should sit there waiting on stdio (no visible output is expected —
that's normal, it's waiting for an MCP client to talk to it over
stdin/stdout). Ctrl+C to stop.

You can also use the MCP inspector to poke at it interactively without
wiring up a full client:

```bash
mcp dev server.py
```

This opens a browser UI where you can call each tool by hand and see
the JSON that comes back.

## 3. Connect it to Claude Desktop

Add an entry to your Claude Desktop config
(`~/Library/Application Support/Claude/claude_desktop_config.json` on
macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):

```json
{
  "mcpServers": {
    "jsonplaceholder": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/jsonplaceholder-mcp/server.py"]
    }
  }
}
```

Restart Claude Desktop, and the `jsonplaceholder` tools should show up
in the tool picker.

## 4. Where to go from here (adapting to a real API)

To point this at an internal REST service instead:

1. Change `BASE_URL`.
2. Add auth — most internal APIs need a header or token. Add it once
   in `_get`/`_post` (e.g. `headers={"Authorization": f"Bearer {TOKEN}"}`),
   pulling the token from an environment variable rather than hardcoding it.
3. Replace each `@mcp.tool()` function with one per operation you want
   to expose. Keep the docstrings precise — the LLM uses them to decide
   when and how to call each tool, so vague docstrings lead to the tool
   being picked (or skipped) incorrectly.
4. Keep tools narrow and single-purpose rather than one giant
   "call any endpoint" tool — that's what makes MCP tools reliable for
   an LLM to select correctly.