Metadata-Version: 2.4
Name: c3db
Version: 0.2.1
Summary: Terminal + SDK access to the C3DB competition-climbing warehouse, via its hosted MCP server.
Project-URL: Homepage, https://github.com/NGYeung/C3DB
Project-URL: Repository, https://github.com/NGYeung/C3DB
Author: C3DB
License-Expression: MIT
License-File: LICENSE
Keywords: analytics,bigquery,climbing,ifsc,mcp,sports-data,sql
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Database :: Front-Ends
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.10
Requires-Dist: mcp>=1.9
Requires-Dist: pandas>=2.0
Requires-Dist: pyarrow>=14
Provides-Extra: anthropic
Requires-Dist: anthropic>=0.39; extra == 'anthropic'
Provides-Extra: ask
Requires-Dist: anthropic>=0.39; extra == 'ask'
Requires-Dist: openai>=1.40; extra == 'ask'
Provides-Extra: openai
Requires-Dist: openai>=1.40; extra == 'openai'
Description-Content-Type: text/markdown

# c3db

Query the **C3DB competition-climbing warehouse** from your terminal — as raw SQL or from your own
AI coding tool. It's a thin client over C3DB's hosted, **read-only** MCP server: every query is a
single `SELECT`/`WITH`, cost-capped, row-capped, and timed out server-side. Nothing about the vetted
query core is reimplemented here.

```bash
pip install c3db
c3db login                                   # sign in via your browser (one time)
c3db query "SELECT * FROM event_standings WHERE final_rank = 1 LIMIT 5"
c3db connect claude                          # wire the warehouse into Claude Code

pip install "c3db[ask]"                      # natural-language querying (bring your own model)
export ANTHROPIC_API_KEY=sk-ant-…            # your own model key — c3db never sees it
c3db ask "who has won the most World Cup golds in lead?"
```

```python
from c3db import Client

df = Client().query("SELECT athlete_name, count(*) wins "
                    "FROM event_standings WHERE final_rank = 1 GROUP BY 1 ORDER BY 2 DESC")
```

## Commands

| Command | What it does |
|---|---|
| `c3db login` | Sign in through your browser to mint + store a `c3db_…` key (`~/.config/c3db/config.json`, 0600). `--paste` to paste a key instead (headless/SSH). |
| `c3db query "<sql>"` | Run a read-only query. `-f file.sql` or stdin for the SQL. At a terminal, small results (≤50 rows) print and you're offered a download; big ones show a summary and suggest saving. `-o out.csv` (or `.parquet` / `.json`) saves straight to a file; `--format table\|csv\|json` writes to stdout for pipes. |
| `c3db ask "<question>"` | Plain-English → SQL → rows, using **your own** model. `--provider`, `--model`, `--base-url`, `--show-sql`. Needs `pip install "c3db[ask]"`. |
| `c3db connect claude\|cursor` | Register the hosted MCP into your AI tool so its model can query the warehouse. `--scope user\|local\|project`. |
| `c3db schema` | Print the query conventions + authoritative BigQuery DDL. |

## Natural language — bring your own model

`c3db ask` and `Client().ask()` are **bring-your-own-model**: your own LLM reads the warehouse
schema and writes the SQL; c3db validates and runs it. c3db never sees or pays for your model key
— it's separate from the `c3db_…` data key. Install a provider and set its key:

```bash
pip install "c3db[anthropic]"    # or "c3db[openai]", or "c3db[ask]" for both
export ANTHROPIC_API_KEY=…       # Anthropic (default: claude-sonnet-5 — plenty for NL→SQL)
export OPENAI_API_KEY=…          # OpenAI-compatible; add C3DB base url / --base-url for DeepSeek/GLM/local
c3db ask "top 3 nations by lead World Cup wins since 2020"
```

**Already use Claude Code?** Then Claude needs *no key at all* — if you've run `ant auth login`
(or Claude Code is set up), `c3db ask` picks up that OAuth login automatically. Just
`pip install "c3db[anthropic]"` and ask.

Provider auto-detects (Anthropic by default — including via that OAuth login; override with
`--provider`); `--model` picks the model. `Client().ask(q)` returns a DataFrame with the generated
SQL on `df.attrs["sql"]`.

## The two kinds of access

- **Raw SQL** (`c3db query`, `Client().query()`) — you write the SQL; c3db runs it and hands back rows.
- **Your own AI** (`c3db connect`) — your AI tool's model reads the schema and writes the SQL itself,
  then runs it through the same server. This is **bring-your-own-model**: c3db never sees or pays for
  your AI subscription; it only issues the `c3db_…` data key that identifies you to the warehouse.

## Results, limits & bulk data

A query returns up to **50,000 rows** to the client (add a `LIMIT` for more than the default 1,000; the
scan is capped at 2 GB and 60 s regardless). Save results locally as **csv / parquet / json**. The AI
path (`c3db connect`) only sees a ~50-row preview plus the true row count — your model answers from that
and points you here for the full data. For the **whole raw dataset** (bulk), self-serve download is
coming; for now email **yvonnelau.work@gmail.com**.

## Config

Resolved in order: environment → `~/.config/c3db/config.json` → built-in default.

| Variable | Meaning |
|---|---|
| `C3DB_API_KEY` | Your `c3db_…` data key (overrides the stored one). |
| `C3DB_SERVER_URL` | MCP endpoint (defaults to the hosted service). |
| `C3DB_CONFIG_DIR` | Override the config directory (default `~/.config/c3db`). |

`c3db login` mints your key self-serve (sign in on the C3DB site → the key is created and stored
locally). No key is typed at the terminal. Manage or revoke keys any time at the site's login page.
