Metadata-Version: 2.4
Name: qvasa-mcp
Version: 0.1.0
Summary: MCP server that exposes the Qvasa user-access agentic API to Claude.
Author: Qvasa
License: Proprietary
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# qvasa-mcp

MCP server that exposes the Qvasa user-access agentic API to Claude.

This is a thin proxy: Claude sends MCP tool calls over stdio, the server translates each call into one or more HTTP requests against the Qvasa Rails app, and returns the result. It owns session lifecycle (login, refresh on 401 SessionStale, two-token auth) so Claude doesn't have to.

Rails counterpart: `one_qvasa_app` repo, namespace `/user_access/api/*`. The toolkit version constant lives at `app/services/user_access/api/toolkit_version.rb`.

## Configuration

Set these env vars (Claude Desktop injects them from the `.mcpb` config block on install):

| var | required | default | purpose |
| --- | --- | --- | --- |
| `QVASA_API_KEY` | yes | — | A user-access token (UAT). Generate at `/user_settings/user_access_tokens` in the Qvasa UI. Format `qva_uat_…`. |
| `QVASA_API_BASE_URL` | no | `https://qvasa.com` | Override for staging or local dev (e.g. `http://localhost:3000`). |

## Local dev

```sh
python3 -m venv .venv
source .venv/bin/activate
pip install -e '.[dev]'

export QVASA_API_KEY=qva_uat_…
export QVASA_API_BASE_URL=http://localhost:3000

# Run the server (it will read MCP requests on stdin, write responses on stdout).
qvasa-mcp

# Run the tests.
pytest
```

## Tool list (17 total)

**Orientation**
- `qvasa_overview` — call this FIRST. Returns positioning, intent triggers, intent-keyed workflows, a feedback guide, and the cached session manifest. One call per session; no HTTP round-trip after the first.
- `qvasa_submit_feedback` — frictionless channel for filing bug reports, feature requests, friction points, unexpected_behavior notes, and impossibility reports back to Qvasa engineering.
- `qvasa_search_saved_widgets` — search the user's personal-dashboard saved queries (the agent's memory layer). Call BEFORE rebuilding a metric from scratch.

**Discovery — widgets** (unified: search by phrase, browse a group, or list all groups)
- `qvasa_search_widgets` — pass `query` to search (strict → fuzzy fallback), `group_name` to browse a group, or neither for the groups manifest.
- `qvasa_describe_widget` — bulk schema fetch (widget_type, component_configurations, inspect block).

**Discovery — filters** (unified: same shape as widgets)
- `qvasa_search_filters` — pass `query` to search (strict → fuzzy fallback), `group_name` to browse a group, or neither for the groups manifest.
- `qvasa_describe_filter` — bulk schema fetch.

**Filter values & date range**
- `qvasa_search_filter_values` — value/parent-record search across 19 filter kinds.
- `qvasa_search_values_across_attributes` — reverse-lookup a value across static attributes.
- `qvasa_resolve_date_range` — unified date-range tool. Pass `phrase` for natural-language resolution (e.g. 'yesterday', 'last 7 days') or `strategy` for explicit construction.
- `qvasa_search_component_configuration_values` — value lookup for widget component_configuration_* fields (9 endpoints).

**Metric execution**
- `qvasa_query_metric` — kickoff + block-until-done across all 5 chart types (quick_stat, basic_chart, donut_chart, multi_data_chart, heat_map)
- `qvasa_inspect_metric` — same pattern but materialises a TicketSet (quick_stat / basic_chart / donut_chart only)
- `qvasa_list_in_flight` — show queued/processing metric requests
- `qvasa_cancel_metric` — cancel an enqueued request

**Ticket sets** (drill-down on inspect results)
- `qvasa_describe_ticket_set` — show set metadata + tools_available
- `qvasa_get_ticket_set_summaries` — paginated AI ticket summaries
