Metadata-Version: 2.4
Name: ingestion-mcp
Version: 0.2.0
Summary: Read-only MCP server for querying Kenda token spend and waste
Project-URL: Homepage, https://kenda.app
Project-URL: Repository, https://github.com/kenda-co/ingestion-mcp
Project-URL: Issues, https://github.com/kenda-co/ingestion-mcp/issues
Project-URL: Changelog, https://github.com/kenda-co/ingestion-mcp/blob/main/CHANGELOG.md
Author: Kenda
License-Expression: MIT
License-File: LICENSE
Keywords: finops,llm,mcp,model-context-protocol,observability,token-usage
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.11
Requires-Dist: mcp<2,>=1.10
Provides-Extra: dev
Requires-Dist: anyio>=4; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# ingestion-mcp

A small, read-only [Model Context Protocol](https://modelcontextprotocol.io) server that lets an
AI host (e.g. Claude Code) answer questions about your **Kenda** token spend and waste straight
from the terminal — _"how much did I spend this week?"_, _"which agent is wasting the most?"_.

It is a **query surface only**: it never captures or writes usage. It reads the token-authed
`/collector/*` endpoints of the Kenda API using the endpoint + token from `~/.kenda/config.json`
(the same ingest token the Kenda collector writes), which resolve the token to its org
server-side — so the terminal needs no browser/Auth0 session.

<!-- mcp-name: io.github.kenda-co/ingestion-mcp -->

## Tools

| Tool | Endpoint | Returns |
|------|----------|---------|
| `kenda_spend_summary` | `GET /collector/summary` | Top-line spend, waste, and health for your org |
| `kenda_waste_by_agent` | `GET /collector/agents` | Per-agent spend and redundant (wasted) dollars |

## Install

```sh
uv tool install ingestion-mcp     # or: pipx install ingestion-mcp
```

The console script `kenda-mcp` runs the stdio server. `uvx ingestion-mcp` runs it without
installing anything.

`uv` and `pipx` are recommended over a bare `pip install` because this ships a command-line
entry point, and `pip` refuses to install into a Homebrew or distro-managed interpreter at all
(`error: externally-managed-environment`, PEP 668). If you only have `pip`, use
`pip install --user ingestion-mcp`. Both `uv` and `pipx` install into `~/.local/bin`, which is
not on `PATH` by default on macOS — if `kenda-mcp` is not found afterwards, that is why.

## Configure

The server reads `~/.kenda/config.json`:

```json
{
  "endpoint": "https://api.kenda.app",
  "token": "kenda_your-ingest-token"
}
```

Only `endpoint` and `token` are required for queries. Both are written for you by
`kenda-collect init` (the Kenda collector) or the Claude Code plugin's `/kenda-setup`. Environment
variables override the file (`KENDA_ENDPOINT`, `KENDA_TOKEN`) for CI and power users.

## Use with your AI host

The server is plain stdio MCP: every host below runs the same one-line command, `kenda-mcp` —
only the config file differs. After registering, ask your assistant: _"what did I spend this
week?"_ or _"which agent is wasting the most?"_.

### Claude Code

`.mcp.json` in the project (or `claude mcp add kenda -- kenda-mcp`):

```json
{
  "mcpServers": {
    "kenda": { "command": "kenda-mcp" }
  }
}
```

### Cursor

`~/.cursor/mcp.json` (all projects) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "kenda": { "command": "kenda-mcp" }
  }
}
```

### Windsurf

`~/.codeium/windsurf/mcp_config.json` ([docs](https://docs.devin.ai/desktop/cascade/mcp)):

```json
{
  "mcpServers": {
    "kenda": { "command": "kenda-mcp" }
  }
}
```

### VS Code (Copilot agent mode)

`.vscode/mcp.json` for one workspace — or run **MCP: Open User Configuration** from the
command palette to register it for all workspaces. Note the key is `servers` here, not
`mcpServers`:

```json
{
  "servers": {
    "kenda": { "type": "stdio", "command": "kenda-mcp" }
  }
}
```

### Codex CLI

`~/.codex/config.toml` (or `codex mcp add kenda -- kenda-mcp`):

```toml
[mcp_servers.kenda]
command = "kenda-mcp"
```

### Gemini CLI

`~/.gemini/settings.json` (or `.gemini/settings.json` in a project):

```json
{
  "mcpServers": {
    "kenda": { "command": "kenda-mcp" }
  }
}
```

### Troubleshooting

If your host reports the server as failed, run the built-in self-test — it works even when
the `mcp` package is broken, and tells you whether the problem is your config, the network,
or the host:

```sh
kenda-mcp --check
```

It prints the version, the config it resolved (token masked), and the result of one live
API call; exit code 0 means the server side is healthy, so the problem is host config.

## Develop

```sh
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
ruff check .
pytest
```

The HTTP query layer is pure stdlib and unit-tested (`tests/test_query.py`); the MCP transport is
driven end-to-end with an in-memory client (`tests/test_server.py`), including a schema-regression
test that pins host-safe tool shapes; the `--check` doctor mode is covered by `tests/test_check.py`.
The `mcp` package is a runtime dependency, so all suites run in CI.

## License

MIT — see [LICENSE](./LICENSE).
