v0.2.0
[0.2.0] — 2026-08-02
This release exists so that a repair reaches the people running the server:
the published 0.1.0 cannot be installed any more. It declares mcp with
no upper bound, and mcp 2.0.0 removed mcp.server.fastmcp — so a fresh
pip install lindas-mcp resolves to 2.0.0 and the console script dies on
startup with ModuleNotFoundError. Measured against the real artefact in an
empty venv, cold and warm interpreter alike.
The repository has carried the fix since the 2.x migration was merged; it was
simply never released, and main kept the same version number as the broken
artefact — so nothing contradicted it.
Changed (breaking)
- Migrated to the
mcpPython SDK 2.x. The server API moved from
mcp.server.fastmcptomcp.server.mcpserverwith no compatibility shim,
and the dependency is nowmcp>=2.0.0,<3. The tool surface is unchanged —
what breaks is embedding this server's Python API and the dependency floor.
Anyone who must stay onmcp1.x should stay on 0.1.0, and pin an upper
bound themselves, because the published 0.1.0 has none.
Added
- Portfolio-standard repository structure:
CONTRIBUTING.md/.de,
SECURITY.md/.de,EXAMPLES.md,PUBLISHING.md,docs/network-egress.md,
docs/roadmap.md,Dockerfile,compose.yaml,.dockerignore,.gitignore,
claude_desktop_config.json,server.json(MCP Registry metadata), and
.github/workflows (ci,live,publish) +dependabot.yml. tool-definitions.lock.jsonwith a SEC-022 CI integrity check: a committed
hash snapshot of every tool name and its argument surface, verified by
server.tool_manifest()so a silent rug-pull fails the build.- Full
mcp-auditrun underaudits/2026-07-26T125407-Z-lindas-mcp/
(production-ready; 11 hardening findings). - Audit remediation — structured logging (OBS-003): stderr-bound JSON logs
viastructlog(logging_config.py), per-tool-call events (tool, duration,
outcome) and aLOG_LEVELenv var. stdout stays reserved for JSON-RPC. - Audit remediation — not-found heuristics (ARCH-003):
search_cubesand
resolve_municipalitynow returnmatch_type(exact/none) and an
actionablesuggestionon an empty result. - Audit remediation —
Contextinjection (SDK-003): tools accept aContext
and emit progress/debug events for long-running SPARQL calls.
Changed
- Egress hardening (SEC-021): added a code-layer
ALLOWED_HOSTSallow-list
andassert_host_allowed()inlindas/client.py; the HTTP client now uses
follow_redirects=Falseso an off-host redirect is surfaced as an error. - Binding default (SEC-016): the SSE / streamable-http transport now defaults
HOSTto127.0.0.1(loopback) instead of0.0.0.0; binding to all
interfaces is an explicit opt-in and prints a stderr warning. The container
image setsHOST=0.0.0.0deliberately. - Connection pooling (SDK-001): a single
httpxclient is now built once by
a FastMCPlifespanand shared across all tool calls (client_session()),
instead of a fresh client per call. Direct unit-test calls fall back to a
per-call client. - Tool annotations (ARCH-009): all tools now also set
idempotentHint: true
andopenWorldHint: true. - Schema-level input validation (SEC-018): tool arguments use
Annotated[..., Field(ge=/le=/min_length=/max_length=)]— out-of-range inputs
are rejected as aValidationErrorat the boundary instead of being clamped. - Error masking (OBS-002): unexpected exceptions are logged server-side and
surfaced to the LLM as a generic message;SparqlError/UpstreamError(which
carry only the public endpoint's own diagnostics) still propagate unchanged. - CORS (SDK-004): the HTTP transport serves a CORS-wrapped app exposing the
Mcp-Session-Idheader, with origins configurable viaALLOWED_ORIGINS
(comma-separated; default*) instead of a hardcoded wildcard. - Documented the single-file
server.pyrationale (ARCH-011) and the MCP
protocol-version policy (ARCH-012). - Aligned
pyproject.tomlto the portfolio floor (mcp>=1.28.1,structlog,
Python 3.13 classifier,IssuesURL).