Start catching the bugs in your data. The agent harness for real world data work.
Python
2
172 commits
updated Oct 7, 2026
portia
Start catching the bugs in your data.
Named after Portia, the jumping spider that hunts other spiders.
portia is a copilot for data work. Connect it to Snowflake, BigQuery, PostgreSQL or a folder of CSV and Parquet files. It profiles every table, answers your questions about them, draws charts, and builds the tables you ask for one decision at a time. Each decision is recorded in a YAML spec and compiled to dbt-shaped SQL that runs without portia.
The model never reads your data. It has no filesystem and no shell. Every number it tells you was computed by deterministic code, so it works on tables too big to open and every claim it makes can be checked.
If an AI agent is installing this for you, point it at INSTALL.md. It covers the
app and the Claude Code plugin, step by step, with a check after each step.
Requires Python 3.11+, uv and Docker.
git clone https://github.com/Jad1908/portia.git
cd portia
uv sync --extra ui --extra agent --extra graph # add --extra snowflake, bigquery or postgres
docker compose up -d neo4j
Neo4j holds the knowledge graph, which is where column lineage and measured overlaps live. The copilot reads it to work out which table to look at.
The copilot runs on the Claude Agent SDK and
drives Claude Code unmodified: your own install when it is at least as new as the copy the SDK
bundles, else that copy. Set ANTHROPIC_API_KEY, or use a
local model. portia has no sign-in of its own and never reads, stores or forwards
a credential, so usage is billed to your own Anthropic account. Neo4j needs a password:
export NEO4J_PASSWORD=portia-dev
portia is an independent project and is not affiliated with Anthropic.
uv run python -m portia.ui
order_id really unique." "Show me revenue by month."models/ as one .sql per table.To try it on data with known problems, python -m devtools.demodata writes a five-table demo
project to sandbox/demo and devtools/demodata/DEMO.md says what is planted in it.
build --check fails CI when a .sql no longer matches its spec.http://localhost:7474.portia's tools also run in your own Claude Code session, with no window. Install the two commands the plugin starts, then the plugin:
uv tool install "portia[agent,ui,graph] @ git+https://github.com/Jad1908/portia"
claude plugin marketplace add Jad1908/portia
claude plugin install portia@portia
Start a new Claude Code session afterwards. INSTALL.md has the checks, the
warehouse setup and what to do when something goes wrong.
Claude then profiles, queries, charts and records steps through portia, and a hook holds a reply
until it has reviewed what it asked, which is how findings get kept. Charts go to the window:
portia ui --project . opens it and it follows the session within two seconds. With
the window closed Claude says a chart is waiting.
The difference from the app is one you should know. The app's copilot has no file access, so it
cannot read raw data. Claude Code does have file access. The plugin refuses its file tools on
indexed data and on portia's own files, and a shell command is not refused. See
plugin/README.md.
The copilot also runs on a model served on your machine by Ollama or
llama.cpp's llama-server. Pick the provider beside the model in the composer, or pass
--provider to cli.chat. The instructions alone are about 15,000 tokens, so serve at least a
32K context. portia checks before sending and refuses with both numbers if it is smaller.
OLLAMA_CONTEXT_LENGTH=32768 ollama serve # then: ollama pull qwen3:8b
llama-server -hf <org/repo:quant> -c 32768 -np 1 --cache-reuse 256 --port 8081
python -m portia.cli.models list # every provider and its models
python -m portia.cli.models check --provider ollama qwen3:8b
The window can start llama-server for you. On a 16 GB laptop an 8B model takes three to four
minutes on a cold first turn.
The same engine, without the window.
python -m portia.cli.index data # profile files into the catalog
python -m portia.cli.connect add prod ... # add a warehouse connection
python -m portia.cli.chat ask "..." # one exchange with the copilot
python -m portia.cli.run specs/x.yaml # execute one spec
python -m portia.cli.build [--check] # compile every spec to models/*.sql
python -m portia.cli.journal list --spec x # what was asked on the way to one model
python -m portia.cli.history # replay past chats
python -m portia.cli.knowledge --write # rebuild the knowledge graph
uv sync --extra dev --extra agent --extra ui
uv run pytest
uv run pre-commit install
GRAPH_SCHEMA.md describes what you will find in the knowledge graph, with
Cypher recipes. BENCHMARK_EVAL.md is how portia gets measured: the
method, and the tooling under devtools/bench/. See CONTRIBUTING.md before opening an issue.
AGPL 3.0. Use it and change it freely, at home or at work. If you distribute it or run it as a service for others, your version must be published under the same license. The name "portia" and the logo are not part of the license.
Start catching the bugs in your data. The agent harness for real world data work.
Python
2
172 commits
updated Oct 7, 2026
portia
Start catching the bugs in your data.
Named after Portia, the jumping spider that hunts other spiders.
portia is a copilot for data work. Connect it to Snowflake, BigQuery, PostgreSQL or a folder of CSV and Parquet files. It profiles every table, answers your questions about them, draws charts, and builds the tables you ask for one decision at a time. Each decision is recorded in a YAML spec and compiled to dbt-shaped SQL that runs without portia.
The model never reads your data. It has no filesystem and no shell. Every number it tells you was computed by deterministic code, so it works on tables too big to open and every claim it makes can be checked.
If an AI agent is installing this for you, point it at INSTALL.md. It covers the
app and the Claude Code plugin, step by step, with a check after each step.
Requires Python 3.11+, uv and Docker.
git clone https://github.com/Jad1908/portia.git
cd portia
uv sync --extra ui --extra agent --extra graph # add --extra snowflake, bigquery or postgres
docker compose up -d neo4j
Neo4j holds the knowledge graph, which is where column lineage and measured overlaps live. The copilot reads it to work out which table to look at.
The copilot runs on the Claude Agent SDK and
drives Claude Code unmodified: your own install when it is at least as new as the copy the SDK
bundles, else that copy. Set ANTHROPIC_API_KEY, or use a
local model. portia has no sign-in of its own and never reads, stores or forwards
a credential, so usage is billed to your own Anthropic account. Neo4j needs a password:
export NEO4J_PASSWORD=portia-dev
portia is an independent project and is not affiliated with Anthropic.
uv run python -m portia.ui
order_id really unique." "Show me revenue by month."models/ as one .sql per table.To try it on data with known problems, python -m devtools.demodata writes a five-table demo
project to sandbox/demo and devtools/demodata/DEMO.md says what is planted in it.
build --check fails CI when a .sql no longer matches its spec.http://localhost:7474.portia's tools also run in your own Claude Code session, with no window. Install the two commands the plugin starts, then the plugin:
uv tool install "portia[agent,ui,graph] @ git+https://github.com/Jad1908/portia"
claude plugin marketplace add Jad1908/portia
claude plugin install portia@portia
Start a new Claude Code session afterwards. INSTALL.md has the checks, the
warehouse setup and what to do when something goes wrong.
Claude then profiles, queries, charts and records steps through portia, and a hook holds a reply
until it has reviewed what it asked, which is how findings get kept. Charts go to the window:
portia ui --project . opens it and it follows the session within two seconds. With
the window closed Claude says a chart is waiting.
The difference from the app is one you should know. The app's copilot has no file access, so it
cannot read raw data. Claude Code does have file access. The plugin refuses its file tools on
indexed data and on portia's own files, and a shell command is not refused. See
plugin/README.md.
The copilot also runs on a model served on your machine by Ollama or
llama.cpp's llama-server. Pick the provider beside the model in the composer, or pass
--provider to cli.chat. The instructions alone are about 15,000 tokens, so serve at least a
32K context. portia checks before sending and refuses with both numbers if it is smaller.
OLLAMA_CONTEXT_LENGTH=32768 ollama serve # then: ollama pull qwen3:8b
llama-server -hf <org/repo:quant> -c 32768 -np 1 --cache-reuse 256 --port 8081
python -m portia.cli.models list # every provider and its models
python -m portia.cli.models check --provider ollama qwen3:8b
The window can start llama-server for you. On a 16 GB laptop an 8B model takes three to four
minutes on a cold first turn.
The same engine, without the window.
python -m portia.cli.index data # profile files into the catalog
python -m portia.cli.connect add prod ... # add a warehouse connection
python -m portia.cli.chat ask "..." # one exchange with the copilot
python -m portia.cli.run specs/x.yaml # execute one spec
python -m portia.cli.build [--check] # compile every spec to models/*.sql
python -m portia.cli.journal list --spec x # what was asked on the way to one model
python -m portia.cli.history # replay past chats
python -m portia.cli.knowledge --write # rebuild the knowledge graph
uv sync --extra dev --extra agent --extra ui
uv run pytest
uv run pre-commit install
GRAPH_SCHEMA.md describes what you will find in the knowledge graph, with
Cypher recipes. BENCHMARK_EVAL.md is how portia gets measured: the
method, and the tooling under devtools/bench/. See CONTRIBUTING.md before opening an issue.
AGPL 3.0. Use it and change it freely, at home or at work. If you distribute it or run it as a service for others, your version must be published under the same license. The name "portia" and the logo are not part of the license.