Skip to main content
Glama
mcp-toolbox
by jorgitobg

mcp-toolbox

A small, tested MCP server that lets an AI client search and read official Spanish BOE documents. It is the start of a toolbox of narrow servers reusing the adapters of open-tender-radar and sovereign-rag.

Current status (v0.1)

One server, three read-only tools, four resources (two of them templates) and one prompt, stdio transport, built on the official Python SDK (mcp>=1.12,<2):

  • search_boe(query, limit=5): ranked keyword search (accent-insensitive, title matches weigh 3x) with snippets and source URLs.

  • get_boe_document(doc_id): metadata and paragraphs of one document; unknown ids return an MCP tool error.

  • triage_tenders(verdict=None, query=None, limit=10): lists the recorded open-tender-radar report (10 public TED/PLACSP tenders screened against a fictional profile on 2026-11-04) with GO / REVIEW / NO_GO and per-criterion evidence. Rule-based screening, not bid advice; evidence like "days left" is frozen at the recording date. Provenance in src/mcp_toolbox/data/tenders/SOURCES.md.

  • Prompt summarise_boe_document(doc_id, audience="a non-lawyer"): a reusable template that embeds the numbered paragraphs of a bundled document and instructs the model to stay within the text and cite paragraph numbers. It only renders text; no model is called by the server. Unknown ids return an MCP error.

Data: 11 recorded BOE documents (BOE of 2026-11-03) bundled in the package. No network, keys or LLM at runtime or in tests.

Related MCP server: boe-mcp

Quickstart

Python 3.12+.

git clone https://github.com/jorgitobg/mcp-toolbox
cd mcp-toolbox
python -m venv .venv && . .venv/bin/activate
pip install -e .
mcp-toolbox-demo        # or: python -m mcp_toolbox.demo

Use it from an MCP client by launching python -m mcp_toolbox (or mcp-toolbox) over stdio.

Configure a desktop MCP client

Most desktop clients read a JSON file with an mcpServers map (the file location depends on the client). Point command at the Python of the virtualenv where you ran pip install -e . (use an absolute path):

{
  "mcpServers": {
    "mcp-toolbox": {
      "command": "/absolute/path/to/mcp-toolbox/.venv/bin/python",
      "args": ["-m", "mcp_toolbox"]
    }
  }
}

Besides the three tools, the server exposes read-only resources that a client can attach to a conversation without a tool call: boe://index (all bundled documents), boe://document/{doc_id} (one document, same payload as get_boe_document), tenders://report (the whole recorded tender report) and tenders://report/{verdict} (GO, REVIEW or NO_GO; same payload as triage_tenders). No subscriptions: the data are static snapshots. This snippet follows the common client convention and was not tested against a specific desktop client here; the server itself is exercised by the test-suite with the official Python MCP client over stdio.

Development: pip install -e '.[dev]', then ruff check . && ruff format --check . && pyright && pytest (coverage gate 85%). Only editable installs are exercised.

Demo output

The demo spawns the real server as a subprocess and talks to it with the official MCP client. Real output:

tools: get_boe_document, search_boe, triage_tenders
search_boe('plazas Subalterno Ayuntamiento'): 3 result(s)
  BOE-A-2026-23041 score=8 Resolución de 28 de octubre de 2026, del Ayuntamiento de Torrox (Málaga), referente a la c
  BOE-A-2026-23049 score=8 Resolución de 29 de octubre de 2026, del Ayuntamiento de Borriana/Burriana (Castellón/Cast
  BOE-A-2026-23045 score=7 Resolución de 29 de octubre de 2026, del Ayuntamiento de Tarragona, Instituto Municipal de
get_boe_document(BOE-A-2026-23041): 6 paragraphs, https://www.boe.es/diario_boe/xml.php?id=BOE-A-2026-23041
triage_tenders(verdict='GO'): 1 of 10 matched
  [GO] PLACSP:412026 Servicios de operación del Centro de Operaciones de Segurida
    cpv       pass    CPV 72222300 within profile
    deadline  pass    7 days left
    keywords  unknown no profile keyword in title
    value     pass    206,612 EUR within limits

Layout

Hexagonal: domain/ (models, DocumentSource port), application/search.py, adapters/ (BOE XML parser, bundled corpus), server.py (MCP wiring). See docs/spec/0001-boe-search-server.md and docs/adr/.

Limitations

  • Keyword counting only: no stemming, phrases or semantics.

  • Static snapshots (11 BOE documents, one tender report); no live BOE, TED or PLACSP access, and the tender report is a copy, not a live call into open-tender-radar.

  • stdio only; no HTTP transport or auth.

  • mcp 2.x is not supported yet (API renamed); pinned below 2. A throwaway run of the tests against 2.3.0 passed after mechanical renames, see ADR 0003.

Licence

Apache-2.0. BOE content is reused under the Agency's reuse licence (see src/mcp_toolbox/data/SOURCES.md).

Available Tools

3 tools
get_boe_documentA

Return one bundled BOE document (metadata + paragraphs) by identifier.

Inputs: doc_id (required). Returns: object

search_boeB

Search the bundled BOE corpus by keywords. Title matches weigh 3x. Offline, read-only.

Inputs: query (required), limit. Returns: object

triage_tendersA

List recorded TED/PLACSP tenders screened against a fictional profile.

Rule-based GO / REVIEW / NO_GO with per-criterion evidence (open-tender-radar report, recorded 2026-11-04). Optional verdict filter and keyword query. Offline, read-only.

Inputs: limit, query, verdict. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 3 tools

    Disambiguation4/5

    search_boe and get_boe_document form a clean search/retrieve pair over the same corpus, and triage_tenders targets a clearly different dataset (TED/PLACSP) with a different output shape. The only mild overlap is that both search_boe and triage_tenders are 'query a corpus with keywords and filters' operations, so an agent could occasionally hesitate about which entry point to use.

    Naming Consistency4/5

    All names are snake_case with a leading verb (search_/get_/triage_), which reads predictably. The minor deviation is that search_boe names the corpus rather than the object (compare get_boe_document), so the noun convention isn't fully uniform.

    Tool Count3/5

    Three tools is thin for something branded as a 'toolbox', and the surface splits across two fairly different domains (BOE documents vs. tender triage), making the small set feel like two mini-servers glued together. It is defensible for a narrow offline read-only scope, but it sits at the borderline.

    Completeness3/5

    The BOE side has adequate read-only coverage (search plus fetch by identifier) for its offline scope. The tender side is a dead end: triage_tenders lists screened tenders but there is no tool to fetch a specific tender's full record or evidence detail, forcing agents to work from the list output alone.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers