Skip to main content

gengomcp

An MCP server (Python, stdio transport) that lets an agent retrieve ACL conference papers about NLP from a Qdrant vector database. It combines semantic search (Sentence‑Transformers embeddings) with structured filtering by bibliographic fields like publication year and venue.

Qdrant access is currently limited. This server queries a shared Qdrant collection of ACL NLP papers. If you'd like credentials to use it, please reach out to the project maintainer — access may be granted at a limited scale. You'll receive a QDRANT_URL, QDRANT_KEY, and QDRANT_COLLECTION_NAME to add to your .env or MCP client env field.

Quick start

# 1. install (from the project root)
uv sync            # creates .venv and installs deps (mcp, qdrant-client, sentence-transformers, python-dotenv)

# 2. configure — NEVER commit real keys
cp .env.example .env   # edit .env with your Qdrant credentials

# 3. run
uv run gengomcp             # console script (registered by pyproject.toml)
# or: uv run python server.py
# or: uv run python main.py

The server reads its .env from the project root (next to server.py), so it also works when launched from another working directory (e.g. by an MCP client or a sandbox) — see Wiring it into an MCP client.

The API key is read from the environment and is never logged or hard-coded. For local runs, copy .env.example → .env and fill in your Qdrant connection details (.env is gitignored). For MCP-client deployment, you can inject the same variables via your client's env field instead — see Configuring credentials via the MCP client.

Wiring it into an MCP client

Any MCP client over stdio works. The command below is cwd‑independent (the absolute server path means the server loads .env from its own project root), so it's safe to launch from any working directory.

Example for Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "gengomcp": {
      "command": "uv",
      "args": ["run", "--project", "/Users/.../gengomcp", "gengomcp"]
    }
  }
}

Using the installed gengomcp console script (registered by pyproject.toml) is the simplest entry point. For setups without uv, point command at the script in the venv directly:

"command": "/Users/.../gengomcp/.venv/bin/gengomcp",
"args": []

Configuring credentials via the MCP client

Credentials (QDRANT_URL, QDRANT_KEY, QDRANT_COLLECTION_NAME) are read from the process environment, so you can inject them directly through your MCP client's env field — no .env file required. This is the recommended way to wire per-agent secrets:

{
  "mcpServers": {
    "gengomcp": {
      "command": "uv",
      "args": ["run", "--project", "/Users/.../gengomcp", "gengomcp"],
      "env": {
        "QDRANT_URL": "https://<cluster>.cloud.qdrant.io",
        "QDRANT_KEY": "<your-api-key>",
        "QDRANT_COLLECTION_NAME": "papers_test"
      }
    }
  }
}

Precedence: environment variables set by the MCP client (env field) always take priority. A local .env file is only used as a fallback (loaded with python-dotenv, which does not override existing env vars). This means you can use .env while developing locally and switch to the client env field for production without changing the server.

Required variables (no defaults):

Variable Description
QDRANT_URL Qdrant cluster URL
QDRANT_KEY Qdrant API key
QDRANT_COLLECTION_NAME Collection to search (e.g. papers_test)

Optional variables (have defaults, see .env.example): EMBEDDING_MODEL, AUTO_CREATE_INDEXES, LOG_LEVEL.

If a required variable is missing at startup, the server exits with a clear error explaining how to set it.

Poolside (pool)

The server is already registered for you. Verify with:

pool mcp list          # shows: gengomcp
pool mcp get gengomcp  # shows the stored command + args

It was added with the cwd‑independent command above, stored under mcp_servers in ~/.config/poolside/settings.yaml (personal config). The server reads its own .env, so no keys are stored in the poolside config. To remove it later:

pool mcp remove gengomcp

Tools

Tool Purpose
search_papers Semantic search for ACL NLP papers. USE when the user has a topic/question. Embeds query and returns the most similar papers, optionally narrowed by structured filters.
get_paper USE to inspect a single ACL NLP paper in full detail (abstract, summaries, entities) when you already have its paper_uuid from a search result.
list_papers USE to browse/filter ACL NLP papers with no query text — pure structured filtering + pagination (e.g. "all ACL 2024 papers").
get_collection_info USE first to discover available venues, years, fields of study, and vector names before building filters.

search_papers parameters

