Skip to main content
Glama
GowthamS05

JSON Placeholder Posts MCP

by GowthamS05
README.md
# JSON Placeholder Posts MCP

A small UV-managed FastMCP server that calls:

```text
https://json-placeholder.mock.beeceptor.com/posts
```

It exposes two MCP tools:

- `get_posts_by_user`, which returns matching posts when `userId` is provided.
  If `userId` is missing, it creates a durable pending workflow instead of using
  native MCP elicitation.
- `continue_workflow`, which accepts the missing input and completes a pending
  workflow from any pod.

The tools emit MCP server notifications with log messages and progress updates
while they resolve input, fetch posts, and filter results.

## Setup

```bash
uv sync
```

## Run

For MCP clients that use stdio:

```bash
uv run json-placeholder-posts-mcp
```

For local HTTP testing:

```bash
uv run json-placeholder-posts-mcp --transport streamable-http
```

By default the HTTP server listens at:

```text
http://127.0.0.1:8000/mcp
```

You can override the host and port with environment variables:

```bash
HOST=127.0.0.1 PORT=9000 uv run json-placeholder-posts-mcp --transport streamable-http
```

Workflow continuation uses Mongo. By default, the server connects to
`mongodb://localhost:27017`:

```bash
uv run json-placeholder-posts-mcp --transport streamable-http
```

For deployed environments, override the Mongo connection details:

```bash
MONGO_URI=mongodb://mongo:27017 \
MONGO_DATABASE=json_placeholder_posts_mcp \
MONGO_WORKFLOW_COLLECTION=elicitation_workflows \
uv run json-placeholder-posts-mcp --transport streamable-http
```

## Technical Design

See [docs/mcp-workflow-design.md](docs/mcp-workflow-design.md) for the MCP
creation flow, workflow continuation pattern, elicitation decision, and
multi-pod workflow ID storage design.

## Tool

### `get_posts_by_user`

Fetches all posts from the Beeceptor API and returns only posts matching the
provided `userId`. When `userId` is omitted, the server creates a pending
workflow that any pod can continue with the returned `workflowId`.

Input:

```json
{
  "userId": 1
}
```

Output:

```json
{
  "status": "completed",
  "userId": 1,
  "count": 2,
  "posts": [],
  "source": "https://json-placeholder.mock.beeceptor.com/posts"
}
```

Pending workflow input:

```json
{}
```

Pending workflow output:

```json
{
  "status": "input_required",
  "workflowId": "abc123",
  "message": "Please choose a user:\n1. User 1\n2. User 2\n3. User 3\n4. User 4\n5. User 5\n6. User 6\n7. User 7\n8. User 8\n9. User 9\n10. User 10\n\nReply with the number or userId.",
  "requiredInput": {
    "field": "userId",
    "type": "select",
    "dataType": "integer",
    "display": "dropdown",
    "options": [
      {
        "label": "User 1",
        "value": 1
      },
      {
        "label": "User 2",
        "value": 2
      },
      {
        "label": "User 3",
        "value": 3
      }
    ]
  },
  "nextTool": "continue_workflow",
  "expiresAt": "2026-06-18T10:15:00+00:00"
}
```

Clients that own their UI can render `requiredInput.options` as a dropdown.
Chat clients without custom UI support can show the same `message` as numbered
choices and pass the selected `userId` to `continue_workflow`.

### `continue_workflow`

Completes a pending workflow and clears its stored details after success or
failure.

Input:

```json
{
  "workflowId": "abc123",
  "userId": 1
}
```

## Development

```bash
uv run pytest
uv run ruff check .
```