Metadata-Version: 2.4
Name: cogitan-mcp
Version: 0.1.0
Summary: MCP server for Fluxus — superconducting quantum design surrogates, as tools an agent can call.
Project-URL: Homepage, https://www.cogitan.ai
Project-URL: Documentation, https://www.cogitan.ai/docs
Author: Cogitan
License: MIT
Keywords: agent,eda,fluxus,mcp,quantum,superconducting,surrogate
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.2
Description-Content-Type: text/markdown

# cogitan-mcp

Fluxus — superconducting quantum design surrogates — as tools an AI agent can
call.

```
agent  <--stdio-->  cogitan-mcp  --cog_sk_-->  api.cogitan.ai/v1/fluxus/*
```

## Install

```bash
pip install cogitan-mcp
```

You need a Cogitan API key. Keys are issued to approved accounts only —
[request access](https://www.cogitan.ai/dashboard/exclusive). The server reads
`COGITAN_API_KEY`, falling back to the key `cogitan login` saved in
`~/.cogitan/config.json`.

### Claude Desktop / Claude Code

```json
{
  "mcpServers": {
    "cogitan": {
      "command": "cogitan-mcp",
      "env": { "COGITAN_API_KEY": "cog_sk_..." }
    }
  }
}
```

## What it exposes

Two free tools and one per function the engine states it can perform:

| tool | quota |
|---|---|
| `fluxus_capabilities` | free |
| `fluxus_routes` | free |
| `fluxus_<function>` | 1 call each |

**Tools are generated at startup from the engine's own capability manifest**,
not hand-written. Two consequences, both deliberate: the tool list cannot drift
from what the API actually serves, and a function Cogitan adds to the manifest
appears here on the next start without a release of this package.

## Why the tool descriptions look like that

An MCP tool description usually says what a tool *does*. These say what may be
**believed** about the answer, because that is the question an autonomous caller
has to settle before it acts on a number:

```
Hamiltonian for one TransmonCross + claw cell.

COSTS 1 CALL from your Fluxus quota.
FIDELITY: surrogate_of_em_solve+exact_hamiltonian
GEOMETRY FAMILY: squadds_transmon_cross — as used by qiskit-metal.
VALIDATION: median 0.30% relative error; p95 0.56%; n=1160;
            reference: HFSS eigenmode (simulated, not silicon)
TRUSTED INPUT ENVELOPE:
  cross_length_um: 100.0 to 400.0
  cross_gap_um: FIXED at 30.0 (any other value is refused)
  junction_lj_nh: unconstrained — sets EJ, not the capacitance
REFUSES WHEN:
  - a swept axis outside its range -> HTTP 422 outside_envelope
  - a single-valued axis changed -> HTTP 422 outside_envelope

IMPORTANT: NOTHING HERE IS VALIDATED AGAINST SILICON.
```

That is in front of the model **while it chooses a tool**, not after it calls
one. An agent driving EDA tooling is dangerous precisely because it will
cheerfully report a number from outside the model's validity envelope, and the
engineer reviewing the transcript cannot tell.

## Refusals are results, not errors

Fluxus refuses rather than extrapolating, and its refusals are structured:

```json
{
  "error": {
    "code": "outside_envelope",
    "field": "cross_length_um",
    "value": 900.0,
    "allowed": { "min": 100.0, "max": 400.0 }
  }
}
```

Those fields are passed through **verbatim**. An agent that receives them can
repair its own call. Rewriting them into prose — "the value you supplied was
invalid" — would destroy the only thing that makes autonomous repair possible,
which is why this server does not do it.

Predictions outside a trained region come back with `abstained: true` and the
analytic oracle's answer rather than a confident guess, and every answer is
stamped with which engine produced it (`value.source`).

## Quota

Access carries a call quota for a period. Discovery is free — charging for the
manifest that says what may be believed would push agents toward calling blind.
Compute consumes one call; a call that fails through our fault does not.

Exhausted quota returns HTTP 429 with `Retry-After` set to the period end, not
402: there is nothing to pay, and "stop until this date" is the only actionable
fact about it.

## The manifest publishes its own bad news

`fluxus_sfq_predict` reports, in the tool description the model reads before
choosing it:

```
  classical_baseline:
    model: gradient-boosted trees on ~26 tabular circuit features, no layout
    ic_margin: 0.006          (surrogate: 0.093)
    bias_margin: 0.003        (surrogate: 0.076)
    verdict: the baseline WINS every schema-derivable head
```

A simpler classical model is roughly an order of magnitude more accurate on
RSFQ margins than the surrogate is. That is stated up front rather than buried,
because an agent choosing a tool on margin accuracy should choose the baseline.
The surrogate's claim is the tasks with no tabular route — layout-derived DRV,
unseen cell types, composite chains (222 held-out chains: 2.08 ps delay RMSE,
99.1% functional match) — not those numbers.

The DRV head reports 100% and immediately says why that is unimpressive:
deterministically solvable by a rule checker, reported as a representation
sanity check.

This is the difference between a manifest and a brochure. If yours only ever
contains good news, it is the second thing.

## Coverage

Tools appear for every function the manifest describes: currently the cQED
functions (`qem`, `qem_cross`, `inv_cross`, `resonator_fr`) and the SFQ
functions (`sfq_predict`, `spice_characterize`). Other routes are reachable
through the REST API but do not appear here until the engine will make a
fidelity and envelope statement about them — listing a tool that cannot be
described that way would undo the point of the design.

## Development

```bash
python -m pytest test_tools_from_manifest.py -q
```

Those tests pin the manifest → tool-description transform: fidelity, envelope,
refusal conditions and the silicon caveat must all survive it, and an absent
validation number must read as absent rather than as zero error.