query                 str   (required) search text
limit                 int   = 10   (clamped 1..100)
vector_name           str   = "overview"   one of overview/approach/challenge/outcome
year                  int            exact publication year (e.g. 2026)
year_min / year_max   int            year range (inclusive)
year_gt  / year_lt    int            year range (exclusive)
venue                 str            substring match on the booktitle (e.g. "Annual Meeting")
collection_acronym    str            exact venue acronym, e.g. "ACL" / "EMNLP" / "NAACL"
collection_id         str            e.g. "2026.acl"
field_of_study        list[str]      membership on `field_of_studies` (e.g. ["Reasoning"])
author                str            name contained in `author_names`
min_score             float          only return results with similarity >= this value

All filters are AND‑combined, so you can layer them, e.g. search_papers(query="...", year_min=2020, collection_acronym="ACL").

Example tool calls

search_papers(query="stress testing large language models",
              vector_name="overview", year_min=2024, year_max=2026,
              collection_acronym="ACL", limit=5)

get_paper(paper_id="000036a6-e2be-523e-8b8d-0f2cbe2b39e7")

list_papers(collection_acronym="EMNLP", year=2024, limit=20)

list_papers(field_of_study=["Reasoning"], author="Pan", limit=20, offset=<prev_uuid>)

How it works

  • Secrets & config — credentials are read from environment variables (QDRANT_URL, QDRANT_KEY, QDRANT_COLLECTION_NAME). For local runs, copy .env.example → .env and fill them in. For MCP deployment, inject the same variables via your client's env field instead. QDRANT_KEY is used directly by the Qdrant client and is never printed or hard-coded.
  • Payload indexes — Qdrant requires a payload index to filter on a field. This collection ships with no indexes, so the server creates the needed ones idempotently at startup (non-destructive — it only adds indexes). Disable with AUTO_CREATE_INDEXES=0 if you manage indexes yourself.
  • Embeddings — queries are embedded with Sentence‑Transformers using Snowflake/snowflake-arctic-embed-s, the only model that matches this collection's 384-dimensional index. The server can truncate+renormalise other model outputs to the index dimensionality (matryoshka‑style) as a safety net, but models in a different embedding space (e.g. the 768-dim m-v1.5) will still fail to retrieve — see The embedding model.
  • Named vectors — the overview/approach/challenge/outcome named vectors in the collection are all 384-dimensional.

The embedding model

The collection's vectors are 384-dimensional and were built with the Snowflake arctic-embed "s" model (Snowflake/snowflake-arctic-embed-s). This is the only model that produces embeddings in the correct space for this index — it is the default and should not be changed.

The Snowflake family ships in several sizes, but only the s (384-dim) variant matches this collection's index:

model dims works with this index?
Snowflake/snowflake-arctic-embed-s 384 ✅ yes (default)
snowflake-arctic-embed-m-v1.5 768 ❌ no — different embedding space
snowflake-arctic-embed-l-v1.5 1024 ❌ no — different embedding space

The m and l variants live in different embedding spaces than the stored 384-dim vectors — even though the server can truncate to match dimensionality, the resulting embeddings will not align with the index and retrieval will fail (verified: ~0 cosine similarity against stored vectors). Keep EMBEDDING_MODEL at its default unless you re-index the collection with a different model.

Project layout

gengomcp/
├── server.py        # the MCP server (tools + Qdrant/Embeddings glue)
├── main.py          # thin launcher
├── pyproject.toml   # deps + `gengomcp` console script
├── uv.lock          # pinned dependency versions
├── LICENSE          # MIT
├── .env             # local secrets  (gitignored — never commit)
├── .env.example     # template (committed)
└── README.md

Development / testing

uv run python -c "import server; print('ok')"

Metadata

Release files for gengomcp 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gengomcp 1.0.0
File Size Uploaded
gengomcp-1.0.0.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gengomcp 1.0.0
File Interpreter ABI Platform
gengomcp-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 27.0 kB

Release files / gengomcp-1.0.0.tar.gz

Download URL gengomcp-1.0.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0e756cb96cd5d2866e09bd60270c3cfd7b28e4e799af1c965425177c0f2250f7
BLAKE2b-256 checksum
How to use checksums
44c8b124474061005b22698dd1d0d7d60bd659ebda6ea636212f3378de487e26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.18

Release files / gengomcp-1.0.0-py3-none-any.whl

Download URL gengomcp-1.0.0-py3-none-any.whl
Size 13.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8d4d4c8eaf9fc11a7abaf6e936e860fd7a82e391614b51b1c4cb38a63c8b2b20
BLAKE2b-256 checksum
How to use checksums
77e54e8780b44d93ede220e326d76e97c6f91497ac59a93dca9074e6201e306a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.18

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page