Skip to main content

Lucerna MCP

CLI or API | MCP

PyPI - Version MCP Server PyPI - Downloads GitHub Repo stars GitHub forks GitHub contributors PyPI - License GitHub GitHub last commit (by committer) GitHub pull requests GitHub closed pull requests GitHub issues GitHub top language GitHub language count GitHub repo size GitHub repo file count (file type) PyPI - Wheel PyPI - Implementation

Documentation — Installation, deployment, and usage across the API, CLI, MCP, official documentation.


Table of Contents

Overview

lucerna-mcp exposes a standardized interface to the platform's OpenSearch deployment (CA-50, http://localhost:9200) via the Model Context Protocol — index/alias/mapping/settings/rollover admin, BM25/k-NN/hybrid search, ingest pipeline admin, and document-level-security (DLS) policy read/apply. A trigger-only opensearch_reindex_from_kg tool records a rebuild request as an :IndexingRun node; the actual reindex is CA-24's own CDC-fed indexer.

The single hardest invariant this package holds: every request carries the calling principal's own token, attached fresh on every HTTP call — never a fixed/service-level credential. lucerna_mcp.auth.get_client() is the ONLY client factory in the package; there is no fallback path. See Architecture and AGENTS.md for how this is enforced structurally.

k-NN is disabled cluster-wide (pre-AVX2 homelab nodes — no AVX2-free OpenSearch k-NN build exists upstream). opensearch_knn_search/ opensearch_hybrid_search exist per this package's scope but raise a typed, named error rather than a bare 500 when the plugin refuses the operation.

Installation

Pick the extra that matches what the operator want to run:

Extra Installs Use when
lucerna-mcp[mcp] Connector-focused MCP server (agent-connector-sdk — FastMCP/FastAPI + epistemic-graph[full]) The operator only run the MCP server (smallest install / image)
lucerna-mcp[all] Everything (mcp + agent + logfire) Development / both surfaces
uv pip install "lucerna-mcp[mcp]"

Container images (:mcp)

One multi-stage docker/Dockerfile builds the MCP-only image (--target mcp):

docker build --target mcp   -t lucerna-mcp:mcp    .

Usage

Run the MCP server directly:

python -m lucerna_mcp

MCP Configuration Example (stdio)

{
  "mcpServers": {
    "lucerna-mcp": {
      "command": "uv",
      "args": ["run", "lucerna-mcp"],
      "env": {
        "MCP_TOOL_MODE": "intent",
        "OPENSEARCH_URL": "http://localhost:9200",
        "OPENSEARCHTOOL": "True",
        "INGESTTOOL": "True",
        "ENABLE_DELEGATION": "True",
        "OIDC_CONFIG_URL": "http://localhost:8080/realms/homelab/.well-known/openid-configuration",
        "OIDC_CLIENT_ID": "",
        "OIDC_CLIENT_SECRET_REF": "",
        "OPENSEARCH_KEYCLOAK_CLIENT_ID": "opensearch"
      }
    }
  }
}

Architecture

