Metadata-Version: 2.5
Name: nimbus-mcp
Version: 0.14.1
Summary: MCP server bridging AI agents to Nimbus BCI pipelines (device-flow login, desktop auto-discovery, or API key)
Project-URL: Homepage, https://github.com/nimbusbci/nimbus-mcp
Project-URL: Repository, https://github.com/nimbusbci/nimbus-mcp
Project-URL: Changelog, https://github.com/nimbusbci/nimbus-mcp/releases
License: NIMBUS MCP SERVER — SOFTWARE LICENSE AGREEMENT
        
        Copyright (c) 2024–2026 Nimbus BCI Inc. All rights reserved.
        
        ================================================================================
        1. OVERVIEW
        ================================================================================
        
        This Software License Agreement ("Agreement") governs use of the Nimbus MCP
        Server ("nimbus-mcp"), including source code, documentation, and tooling
        (collectively, the "Software").
        
        The Software is **proprietary**. Nimbus BCI Inc. ("Nimbus BCI") retains all
        rights not expressly granted herein. Nothing in this Agreement transfers any
        ownership of intellectual property to you.
        
        This Agreement grants rights under **two tracks** that operate in parallel:
        
          - **Section 3 — Non-Commercial License (No-Cost, Self-Executing).**
            Available to anyone meeting the eligibility criteria, with no
            registration, email, or license key required. Use, modification, and
            non-commercial distribution are permitted for Non-Commercial Use.
            Attribution is requested as a community norm (see Section 4) but is
            not a condition of this license.
        
          - **Section 5 — Commercial Licenses (Paid).**
            Required for any use that is not a Non-Commercial Use. Contact
            hello@nimbusbci.com to obtain a commercial license appropriate to your
            use case.
        
        If you do not qualify under Section 3 and have not executed a separate
        written commercial license with Nimbus BCI under Section 5, you have no
        right to use the Software.
        
        ================================================================================
        2. DEFINITIONS
        ================================================================================
        
          - **"Non-Commercial Use"** means use of the Software solely for:
              (a) research, scholarship, or teaching conducted at, or under the
                  auspices of, an accredited academic institution, government
                  research laboratory, or recognized non-profit research
                  organization; OR
              (b) personal learning, hobby, or scientific curiosity, where the
                  Software is not used, directly or indirectly, in or for the
                  benefit of a commercial product, service, or business activity.
        
          - **"Non-Commercial Use"** does not include any activity that is funded
            by, performed under contract for, or intended to produce revenue for a
            commercial entity, including sponsored research with for-profit
            sponsors, internal R&D inside a for-profit company, or product
            development of any kind.
        
          - **"Commercial Use"** means any use of the Software that is not a
            Non-Commercial Use, including without limitation: use inside a
            for-profit company; use in a paid product, service, or SaaS offering;
            internal business operations; sponsored or fee-for-service research;
            consulting; and inclusion in or bundling with a commercial product.
        
          - **"Academic Publication"** means a peer-reviewed paper, preprint
            (e.g., arXiv, bioRxiv), conference proceedings article, thesis, or
            similar scholarly work publicly made available.
        
          - **"Attribution"** means citing the Software in accordance with
            Section 4.
        
        ================================================================================
        3. NON-COMMERCIAL LICENSE (NO-COST, SELF-EXECUTING)
        ================================================================================
        
        Subject to the terms of this Agreement, Nimbus BCI grants you a
        worldwide, no-cost, non-exclusive, non-transferable, revocable license
        to:
        
          (a) install, copy, run, and modify the Software, and to make
              derivative works of it, for Non-Commercial Use;
        
          (b) reproduce, distribute, and publicly post the Software, in whole or in
              part, and your derivative works, **solely for Non-Commercial Use and
              solely at no charge**, provided that each copy or substantial portion
              of the Software:
                (i)   retains this LICENSE.txt file unchanged;
                (ii)  includes all copyright, patent, trademark, and attribution
                      notices present in the Software; and
                (iii) if it is a derivative work, prominently states that it is a
                      derivative of the Nimbus MCP Server and links to
                      https://nimbusbci.com.
        
          Nothing in this Section 3 authorizes distribution for a fee, or any use
          or distribution of the Software that is a Commercial Use.
        
          This license is **self-executing**: no email, registration, license key,
          or proof of affiliation is required to exercise it. Attribution in the
          form of a citation is requested in Section 4 as a community norm, not as
          a legal condition.
        
          Non-commercial patent grant. To the extent that any Nimbus BCI-owned
          patent claims are necessarily infringed by making, using, modifying, or
          distributing the Software as permitted under this Section 3 solely for
          Non-Commercial Use, Nimbus BCI grants you a non-exclusive, worldwide,
          royalty-free, non-transferable, non-sublicensable patent license to do
          so. This patent license does not cover (i) any modification of the
          Software that is not permitted under this Section 3, (ii) any use of the
          Software that is a Commercial Use, or (iii) any combination of the
          Software with other software or hardware where the combination itself
          necessarily infringes a Nimbus BCI patent claim that the Software alone
          would not. If you institute patent litigation against Nimbus BCI (or a
          cross-claim or counterclaim in a lawsuit) alleging that the Software, a
          Nimbus BCI patent, or both directly or indirectly infringe any patent,
          then any patent licenses granted to you under this Section 3 for the
          Software terminate automatically as of the date the litigation is filed.
        
        ================================================================================
        4. ATTRIBUTION AND CITATION (COMMUNITY NORM, NOT A LICENSE CONDITION)
        ================================================================================
        
        Attribution is **not** a contractual condition of the Non-Commercial
        License in Section 3. You do not lose your license by omitting a
        citation. However, Nimbus BCI is a small team and the Software is
        provided at no cost for non-commercial use; **citation is how that work
        is recognized and is therefore strongly requested**, as follows:
        
          (a) Citation in Academic Publications. If you write an Academic
              Publication that uses the Software, reports results produced with
              the Software, or is based on methods reached through the Software,
              please cite it as: "Nimbus MCP Server, Nimbus BCI Inc.,
              https://nimbusbci.com, version <version you used>".
        
          (b) Notice in derivative artifacts. If you publicly distribute a
              derivative work (e.g., a fork, a notebook collection, or artifacts
              produced with the Software), please prominently state "Built with
              the Nimbus MCP Server" and link to https://nimbusbci.com. (This is
              required for distributions under Section 3(b)(iii) above; it is
              requested, not required, for distributions you make under a separate
              written commercial license.)
        
          (c) Retention of notices. You must retain all copyright, patent,
              trademark, and attribution notices present in the Software. This is
              a condition of the license (Section 3(b)(ii)) and survives
              independent of this Section 4.
        
        ================================================================================
        5. COMMERCIAL LICENSES (PAID, SEPARATE AGREEMENT)
        ================================================================================
        
        Any Commercial Use of the Software requires a separate written commercial
        license agreement with Nimbus BCI. Nimbus BCI's commercial tiers describe
        typical offerings; exact terms, fees, and scope are set in the applicable
        commercial agreement you sign.
        
          TIER              TYPICAL USE CASE
          --------------------------------------------------------------------------
          Startup           Companies with less than US $1M annual revenue;
                            single product; standard email support.
          Commercial        Full production rights for commercial applications;
                            unlimited products within the licensed organization;
                            priority technical support.
          Enterprise        Unlimited deployments across the organization; SLA
                            guarantees; on-premise options; custom feature
                            development; training and onboarding.
        
        To obtain a commercial license: hello@nimbusbci.com or
        https://nimbusbci.com/dashboard.
        
        ================================================================================
        6. THINGS YOU MAY NOT DO
        ================================================================================
        
        You may NOT:
        
          1. Use the Software for any Commercial Use without an active commercial
             license agreement under Section 5.
        
          2. Sublicense, rent, lease, sell, resell, or otherwise distribute the
             Software for a fee, in whole or in part. (Distributing the Software
             or your derivative works at no charge for Non-Commercial Use is
             permitted under Section 3; everything else requires a commercial
             license.)
        
          3. Remove, alter, or obscure any copyright, patent, trademark, or
             attribution notices on or in the Software.
        
          4. Institute patent litigation against Nimbus BCI alleging that the
             Software or a Nimbus BCI patent infringes any patent (doing so
             automatically terminates the patent license granted in Section 3, as
             described there).
        
          5. Use the Software in any manner that violates applicable laws or
             regulations, including applicable export-control laws.
        
          6. Use the Software for any life-critical, safety-critical, or
             medical-diagnostic purpose without appropriate regulatory
             clearances.
        
          7. Share, publish, or expose any API keys, license keys, or
             authentication credentials issued by Nimbus BCI.
        
        ================================================================================
        7. INTELLECTUAL PROPERTY
        ================================================================================
        
        The Software, including all code, designs, and implementations, is and
        remains the exclusive property of Nimbus BCI Inc. This Agreement does not
        transfer any ownership rights to you.
        
        ================================================================================
        8. DATA PRIVACY
        ================================================================================
        
        The Software runs locally on your systems and connects to Nimbus BCI
        services that you configure it to use. Nimbus BCI does not collect,
        store, or have access to your research data or subject data through the
        Software.
        
        The Software may transmit to Nimbus BCI servers the authentication
        requests necessary for the features you use (e.g., device-flow login),
        and software version/platform information for compatibility checks.
        
        ================================================================================
        9. WARRANTY DISCLAIMER
        ================================================================================
        
        THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
        
        NIMBUS BCI DOES NOT WARRANT THAT:
          - The Software will meet your specific requirements;
          - The Software will be uninterrupted, timely, secure, or error-free;
          - Any results obtained through the Software will be accurate or reliable;
          - Any errors in the Software will be corrected.
        
        ================================================================================
        10. MEDICAL DEVICE DISCLAIMER
        ================================================================================
        
        IMPORTANT: THE SOFTWARE IS NOT A MEDICAL DEVICE.
        
        The Software has NOT been cleared or approved by the U.S. Food and Drug
        Administration (FDA), the European Medicines Agency (EMA), or any other
        regulatory body for use as a medical device.
        
        The Software is intended for RESEARCH AND DEVELOPMENT PURPOSES ONLY and
        must NOT be used for:
          - Clinical diagnosis or treatment of patients;
          - Medical decision-making or patient care;
          - Any application where failure could result in death or personal
            injury.
        
        ================================================================================
        11. LIMITATION OF LIABILITY
        ================================================================================
        
        TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW:
        
        IN NO EVENT SHALL NIMBUS BCI INC., ITS AFFILIATES, OFFICERS, DIRECTORS,
        EMPLOYEES, OR AGENTS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
        CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING WITHOUT LIMITATION LOSS OF
        PROFITS, REVENUE, OR BUSINESS OPPORTUNITIES; LOSS OF DATA OR RESEARCH
        RESULTS; BUSINESS INTERRUPTION; OR COST OF SUBSTITUTE GOODS OR SERVICES;
        WHETHER ARISING FROM CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY, OR ANY
        OTHER LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
        
        NIMBUS BCI'S TOTAL AGGREGATE LIABILITY SHALL NOT EXCEED:
        
          - **For Non-Commercial Use (Section 3):** One Hundred U.S. Dollars
            (US $100), consistent with the no-cost nature of that grant and with
            the long-standing convention for free-of-charge software.
        
          - **For Commercial Use (Section 5):** The total amount paid by you to
            Nimbus BCI for the Software in the twelve (12) months preceding the
            event giving rise to the claim, or such higher figure as is set out
            in the written commercial agreement executed between you and Nimbus
            BCI. If your commercial agreement specifies a different cap, that cap
            controls and supersedes this Section.
        
        The foregoing caps apply even if a remedy fails of its essential purpose.
        
        ================================================================================
        12. TERM AND TERMINATION
        ================================================================================
        
        This license is effective until terminated. Nimbus BCI may terminate your
        license under this Agreement (whether the Non-Commercial License in
        Section 3 or a commercial license under Section 5) immediately if you
        breach any material term of this Agreement and, where the breach is
        curable, fail to cure it within thirty (30) days of written notice.
        Termination of the patent license under Section 3 occurs automatically
        upon the events specified in Section 3.
        
        Upon termination:
          1. You must cease all use of the Software;
          2. You must destroy all copies of the Software in your possession or
             under your control, except that you may retain verbatim copies
             strictly to support the reproducibility of an Academic Publication
             already published, and except for archival copies you are required
             to keep under applicable law; and
          3. You must certify in writing, if requested, that you have complied.
        
        Termination does not affect the rights of any downstream recipient who
        received the Software (or a permitted derivative work) directly from you
        under Section 3 before the termination event, so long as that recipient
        remains in compliance with this Agreement.
        
        Sections 7 (Intellectual Property), 9 (Warranty Disclaimer), 10 (Medical
        Device Disclaimer), 11 (Limitation of Liability), and 13 (Governing Law)
        survive termination.
        
        ================================================================================
        13. GOVERNING LAW AND JURISDICTION
        ================================================================================
        
        This Agreement is governed by and construed in accordance with the laws
        of the State of Delaware, United States, without regard to its conflict
        of laws principles.
        
        Any disputes arising under this Agreement shall be resolved exclusively
        in the state or federal courts located in Delaware. You consent to the
        personal jurisdiction of those courts.
        
        ================================================================================
        14. EXPORT COMPLIANCE
        ================================================================================
        
        The Software may be subject to U.S. export control laws and regulations.
        You agree to comply with all applicable export laws and not to export or
        re-export the Software to any prohibited countries, entities, or persons.
        
        ================================================================================
        15. ENTIRE AGREEMENT; AMENDMENT; NO RETROACTIVE REDUCTION
        ================================================================================
        
        This Agreement is the entire agreement between you and Nimbus BCI
        regarding the Software and supersedes all prior agreements or
        communications regarding the Software.
        
        Nimbus BCI may amend this Agreement for future releases of the Software.
        The version of the Agreement that ships with the copy of the Software you
        obtained governs your use, unless you obtain a separate written
        commercial license that supersedes it.
        
        **No retroactive reduction.** Nimbus BCI will not, in any future version
        of this Agreement, reduce the Non-Commercial Use rights granted under
        Section 3 for any copy of the Software that you obtained under this
        version. Specifically:
          - The right to install, copy, run, modify, and make derivative works
            of the Software for Non-Commercial Use;
          - The right to reproduce and distribute the Software and your
            non-commercial derivative works at no charge, under the conditions
            of Section 3;
          - The non-commercial patent license described in Section 3;
        
        shall remain available to you for that copy of the Software under the
        terms of this version, even if a later version of this Agreement is more
        restrictive. This is a promise to the community on which the Software's
        adoption depends, and it survives any amendment.
        
        Nothing in this Section prevents Nimbus BCI from changing the license
        terms of *future* releases of the Software.
        
        ================================================================================
        16. CONTACT
        ================================================================================
        
        Nimbus BCI Inc.
        Email:   hello@nimbusbci.com
        Website: https://nimbusbci.com
        Studio:  https://studio.nimbusbci.com
        
        ================================================================================
        
        By installing, copying, or otherwise using the Software, you acknowledge
        that you have read this Agreement, understand it, and agree to be bound by
        its terms.
        
        ================================================================================
        Version: 2.1 (Nimbus MCP Server)
        Last Updated: October 2026
        
        © 2024–2026 Nimbus BCI Inc. All rights reserved.
