Metadata-Version: 2.4
Name: lumoz-mcp
Version: 0.1.2
Summary: Lumoz MCP server for observability data, detections, errors, and problem/RCA investigation and resolution
Author-email: Lumoz AI <support@lumoz.ai>
Project-URL: Homepage, https://lumoz.ai
Keywords: mcp,observability,rca,lumoz
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: mcp<2.0.0,>=1.0.0
Requires-Dist: requests>=2.28.0
Requires-Dist: python-dotenv>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pre-commit>=3.0.0; extra == "dev"

# Lumoz MCP Server

MCP server for Lumoz observability data and RCA resolution reporting. Connect
it to Claude, Cursor, GitHub Copilot, Codex, or any other MCP-compatible
client to query traces, signals, and problems, and to drive RCA generation
and fix reporting directly from your AI tool.

## Getting an API Key

1. Log in to the [Lumoz console](https://console.lumoz.ai).
2. Go to **Settings → API Keys** (org admin required).
3. Click **Create Key**, name it (e.g. `MCP - my laptop`), and save it.
4. Copy the key shown as `client_id:client_secret` — you won't be able to see
   the secret again after closing the dialog.

The default scopes granted (`read:telemetry`, `write:telemetry`) are
sufficient for every tool in this server, including the ones that write RCA
feedback and fix reports.

## Claude / Cursor / Codex / Copilot Config

Requires [`uv`](https://docs.astral.sh/uv/getting-started/installation/)
installed locally — `uvx` runs the server without a separate install step.

```json
{
  "mcpServers": {
    "lumoz": {
      "command": "uvx",
      "args": ["lumoz-mcp"],
      "env": {
        "LUMOZ_API_KEY": "client_id:client_secret"
      }
    }
  }
}
```

Paste in the key from the step above and you're done — the server talks to
Lumoz's production API by default. Add this block to your client's MCP
config file (e.g. Claude Desktop's `claude_desktop_config.json`, or the
equivalent settings file for Cursor/Copilot/Codex), then restart the client.

## Tools

- Data: `list_services`, `list_traces`, `get_trace`, `get_trace_spans`
- Signals: `list_signal_definitions`, `list_signals`, `get_signal`, `list_traces_for_signal`, `list_trace_signals`
- Errors: `list_trace_errors`
- Problems: `list_problems`, `get_problem`, `list_problem_signals`, `generate_rca`, `report_fix`, `submit_problem_feedback`
- RCA: `list_rcas`, `get_rca`, `submit_rca_feedback`

## Inventory Discovery

Use `list_services()` without an `environment` argument to discover all service
and environment combinations visible to the authenticated tenant. Omitting
`environment` is intentional: it does not fall back to `LUMOZ_ENVIRONMENT`; it
returns every service row across all environments.

Hosts should call this first when they need valid `service_id` and `environment`
values:

```json
{}
```

Each returned service row includes `service_id`, `service_name`, and
`environment`. Pass `environment` only when you want to filter inventory to one
environment. `include_summary=true` is the exception: summary metrics require a
specific environment.

## Signal Discovery

Use `list_signals(service_id, environment)` to discover valid `signal_key`
values. Signals are backed by classifier results, but hosts should use the
signal vocabulary in tool calls.

Common flows:

```json
{
  "service_id": "123",
  "environment": "prod"
}
```

- `list_traces_for_signal(service_id, signal_key="error_detection")` lists
  traces where the error signal fired.
- `list_traces_for_signal(service_id, signal_key="workflow_anomaly")` lists
  traces matching the workflow anomaly signal.
- `list_trace_signals(service_id, trace_id)` lists all signals attached to one
  trace.
- `list_trace_errors(service_id, trace_id)` lists error signals and error spans
  for one trace.

Use `list_signal_definitions()` to look up what a `signal_key`/`classifier_key`
actually means — each row has a human-readable `description`, `category`
(`builtin` or `custom`), `match_type`, and `polarity`. It returns the full
catalog (built-in signals plus this tenant's custom ones), not just signals
that have fired, so call it whenever a problem, RCA, or signal result
references a `signal_key` you need to explain to a user, e.g. while writing up
or acting on `get_rca` output. Pass `service_id`/`environment` to narrow custom
signals to one service/env; built-ins are always included.

Built-in signals also break down into `subtypes` — the specific sub-reason a
signal fired (e.g. `loop_detection` → `exact_tool_call_loop`,
`retry_storm_loop`, `reason_act_thrash`), each with its own `description` and
`default_severity`. `subtype_source_field` names which field on the signal
record (`primary_subtype` or `primary_event_key`) holds the value to match
against a subtype's `key`. When a signal record has a subtype, quote that
subtype's description instead of the classifier's general one — it explains
the actual mechanism, not just the category.

## Problem and RCA Discovery

Problems are groups of detected trace signals sharing the same signature.
Drill down progressively:

1. `list_problems(service_id, environment)` — paginated, newest-first, each
   row includes a `latest_rca` summary if one has been generated.
2. `get_problem(service_id, problem_id)` — full detail, including every
   generated RCA (`rcas`) and the lifecycle/feedback audit trail (`events`).
3. `get_rca(rca_id)` — the complete RCA writeup (root cause, evidence
   pattern, recommended fixes), plus the trace `signals` it covers and its
   own feedback/lifecycle audit trail (`events`).

`list_rcas(service_id, environment)` browses generated RCAs directly, across
all problems, without going through `list_problems` first.

If a problem has no RCA yet, `generate_rca(problem_id)` creates one (or
returns the existing one if already generated).

## Problem and RCA Feedback

`submit_problem_feedback` and `submit_rca_feedback` record a `thumbs_up` or
`thumbs_down` vote (optionally with `note`/`reason`) against a problem or an
RCA, respectively:

```json
{
  "service_id": "123",
  "rca_id": "rca-1",
  "environment": "prod",
  "vote": "thumbs_down",
  "reason": "Recommended fix didn't address the root cause."
}
```

## RCA Fix Reporting

`report_fix` marks an existing problem resolved and records the fix
description. This is one-way — there is no unresolve/reopen action:

```json
{
  "service_id": "123",
  "problem_id": "problem-1",
  "environment": "prod",
  "description": "Added timeout handling around vector search fallback."
}
```

## Troubleshooting

- **`environment is required, or set LUMOZ_ENVIRONMENT`** — normal the first
  time you use a service: call `list_services()` to find a valid
  `service_id`/`environment` pair, then pass `environment` on the call, or
  set `LUMOZ_ENVIRONMENT` if you always work in the same one.
- **Client doesn't pick up the server after editing config** — most MCP
  clients only read their config file at startup; fully restart the client,
  don't just reload a window.

