Skip to main content
Glama
Shubhikatiya

MCP Server Suite

by Shubhikatiya
README.md
# MCP Server Suite

Five production-ready **[Model Context Protocol (MCP)](https://modelcontextprotocol.io)** servers built with the official Python SDK. Supports both **stdio** and **HTTP/SSE** transports.

This suite enables any MCP-compatible client (Claude Desktop, Cursor, OpenCode) to interact with restaurant data, web search, browser automation, and filesystem operations.

---

## What is MCP?

MCP is an open standard that lets AI applications connect to external tools and data sources through a uniform interface. Think of it as **USB-C for AI tools** — write once, integrate everywhere.

---

## Servers

### 1. `restaurant_server` (stdio)
Wraps restaurant ordering tools for MCP clients.

**Tools:** `get_menu`, `check_dish_availability`, `check_quantity`, `add_item_to_cart`, `view_cart`, `get_suggestions`, `finalize_order`

### 2. `searxng_server` (stdio)
Wraps a local [SearXNG](https://searxng.org) meta-search engine.

**Tools:** `web_search`, `image_search`

- Supports categories, language, safesearch, time range, and result count
- Uses `httpx.AsyncClient` for non-blocking requests

### 3. `pinchtab_server` (stdio)
Wraps a local [PinchTab](https://pinchtab.com) headless browser.

**Tools:** `navigate`, `snapshot`, `click`, `fill`, `extract_text`

- Enables LLM-driven web browsing and form interaction
- Communicates via PinchTab's REST API

### 4. `filesystem_server` (stdio)
Sandboxed filesystem operations with path traversal protection.

**Tools:** `read_file`, `write_file`, `list_directory`, `search_files`, `file_stat`, `move_file`, `copy_file`, `delete_file`

- `_resolve()` enforces workspace sandboxing via `Path.relative_to()`
- Binary files returned as base64

### 5. `filesystem_server_sse` (HTTP/SSE)
The same filesystem server exposed over **Server-Sent Events** on HTTP.

- Built with **Starlette** + **uvicorn** + **anyio** memory streams
- Per-session JSON-RPC message routing
- Endpoints: `/` (info), `/sse` (event stream), `/messages` (POST)

---

## Quick Start

### 1. Install

```bash
pip install -r requirements.txt
```

### 2. Configure MCP Client

Copy `mcp.json.example` to your client's config directory and update URLs:

```bash
cp mcp.json.example ~/.config/claude/mcp.json   # Claude Desktop
cp mcp.json.example ~/.config/opencode/mcp.json # OpenCode
```

### 3. Run Individual Servers

```bash
# stdio servers (spawned by MCP client)
python -m mcp_servers.restaurant_server
python -m mcp_servers.searxng_server
python -m mcp_servers.pinchtab_server
python -m mcp_servers.filesystem_server /path/to/workspace

# SSE server (runs as HTTP daemon)
python -m mcp_servers.filesystem_server_sse /path/to/workspace
# Then connect to http://localhost:3000/sse
```

---

## SSE Transport Deep Dive

The SSE server is the most technically interesting component:

```python
# Per-session memory streams
rx_send, rx_recv = anyio.create_memory_object_stream(100)
tx_send, tx_recv = anyio.create_memory_object_stream(100)

# MCP server runs in background asyncio task
await server.run(rx_recv, tx_send, server.create_initialization_options())

# SSE handler serializes messages as JSON events
yield f"event: message\ndata: {message.model_dump_json()}\n\n"

# Client POSTs to /messages, injected into receive stream
await SESSIONS[session_id]["rx_send"].send(JSONRPCMessage.model_validate(data))
```

**Key design decisions:**
- Memory streams decouple HTTP I/O from MCP protocol logic
- Session cleanup on disconnect prevents resource leaks
- JSON-RPC message validation ensures protocol compliance

---

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `SEARXNG_URL` | `http://localhost:8080` | SearXNG base URL |
| `PINCHTAB_URL` | `http://localhost:9867` | PinchTab API URL |
| `RESEARCH_WORKSPACE` | `~/workspace/research` | Research report output directory |
| `MCP_HOST` | `0.0.0.0` | SSE server bind host |
| `MCP_PORT` | `3000` | SSE server bind port |

---

## Architecture

```
MCP Client (Claude Desktop / Cursor / OpenCode)
        |
        v
+-- stdio transport --+     +-- SSE transport --+
|  python -m server  |     |  http://host:3000 |
+--------------------+     +-------------------+
        |                           |
        v                           v
  Restaurant Data            Filesystem Ops
  SearXNG Search             (remote access)
  PinchTab Browser
```

---

## Security Notes

- **Filesystem sandboxing**: `_resolve()` prevents path traversal above workspace root
- **stdio transport**: No open network ports — most secure option
- **SSE transport**: Bind to `127.0.0.1` or use reverse proxy with TLS for remote access
- **PinchTab IDPI**: Restricts browsing to allowed origins by default

---

## Testing

Each server can be tested manually:

```bash
# Test SearXNG MCP server
python -m mcp_servers.searxng_server
# Then send JSON-RPC messages via stdin

# Test filesystem SSE server
curl http://localhost:3000/
curl http://localhost:3000/sse
```

---

## Tech Stack

| Component | Technology |
|-----------|-----------|
| MCP Framework | `mcp` Python SDK |
| HTTP Client | `httpx` (async) |
| SSE Server | `starlette` + `uvicorn` + `anyio` |
| Data Format | JSON / JSON-RPC |

---

## License

MIT