License-File: LICENSE.txt
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Requires-Python: >=3.10
Requires-Dist: fastmcp>=2.9
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.7
Provides-Extra: sentry
Requires-Dist: sentry-sdk>=2.19; extra == 'sentry'
Provides-Extra: test
Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
Requires-Dist: pytest>=8; extra == 'test'
Requires-Dist: pyyaml>=6; extra == 'test'
Requires-Dist: ruff>=0.6; extra == 'test'
Description-Content-Type: text/markdown

# nimbus-mcp

<!-- mcp-name: io.github.nimbusbci/nimbus-mcp -->

<!-- smithery badge: their /badge/ endpoint 500s platform-wide (2026-10-07); shields.io image + link keeps the badge rendering -->
[![smithery badge](https://img.shields.io/badge/smithery-nimbusbci%2Fnimbus--mcp-2EA043)](https://smithery.ai/servers/nimbusbci/nimbus-mcp)
[![M8ven Verified](https://m8ven.ai/badge/mcp/nimbusbci-nimbus-mcp-1xjm62?variant=verified&v=01611e09ab598e1f20772a0fc6bd1b96)](https://m8ven.ai/mcp/nimbusbci-nimbus-mcp-1xjm62?s=readme)

MCP server that lets AI agents (Claude Code, Cursor, Claude Desktop) build, validate,
run, and analyze Nimbus BCI pipelines — upload their own EEG data, persist pipelines
into studio projects, run multi-configuration experiment campaigns, watch live EEG
sessions, and (explicitly confirmed) start live streaming — through your **local**
Nimbus backend **or the hosted deployment, with one `nimbus-mcp login`**.

## Why nimbus-mcp (October 2026 field)

The BCI-MCP niche grew four other servers in 2026. They are honest,
focused tools — and each covers a slice of what nimbus-mcp does end-to-end:

| Capability | nimbus-mcp | bci-mcp | eeg-mcp | mne-mcp | ephys-mcp |
|---|---|---|---|---|---|
| Build + validate + run BCI pipelines | ✅ 58 tools | — | — | — | — |
| Train on real data (MOABB packs, uploads) | ✅ | — | — | file I/O only | NWB/DANDI |
| Bring-your-own model code (`python_model`) | ✅ local + cloud sandbox | — | — | — | — |
| Benchmark leaderboard + server-side LOSO scoring | ✅ | — | — | — | — |
| Agent-visible figures (PNG content blocks) | ✅ `plots.*` | — | — | ✅ | ✅ |
| Live hardware sessions on a human | ✅ confirm-gated | ✅ | ✅ | — | — |
| Modelless live band powers (focus/relaxation) | ✅ `stream.telemetry` | ✅ | ✅ | — | — |
| Guided subject calibration | ✅ `calibration.*` | — | — | — | — |
| Neurofeedback protocol sessions | ✅ `protocol.*` | — | — | — | — |
| BIDS export (sha256 manifests) | ✅ `bids.*` | — | — | — | — |
| Cluster-aware group statistics | ✅ `stats.grouped` | — | — | — | partial |
| Transport | stdio + hosted HTTP gateway | stdio + HTTP | stdio | stdio | stdio |
| Validation evidence | [arXiv:2610.13894](https://arxiv.org/abs/2610.13894) — parity study, 3 datasets / 6 pipelines / 2 protocols | band-ratio heuristics | — | — | — |

Scope honesty (deliberate non-goals): **no stimulation output** (eeg-mcp's
triple-interlocked `send_stim_event` is genuinely novel; we don't drive
stimulators), **no spike/ephys data** (ephys-mcp covers intracortical
recording — different data plane), **no source localization / full MNE
parity** (mne-mcp is a deep offline MNE wrapper; `plots.*` covers the
figures agents need on Nimbus data).

## Install

```bash
pip install nimbus-mcp   # or: uvx nimbus-mcp
```

(Also installable from the repo: `pip install -e nimbus-studio/mcp`.)

**Zero-hardware demo**: [examples/demo.md](examples/demo.md) — a copy-paste
agent prompt that runs the whole loop (explore → inspect → figures → train →
confusion figure → leaderboard → stats) on public MOABB data, no device.

## Authentication

Three ways to give the server a credential — tried in this order at startup:

1. **`nimbus-mcp login` (recommended — hosted API, no token pasting).** A
   device-code login: the command prints a URL and an 8-character code, opens
   your browser, you approve in Nimbus Studio, and the minted token is stored
   at `~/.nimbus/credentials.json` (0600) and picked up automatically on every
   future start.

   ```bash
   nimbus-mcp login     # options: --api-url URL, --ttl-days 7..90, --name NAME
   nimbus-mcp status    # doctor: credential source, plan, quota, days-to-expiry, live probe
   nimbus-mcp logout    # remove the stored credential
   ```

   After a login, MCP client configs need no secret at all:

   ```json
   {
     "mcpServers": {
       "nimbus": {
         "command": "uvx",
         "args": ["nimbus-mcp"],
         "env": { "NIMBUS_API_URL": "https://nimbus-studio.fly.dev" }
       }
     }
   }
   ```

2. **Desktop app — zero config.** Just have the Nimbus Studio desktop app
   running: its local key file is auto-discovered (macOS `~/Library/Application
   Support/Nimbus Studio/mcp-key.json`, Linux `~/.config/Nimbus Studio/…`,
   Windows `%APPDATA%\Nimbus Studio\…`) and the server talks to the local
   backend at `http://127.0.0.1:8080`. Nothing to paste or configure.

3. **Environment variables (advanced / CI).** `NIMBUS_TOKEN` (a hosted API
   token `nimb_…` minted in Nimbus Studio → Account → API tokens) or
   `NIMBUS_TOKEN_FILE` (a 0600 JSON file `{"token": "…"}` — keeps the secret
   out of process env and MCP configs), or the local pair
   `NIMBUS_MCP_KEY` / `NIMBUS_MCP_KEY_FILE` (must match `MCP_LOCAL_KEY` on a
   local backend — see below). Explicit env always beats files on disk.

**No credential anywhere?** The server still starts — in **setup mode**. Every
tool call returns `{ok: false, setupRequired: true, message, options}` with the
three paths above, so your agent walks you through onboarding instead of the
server crashing. A hosted token rejected mid-session (expired or revoked)
returns the same shape, including how many days ago it expired and a
`nimbus-mcp login` first option.

### Checking who you are

```
account.whoami() → {userId, email, plan: {isPro, pioneerAccess},
            freeRuns: {monthlyLimit, remaining},
            token: {name, expiresAt, daysLeft} | {masked} | null,  # {masked} = gateway header token
            source}                                      # store | env | token_file | header | …
```

Call `account.whoami()` from the agent to see the account, plan, this month's free-run
quota, and (in token mode) the token's days-to-expiry; `nimbus-mcp status` is
the terminal equivalent with a live backend probe.

### What a hosted token means

- **The token IS you.** Requests run under your account: executions appear in your
  studio history and **your plan's quotas and limits apply** — there is no separate
  agent allowance. When the free monthly quota is exhausted, run errors carry the
  upgrade link `https://studio.nimbusbci.com/pricing?reason=mcp-quota`.
- **CPU-only in v0.4.** Token-authenticated runs do not hydrate cloud GPUs.
- **Rotation.** Tokens live at most 90 days (30 by default). Plan changes are
  snapshotted at mint time — after an upgrade, re-login (or revoke and re-create
  the token) to pick up the new plan. An expired token surfaces as setup
  guidance with the day count, not a dead end.

## Requirements (local mode)

- A Nimbus backend running locally: the **desktop app**, or the dev server
  (`cd nimbus-studio/backend-py && python -m nimbus_backend.server.app`) with `DEBUG=1`.
- The backend started with `MCP_LOCAL_KEY=<some-secret>` (never set this on Fly — it is
  refused there).
- Desktop app users: open **Settings → MCP & Agents** — no manual key setup (the app
  creates the key, injects it into its backend, and hands you copy-ready configs).

**No desktop app required.** Acquisition is fully in-backend: a headless local
backend + `nimbus-mcp` can drive real hardware (BrainFlow boards, BrainBit over
BLE, LSL, PiEEG) and synthetic boards, with zero Electron:

```bash
git clone <this repo> && cd NimbusStudio/nimbus-studio/backend-py
pip install -e ".[streaming]"            # brainflow + pyneurosdk2 + pylsl extras
export DESKTOP_LOCAL_BACKEND=true MCP_LOCAL_KEY=<secret> MCP_LOCAL_USER_ID=user_…
python -m nimbus_backend.server.app      # loopback backend with device radios
# another shell: nimbus-mcp against http://127.0.0.1:8080 with NIMBUS_MCP_KEY=<secret>
```

The same `stream.start → stream.telemetry` flow then works with OR without a
trained model (modelless streams report live signal quality + focus/relaxation
indicators).

## Configure the backend

Desktop/dev env (e.g. `backend-py/data/.env` or the dev shell):

```bash
MCP_LOCAL_KEY=choose-a-long-random-string
MCP_LOCAL_USER_ID=user_your_clerk_user_id
DEBUG=1   # dev server only; the desktop app qualifies automatically
```

`MCP_LOCAL_USER_ID` sets the principal the MCP key authenticates as. Set it to your
own Clerk user id (`user_…`) so everything the agent creates — projects, saved
pipelines, executions — appears in your studio UI as yours. Pick one owner and stick
with it: switching the id mid-life splits ownership of agent-created work across two
principals, and neither identity then sees the whole history.

Watchdog default: streaming sessions started through MCP are auto-stopped after
15 minutes with no one watching (every `stream.status` / `stream.telemetry` poll
resets the timer). Pass `idle_timeout_sec=0` to `stream.start` to disable it for a
session.

When enabling `MCP_LOCAL_KEY` on a machine connected to an untrusted network, also set
`HOST=127.0.0.1` on the backend. The `0.0.0.0` default (`settings.host`) applies to the
bare dev server (`python -m nimbus_backend.server.app`), so with it the key would
otherwise be accepted from the LAN; `backend-py/scripts/run_server.py` already defaults
to `127.0.0.1`, and the desktop app pins loopback itself.

## Run the server

```bash
cd nimbus-studio/mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[test]"
NIMBUS_MCP_KEY=choose-a-long-random-string python -m nimbus_mcp
```

Env vars: `NIMBUS_API_URL` (default `http://127.0.0.1:8080`, or the store's
`api_url` after a login), `NIMBUS_TOKEN` / `NIMBUS_TOKEN_FILE` (hosted API
token — see **Authentication**), `NIMBUS_MCP_KEY` (must match `MCP_LOCAL_KEY`),
`NIMBUS_MCP_KEY_FILE` (path to a 0600 JSON file `{"key": "…"}` — the desktop
app's one-click MCP setup writes it; consulted only when `NIMBUS_MCP_KEY` is
unset), `NIMBUS_EXPORT_DIR` (default `~/nimbus-exports`). With none of the
token/key vars set, the login store and then the desktop key file are
auto-discovered; with nothing found, the server runs in setup mode (every tool
returns onboarding guidance).

## Hosted gateway (streamable HTTP)

`nimbus-mcp serve` runs the same 58 tools over streamable HTTP instead of
stdio — for remote MCP clients, registries (Smithery lists URL-based
servers), and browser-side clients:

```bash
nimbus-mcp serve --port 8080   # env: NIMBUS_MCP_HOST/PORT/PATH
```

The gateway binds **127.0.0.1 by default** — exposing it (`--host 0.0.0.0`)
is explicit opt-in; combine that with the per-request tokens below (the
gateway itself holds no credential to gate access with).

The gateway holds **no** credential itself: each request's Nimbus API token
arrives as a header, so one shared deployment serves many users as
themselves. Calls without a header get setup guidance (add the header, or
install locally via `uvx`).

```json
{
  "mcpServers": {
    "nimbus": {
      "type": "http",
      "url": "https://nimbus-mcp.fly.dev/mcp",
      "headers": { "X-Nimbus-Token": "nimb_…  (Account → API tokens)" }
    }
  }
}
```

(A gateway started with `NIMBUS_TOKEN` in the environment uses it as the
fallback for headerless calls — single-tenant self-hosting.)

## Claude Code

```bash
# --env flags go BEFORE the -- separator (everything after it is the literal
# server command, so the after-form would feed --env to python/uvx):
claude mcp add nimbus --env NIMBUS_MCP_KEY=choose-a-long-random-string \
  -- <path-to-mcp-venv>/bin/python -m nimbus_mcp
```

## Cursor / Claude Desktop (stdio)

```json
{
  "mcpServers": {
    "nimbus": {
      "command": "<path-to-mcp-venv>/bin/python",
      "args": ["-m", "nimbus_mcp"],
      "env": { "NIMBUS_MCP_KEY": "choose-a-long-random-string" }
    }
  }
}
```

## Tools (58)

Auth: `account.whoami` (account, plan, quota, token expiry)
Discovery: `catalog.nodes`, `catalog.node_schema`, `catalog.templates`, `catalog.template`, `catalog.datasets`, `catalog.leaderboard`
Data: `data.upload`
Inspect: `data.inspect_dataset`, `data.inspect_file` (EDA: channels, class balance, band powers, PSD)
Build: `pipeline.validate`, `pipeline.validate_node`
Run: `execution.run` (non-blocking), `execution.get`, `execution.list`, `execution.results`, `execution.cancel`
Campaigns: `experiment.run` (non-blocking, 1-25 paced runs), `experiment.get`
Artifacts: `execution.artifacts`, `execution.download_artifact`, `pipeline.export`
Live: `device.list`, `device.test`, `stream.start` (needs `confirm=true`),
`stream.status`, `stream.telemetry`, `stream.stop`
Calibration: `calibration.start` (needs `confirm=true`), `calibration.status`,
`calibration.pause`, `calibration.resume`, `calibration.train`
Neurofeedback protocols: `protocol.validate`/`protocol.save` (versioned specs),
`protocol.start_assignment` (confirm-gated; simulated sources free, live hardware Pro),
`protocol.session_status`/`pause`/`resume`/`stop`, `protocol.export_stats`
(paired pre/post stats + figure + CSV)
Projects: `project.create`, `project.list`, `project.save`, `project.load`
Python: `python.validate` (static contract check for BYO model code — no execution)
Leaderboard: `leaderboard.submit` (BYO python_model → server-side LOSO scoring,
202 + `submissionId`; `track="pretrained_few_trial"` = efficiency track:
100-trial-capped LOSO, torch code must declare `PARAMS_TRAINED`),
`leaderboard.status` (poll one submission, owner-only),
`leaderboard.mine` (your submissions, newest first)
BIDS: `bids.export_dataset` (pack / upload / recording → BIDS-layout zip;
continuous → BIDS-raw, epoched → BIDS-derivatives), `bids.export_execution`
(results bundle: metrics, participants.tsv, protocol, pipeline snapshot)
Plots: `plots.confusion`, `plots.dataset` (psd / topomap / bandpower /
spectrogram), `plots.erp` (per-class butterfly), `plots.leaderboard` (CI
whisker bars, BYO highlighted; `track=pretrained_few_trial` overlays the
classical LOSO baseline side-by-side) — PNG figures the assistant can SEE
Stats: `stats.grouped` (cluster-aware per-subject accuracies across runs:
t-interval + t-test vs chance)

Not sure which pipeline to build? `catalog.leaderboard()` ranks benchmarked pipelines
per dataset (`meanAccuracyPct` desc, 95% CI) under the canonical `within_session`
protocol — agents pick templates by ranking there and pull the winner with
`catalog.template(pipelineId)`.

## Look at your data first (and at your results)

Before building any pipeline, agents can *see* the data: channels, sampling
rate, trial/class balance, per-channel µV stats, canonical band powers, and a
PSD overview — for a public dataset or a file on disk.

> "Inspect BNCI2014_001 subject S01 before we pick a pipeline."

```python
data.inspect_dataset(dataset="BNCI2014_001", subject="S01", mode="all")
# → {channels: {count: 22, names: [...], flatlined: []}, samplingRate: 250,
#    trials: {count: 288, classLabels: [...], classCounts: {...}},
#    channelStats: [...], bandPowers: {...}, psd: {...},
#    computedFrom: {nSamples: ..., sampleStrategy: "stratified_sample_seed42_4_of_20"}}
```

`subject` is required (e.g. `"S01"`; get the list via `catalog.datasets`) and a
comma-list like `"S01,S03"` loads a cohort; `mode` is `training |
evaluation | all`.

The same works for files: `data.inspect_file` picks the source from the path
shape. An ABSOLUTE path reads the file from disk (local backend only —
desktop app / MCP local mode: no upload step, the data never leaves the
machine); a RELATIVE path — the one `data.upload` returns — describes the
uploaded file on ANY backend (hosted or local):

> "Look at ~/recordings/session-01.edf and tell me if the montage is sane."

```python
data.inspect_file(path="/Users/you/recordings/session-01.edf")  # absolute → local file
data.inspect_file(path="uploads/<user>/session-01.edf")         # data.upload path → upload
```

On a hosted backend absolute paths are refused — `data.inspect_file` then returns
guidance (`data.upload` the file and pass the returned path back, or point
the server at a local backend) instead of a dead end.

Why inspect first: **class balance drives stratification** (imbalanced classes
skew accuracy), and **flatlined channels mean a montage/reference problem**
worth fixing before training. And a units caveat: the loader **assumes
volts** — a µV-native CSV reads 1e6x too large; set `unitsScale` (e.g.
`1e-6` with `units: "uV"`) in the pipeline's `custom_data` config when
needed.

The same data — and your results — can be rendered as **PNG figures the
assistant can look at**, not just JSON: `plots.dataset` (PSD / band-power
heatmap / scalp topomap / spectrogram), `plots.erp` (per-class evoked
butterfly — check class structure before training anything),
`plots.confusion` (after a run: which classes are actually confused),
`plots.leaderboard` (CI whisker bars per dataset, BYO submissions
highlighted). `save=true` also writes the PNG into `NIMBUS_EXPORT_DIR/plots/`.

```python
plots.confusion(execution_id="exec_123")               # → image + per-class accuracy
plots.dataset(kind="psd", source="dataset", dataset="BNCI2014_001", subject="S01")
stats.grouped(execution_ids=["exec_123", "exec_124"])  # cluster-aware t-interval + p
```

## Uploading data

Bring your own recordings instead of (or alongside) the public datasets.

> "I have a `.edf` recording at `~/recordings/session-01.edf` — upload it and build
> a pipeline around it."

The agent calls `data.upload(file_path=…)`, which registers the file with the
backend and returns the stored path; that path goes into a `custom_data` node's
config (`{"filePath": "<path>", "format": "edf", …}`) for `pipeline.validate` /
`execution.run` / `experiment.run`. For plain CSV/TSV/TXT without embedded
metadata, pass `sampling_rate` (Hz) — the backend silently assumes 250 Hz
otherwise; `format` overrides extension-based detection.

## Experiment campaigns

One `experiment.run` call = a paced sweep of 1-25 pipelines (at most 2 training
runs in flight) with aggregated metrics, instead of the agent babysitting 25
individual `execution.run` polls.

> "Compare CSP-LDA vs EEGNet on BNCI2014_001 across subjects 1-3."

The agent builds six train graphs, calls
`experiment.run(runs=[{name: "csp-lda-s1", train_graph: …}, …])`, gets an
`experimentId` back immediately, then polls `experiment.get(experiment_id)` until
status is `completed` — per-run status and, at the end,
`aggregates` like `{"kappa": {"mean": 0.61, "std": 0.08, "best": {name, value}}}`
(mean/std/best over completed runs only).

## Working with projects

Agent builds, human inspects. Pipelines the agent saves land in real studio
projects, so you can open the canvas and see exactly what ran.

> "Save this pipeline as a project called 'motor-imagery-baseline' — I'll review
> it in the studio."

`project.create(name)` makes the container, `project.save(project_id,
train_graph)` writes the graph (layout auto-generated, revision conflicts retried
once) and `project.load(project_id)` reads it back for editing or re-running.
With `MCP_LOCAL_USER_ID` set to your user id, the project shows up in **your**
studio project list.

## Watching a live session

While a streaming session runs, the agent can watch its telemetry and tell you
what it sees.

> "Watch my focus session and tell me when signal quality drops."

The agent polls `stream.telemetry(session_id)` — latest prediction, the recent
window, signal quality (`meanChannelQuality`, `snrDb`, `artifactProbability`) and
running stats — and warns when quality degrades. Each poll also resets the idle
watchdog, so a session under active watch is never auto-stopped; an abandoned one
is shut down after 15 minutes.

## Calibrating a subject

Guided calibration turns a person wearing the device into their own training
data: a cue-guided session records labelled trials, and the agent then trains
the subject's own classifier from the recording.

> "Run a 10-trials-per-class MI calibration on my BrainBit, then train my
> personal classifier when it's done."

The five-tool flow (all non-blocking):

```python
# 1. Start (confirm-gated): fetches the paradigm's calibration template
#    (mi / p300 / sart / target_hit), patches in device + trial count, and
#    starts the session. The Studio app shows the cues on its calibration
#    dashboard automatically.
calibration.start(paradigm="mi", trials_per_class=10, confirm=true)
# → {started: true, executionId: "…"}

# 2. Poll: phase (baseline → imagery trials → complete), current trial, cue,
#    progress tally, and an ETA estimate from the timing SSOT.
calibration.status(execution_id="…")
# → {phase: "imagery", currentTrial: {index: 7, total: 20, class: "Left Hand",
#    cue: "← LEFT"}, progress: {trialsDone: 6, …}, estimatedRemainingSec: 105.0, …}

# 3./4. Pacing between trials (cues hold; resume anytime).
calibration.pause(execution_id="…")   # calibration.resume(...) to continue

# 5. When phase == "complete" the snapshot carries the recording:
#    calibration: {uploadId, path, filename, format}. Train from it.
calibration.train(execution_id="…")
# → {trainExecutionId: "…", calibrationUploadId: "…"} → poll execution.get,
#    then execution.results for the metrics (kappa, accuracy, …).
```

`mi` trains on the default `mi_headband_csp_lda` template (CAR → 8-30 Hz
bandpass → CSP → LDA); `p300` / `sart` / `target_hit` have no default train
template — pass an explicit `template_id` (from `catalog.templates`) or your
own `train_graph` to `calibration.train`. Either way the first data node is
rewired onto the recorded upload (`custom_data` source pinned to the
`uploadId`), preserving the template's training config.

`calibration.start` refuses to run without `confirm=true` — like `stream.start`,
the device goes on a human's head; call `device.test` first.

Pro plan required — calibration workflows and custom-data training are
freemium-gated (free-tier requests are 403 by the node policy). Local
`X-MCP-Key` principals pass when the desktop app flags the signed-in Pro
session (`MCP_LOCAL_IS_PRO`); otherwise the node policy applies to them too.

The calibrate→train handoff requires a Postgres-backed backend (hosted or local
dev): a desktop-local session completes and records, but its upload can't be
resolved by MCP train today.

## Safety

`stream.start` refuses to run without `confirm=true` — it connects an EEG device and
starts a live session on a human. The `X-MCP-Key` path is machine-local only
(never accepted on Fly deployments); hosted mode authenticates with a personal
`Authorization: Bearer` token from `nimbus-mcp login` (see **Authentication**
above). Sessions started via MCP are stopped automatically after 15 idle
minutes (see the watchdog note above).