api/api_client_opensearch.py's OpenSearchApi wraps opensearchpy.OpenSearch directly (the fleet's one new dependency this package adds). Its transport auth is api/api_client_base.py's _PerCallBearerAuth — a requests.auth.AuthBase callable that opensearchpy's RequestsHttpConnection invokes fresh on EVERY outbound request (checked against opensearch-py 3.2.0's own source: RequestsHttpConnection.__init__ assigns http_auth directly to requests.Session.auth, and requests calls an AuthBase.__call__ per request, never once at session construction).

auth.py's get_client() is the ONLY client factory in the package. It exchanges the calling MCP principal's own token for one scoped to the opensearch Keycloak client audience via the fleet's shared agent_connector_sdk.mcp.delegated_auth (RFC 8693 token exchange) — and, unlike gitlab-api/twenty-mcp's use of the same helper, it has no fallback to a fixed/service credential: if delegation isn't enabled or the exchange fails, it raises. No tool in mcp/mcp_opensearch.py or kg_ingest.py accepts a credential override parameter of any kind.

mcp/mcp_opensearch.py registers four tool groups (index, search, pipelines, security) via one register_tool_surface(...) call in mcp_server.py, matching the fleet's one-registration-call convention. kg_ingest.py registers the fifth group (opensearch_reindex_from_kg, tagged ingest/kg/kg_ingest) — a trigger-only tool that records an :IndexingRun node through the required native_ingest (Wire-First) authority; it never performs the reindex itself (CA-24 does).

opensearch_apply_dls_bundle validates a caller-supplied DEC-CA-04 policy bundle's shape (renderings.opensearch, governs: ["M1"], graph) before applying it — this package contains no code path that builds a DLS predicate from scratch.

Environment Variables

Package environment variables

Variable Example Description
OPENSEARCH_URL http://localhost:9200
ENABLE_DELEGATION True lucerna-mcp has NO fixed/service-credential fallback — every request carries the calling principal's own token, exchanged for one scoped to the audience below. These flags are the fleet-shared MCP OIDC-delegation surface (agent_connector_sdk.mcp.server_factory / delegated_auth), not lucerna-mcp-specific, but MUST be enabled for this package's tools to work at all:
OIDC_CONFIG_URL http://localhost:8080/realms/homelab/.well-known/openid-configuration
OIDC_CLIENT_ID —
OIDC_CLIENT_SECRET_REF —
OPENSEARCH_KEYCLOAK_CLIENT_ID opensearch Audience/scope this package exchanges the caller's token for — defaults to OPENSEARCH_KEYCLOAK_CLIENT_ID if --audience isn't passed at MCP startup.
OPENSEARCH_TLS_PROFILE —
OPENSEARCH_TLS_PROFILE_REF —
OPENSEARCHTOOL True
INGESTTOOL True

Inherited agent-connector-sdk variables (apply to every connector)

Variable Example Description
TRANSPORT stdio MCP transport: stdio | streamable-http | sse
HOST 127.0.0.1 Loopback bind host (set an authenticated ingress explicitly)
PORT 8000 Bind port (HTTP transports)
MCP_TOOL_MODE intent Tool surface: intent | condensed | verbose | both
MCP_ENABLED_TOOLS — Comma-separated tool allow-list
MCP_DISABLED_TOOLS — Comma-separated tool deny-list
MCP_ENABLED_TAGS — Comma-separated tag allow-list
MCP_DISABLED_TAGS — Comma-separated tag deny-list
EUNOMIA_TYPE none Authorization mode: none | embedded | remote
EUNOMIA_POLICY_FILE mcp_policies.json Embedded Eunomia policy file
EUNOMIA_REMOTE_URL — Remote Eunomia authorization server URL
ENABLE_OTEL False Enable OpenTelemetry export
OTEL_EXPORTER_OTLP_ENDPOINT — OTLP collector endpoint
MCP_CLIENT_AUTH — Outbound MCP child auth: oidc-client-credentials | basic | none
MCP_BASIC_AUTH_USERNAME — HTTP Basic username (MCP_CLIENT_AUTH=basic)
MCP_BASIC_AUTH_PASSWORD_REF secret://identity/mcp-basic-password Runtime secret reference for HTTP Basic auth (MCP_CLIENT_AUTH=basic)
DEBUG False Verbose logging
PYTHONUNBUFFERED 1 Unbuffered stdout (recommended in containers)
MCP_URL http://localhost:8000/mcp URL of the MCP server the agent connects to
PROVIDER openai LLM provider for the agent
MODEL_ID gpt-4o Model id for the agent

10 package + 22 inherited variable(s). Auto-generated from .env.example + the shared agent-connector-sdk set — do not edit.

Variable Required Notes
OPENSEARCH_URL recommended Bare OpenSearch origin. Defaults to http://localhost:9200.
ENABLE_DELEGATION ✅ Must be True — this package has no other credential path.
OIDC_CONFIG_URL ✅ OIDC discovery document URL (shared agent-connector-sdk MCP surface).
OIDC_CLIENT_ID / OIDC_CLIENT_SECRET_REF ✅ Confidential client used for the RFC 8693 token exchange.
OPENSEARCH_KEYCLOAK_CLIENT_ID optional Delegated-token audience. Defaults to opensearch.
OPENSEARCH_TLS_PROFILE / OPENSEARCH_TLS_PROFILE_REF optional Named outbound TLS trust policy.
OPENSEARCHTOOL optional Tool-group toggle (set False to disable the index/search/pipelines/security tools). Default True.
INGESTTOOL optional Tool-group toggle for opensearch_reindex_from_kg. Default True.
MCP_TOOL_MODE optional condensed | verbose | both | intent (inherited from agent-connector-sdk).

MCP Tools

Tool Group Purpose
opensearch_create_index index Create an index (idempotent)
opensearch_update_mapping index Merge field mappings
opensearch_manage_alias index Add/remove/swap aliases
opensearch_get_aliases index Read-only alias inspection
opensearch_update_settings index Update dynamic index settings
opensearch_rollover index Roll a write alias to a new backing index
opensearch_delete_index index Remove an index
opensearch_search search BM25 lexical search (capped at 100 hits)
opensearch_knn_search search k-NN vector search (typed error — plugin disabled)
opensearch_hybrid_search search Lexical + vector hybrid
opensearch_ingest_pipeline pipelines Get/put an ingest pipeline
opensearch_read_dls_rules security Read-only: one role's DLS query
opensearch_apply_dls_bundle security Validate + apply a CA-16/26-rendered bundle
opensearch_reindex_from_kg ingest Trigger-only: records an :IndexingRun node

Documentation

See docs/ for architecture, configuration, and deployment notes, and AGENTS.md for domain-specific traps (the calling-principal invariant, the k-NN-disabled degrade path, and the DLS-bundle-never-hand-authored rule).

Available MCP Tools

Condensed action-routed tools (MCP_TOOL_MODE=condensed)

MCP Tool Toggle Env Var Description
opensearch_apply_dls_bundle OPENSEARCHTOOL Apply a CA-16/26-rendered policy bundle's OpenSearch renderings.
opensearch_ingest_pipeline OPENSEARCHTOOL Read or define an ingest pipeline.
opensearch_reindex_from_kg INGESTTOOL Request a reindex of index_pattern from the KG's current state.

Verbose 1:1 API-mapped tools (MCP_TOOL_MODE=verbose or both)

18 per-operation tools — one per public API method (click to expand)
MCP Tool Toggle Env Var Description
opensearch_apply_dls_bundle_rendering OPEN_SEARCH_APITOOL Apply ONE already-validated renderings.opensearch entry.
opensearch_cluster_health OPEN_SEARCH_APITOOL Invoke the cluster_health operation.
opensearch_create_index OPENSEARCHTOOL Invoke the create_index operation.
opensearch_delete_index OPENSEARCHTOOL Invoke the delete_index operation.
opensearch_get_aliases OPENSEARCHTOOL Invoke the get_aliases operation.
opensearch_get_ingest_pipeline OPEN_SEARCH_APITOOL Invoke the get_ingest_pipeline operation.
opensearch_hybrid_search OPENSEARCHTOOL OpenSearch's native hybrid (lexical + vector) query compound clause.
opensearch_ingest_pipeline__get MUTATINGTOOL Read or define an ingest pipeline.
opensearch_ingest_pipeline__put MUTATINGTOOL Read or define an ingest pipeline.
opensearch_knn_plugin_enabled OPEN_SEARCH_APITOOL Live check of the k-NN plugin's runtime-enabled flag (never assumed).
opensearch_knn_search OPENSEARCHTOOL Invoke the knn_search operation.
opensearch_manage_alias OPENSEARCHTOOL Apply one or more alias actions ({"add": {...}}/{"remove": {...}}).
opensearch_put_ingest_pipeline OPEN_SEARCH_APITOOL Invoke the put_ingest_pipeline operation.
opensearch_read_dls_rules OPENSEARCHTOOL Read one OpenSearch security-plugin role's index permissions/DLS query.
opensearch_rollover OPENSEARCHTOOL Invoke the rollover operation.
opensearch_search OPENSEARCHTOOL Invoke the search operation.
opensearch_update_mapping OPENSEARCHTOOL Invoke the update_mapping operation.
opensearch_update_settings OPENSEARCHTOOL Invoke the update_settings operation.

3 action-routed tool(s) · 18 verbose 1:1 tool(s). Each is enabled unless its <DOMAIN>TOOL toggle is set false; MCP_TOOL_MODE selects the surface (intent default — the six verb-tools, granular set loaded on demand · condensed action-routed · verbose 1:1 · both). Auto-generated — do not edit.


Repository Owners

GitHub followers GitHub User's stars


Contribute

Contributions are welcome! Please ensure code quality by running local checks before submitting pull requests:

  • Format code using ruff format .
  • Lint code using ruff check .
  • Validate type-safety with mypy .
  • Ran test suites using pytest

Deploy with agent-connector-sdk-deployment

Provision this package with the consolidated agent-connector-sdk-deployment workflow. It selects an installed-package, editable-source, or immutable-container path; records only runtime secret and TLS-profile references in AgentConfig; and runs doctor, registration, policy, observability, and rollback gates. Ask your agent to "deploy lucerna-mcp with agent-connector-sdk-deployment".

Install mode Command
Installed package uv tool install "lucerna-mcp[mcp]", then run lucerna-mcp
Immutable container deploy registry.example.invalid/lucerna-mcp@sha256:<digest> through the operator-selected orchestrator

The repository embeds no deployment profile, credential value, certificate path, or environment-specific endpoint. Supply those at runtime through AgentConfig and the configured secret provider.

Governed capability contract

This package ships a compact canonical skill surface with specialist procedures kept as referenced workflows. The current MCP tools, skill metadata, connector_manifest.yml, ontology, mappings, shapes, fixtures, migrations, tool-schema fingerprints, and certification metadata form one versioned capability contract. Validate them together; do not rely on stale tool names or historical per-task skill wrappers.

Runtime endpoints, credentials, certificate trust, tenant identity, retention, and observability policy are deployment inputs and are never packaged values. See Configuration, trust, and privacy before enabling a network transport, connector ingestion, Arbora delegation, or trace export.

Metadata

Release files for lucerna-mcp 0.3.4

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

Source distribution (sdist)

Source distribution for lucerna-mcp 0.3.4
File Size Uploaded Provenance Actions
lucerna_mcp-0.3.4.tar.gz 42.2 kB Without provenance Details for lucerna_mcp-0.3.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for lucerna-mcp 0.3.4
File Interpreter ABI Platform Actions
lucerna_mcp-0.3.4-py3-none-any.whl Python 3 none any Details for lucerna_mcp-0.3.4-py3-none-any.whl

Total release size: 89.1 kB

Release files / lucerna_mcp-0.3.4.tar.gz

Download URL lucerna_mcp-0.3.4.tar.gz
Size 42.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7ba4f983f150d9ccb6795c48e9fffee9680b964c28c458ac6291f2690c2d1333
BLAKE2b-256 checksum
How to use checksums
f5cf5cdf76743d47c844d245b0edd351f56b3f13d716457c693b096fba71319a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / lucerna_mcp-0.3.4-py3-none-any.whl

Download URL lucerna_mcp-0.3.4-py3-none-any.whl
Size 46.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4109589d94669ae4990be861582ae23fe5a0f7a127f2f95aa4ae2eccd1369d4
BLAKE2b-256 checksum
How to use checksums
ffc42be984e68fdd4b3c47f0dd9d1c4b88db7783418a38f228d0a0a589fc72d4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Security for lucerna-mcp 0.3.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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