Skip to main content
Glama
README.md
# Mercury MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server exposing three tools to
any MCP-compatible host (Claude Desktop, Cursor, etc.). It runs as a local Python process over
stdio — no database, no REST API, no Docker Compose, no separate frontend.

## Overview

The server exposes three tools:

| Tool | Purpose |
|------|---------|
| `surf_sense_search` | Live web research via the SurfSense REST API (with a mock fallback when not configured). |
| `ghost_pepper_process` | Local transcript / text processing — extracts headlines, word count, and top keywords. |
| `hermes_3d_visualize` | 3D office visualization — returns an iframe URL when enabled, otherwise a text summary. |

Configuration is done entirely via environment variables (optionally loaded from a `.env` file).

> **SDK note:** the `mcp` Python SDK removed the low-level `@app.list_tools()` /
> `@app.call_tool()` decorator API in 2.x. This project uses the current low-level
> `mcp.server.Server` API, passing the handlers as `on_list_tools` / `on_call_tool`
> constructor arguments. The three tool names, descriptions, and input schemas are
> identical to the design. (`FastMCP` was also renamed to `MCPServer` in 2.x.)

## Requirements

- Python 3.11+
- [pip](https://pip.pypa.io/)

## Setup

Create and activate a virtual environment, then install the package with its dependencies:

```bash
# from the project root (this directory)
python -m venv .venv

# activate: Windows (Git Bash / cmd)
source .venv/Scripts/activate
# activate: macOS / Linux
# source .venv/bin/activate

# install the package in editable mode (installs mcp, requests, python-dotenv, pytest)
pip install -e ".[dev]"
```

> `[dev]` includes `pytest`. If you did not install with the `dev` extra, run
> `pip install pytest` and `pip install -e .` separately.

Optional: copy the environment template and fill in your keys:

```bash
cp .env.example .env
```

## Environment variables

| Variable | Default | Description |
|----------|---------|-------------|
| `SURFSENSE_API_URL` | `https://api.surfsense.com` | Base URL of the SurfSense API. |
| `SURFSENSE_WORKSPACE_ID` | `""` | SurfSense workspace ID (required to enable live search). |
| `SURFSENSE_API_KEY` | `""` | SurfSense API key. `surf_sense_search` uses a mock fallback when this is empty. |
| `GHOST_PEPPER_TRANSCRIPT_DIR` | `""` | Directory of `.md` transcript files for `ghost_pepper_process`. |
| `HERMES3D_ENABLED` | `false` | When `true`, `hermes_3d_visualize` returns an iframe; otherwise a text summary. |
| `HERMES3D_OFFICE_URL` | `http://localhost:3000/office` | URL embedded in the iframe. |
| `LOG_LEVEL` | `INFO` | Logging level. |

## Running the server

Run the stdio server directly:

```bash
python -m mercury_mcp.server
```

or via the installed console script:

```bash
mercury-mcp
```

Because it is an MCP stdio server it is normally launched *by* your MCP host rather than
run interactively. See [MCP server config](#mcp-server-config-section-8) below.

## The three tools

### `surf_sense_search`

Live web search via SurfSense. When `SURFSENSE_API_KEY` and `SURFSENSE_WORKSPACE_ID` are both
set it performs a real scrape; otherwise it returns deterministic mock data.

**Input schema:** `query` (required string) and `connector` (optional, default `google_search`,
one of `google_search`, `reddit`, `youtube`, `web_crawl`, `amazon`, `walmart`, `google_maps`,
`indeed`, `tiktok`, `instagram`).

```json
{
  "query": "latest AI news",
  "connector": "google_search"
}
```

**Output:** JSON with `source`, `query`, and `items` (each `item` has `title` and `content`).

### `ghost_pepper_process`

Process a transcript or arbitrary text. If `text` is empty, it reads the most recently
modified `.md` file in `GHOST_PEPPER_TRANSCRIPT_DIR`.

**Input schema:** `text` (optional string).

```json
{
  "text": "We discussed AI trends and new features. The roadmap is approved. Next step is rollout."
}
```

**Output:** JSON with `headlines` (up to 3 sentences), `word_counts`, `top_terms` (up to 5
keyword/count pairs), and the full `transcript`.

### `hermes_3d_visualize`

Turn processed data into a 3D office visualization. When `HERMES3D_ENABLED=true` it returns an
HTML `<iframe>` pointing at `HERMES3D_OFFICE_URL`; otherwise it returns a short text summary.

**Input schema:** `data` (required object, e.g. the result of `ghost_pepper_process`).

```json
{
  "data": { "headlines": ["We discussed AI trends", "Roadmap approved"] }
}
```

**Output:** iframe HTML or a text string.

## Tests

```bash
pytest -q
```

## MCP server config (section 8)

Add the server to your MCP client configuration. Example for
[`openmausbot`](examples/openmausbot_mcp_config.json):

```json
{
  "mcpServers": {
    "mercury": {
      "command": "python",
      "args": ["-m", "mercury_mcp.server"],
      "env": {}
    }
  }
}
```

Use the full path to your venv's Python if `python` is not on the host's `PATH`. For instance,
on Windows the venv interpreter is typically:
`.venv/Scripts/python.exe` under the project root. You can also inject environment variables
via the `"env"` block, or rely on the `.env` file (loaded automatically on startup).

## Project layout

```
.
├── pyproject.toml
├── README.md
├── .env.example
├── .gitignore
├── src/
│   └── mercury_mcp/
│       ├── __init__.py
│       ├── server.py
│       ├── config.py
│       └── tools/
│           ├── __init__.py
│           ├── surfsense.py
│           ├── ghostpepper.py
│           └── hermes3d.py
├── tests/
│   ├── test_surfsense.py
│   ├── test_ghostpepper.py
│   └── test_hermes3d.py
└── examples/
    └── openmausbot_mcp_config.json
```

TDQS

B3.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a clearly distinct action: web search, transcript/text processing, and 3D visualization. There is no functional overlap between them, so an agent will not confuse surf_sense_search with ghost_pepper_process or hermes_3d_visualize.

Naming Consistency4/5

All three follow a consistent <brand>_<action> snake_case pattern (surf_sense_search, ghost_pepper_process, hermes_3d_visualize), which is predictable. However the opaque brand prefixes (ghost_pepper, hermes) reduce readability and hint at product-specific naming rather than a clean verb_noun convention.

Tool Count4/5

Three tools is on the thin side but each maps to a distinct stage of a search -> process -> visualize pipeline, so none feels redundant. It is reasonable for a focused media/analysis server, though slightly under-scoped for standalone use.

Completeness3/5

The set implies a pipeline (search, process, visualize) but lacks ways to retrieve or persist intermediate results, configure the pipeline, or manage prior runs. Core stages exist but there are notable gaps that could force agents to work around missing operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues