OpenContextually
The open context layer before the coding agent.
Turns a task into a small, ranked, explainable context package from your repository.
No model · No API key · No network · No database
Works with Claude Code · Cursor · Codex · MCP-compatible agents · custom coding agents
Quickstart · How it works · MCP · Contributing
Discord · Discussions · ContextBench · Ecosystem · Community
Overview
Agents perform better when they receive small, relevant, explainable task context instead of blindly consuming everything.
That’s why we built OpenContextually, an open-source context layer for coding agents. Give it a task, and it identifies, ranks, and explains the context that matters before the agent starts working.
Give it a task:
gctx "fix the authentication bug"
It scans your repository, follows the relationships a keyword search would miss — imports, calls, tests, configuration, documentation — and returns a small, ranked, explainable package of what to look at before acting. No model, no API key, no network call, no database; the same repository and task produce byte-identical output every time.
It is not another coding agent. It is the layer that helps the agent — or you — figure out what it should know before it starts working.
How it works
your task
│
▼
SELECT → FOLLOW → BOUND → CHECK → EXPLAIN
│
▼
small, ranked, explainable context
| Step | What happens |
|---|---|
| SELECT | Score every file against the task — filename, symbols, content |
| FOLLOW | Walk the import graph to reach files that share no vocabulary with the task at all |
| BOUND | Cap what ships to a small, readable package — considering a file is free, delivering one costs the reader |
| CHECK | Run two deterministic checks for config/doc drift and untested symbols |
| EXPLAIN | Every file in the package carries a reason — a filename match, a symbol match, or "called by X" |
The selection itself is local and deterministic — no model decides what matters.
Quickstart
pip install opencontextually
gctx "fix the authentication bug"
No model. No API key. No network. No database. No setup. One dependency. The same repository and task produce byte-identical output every time.
What it looks like
gctx "dependency override not applied in nested routers"
Run from a clone of fastapi/fastapi at
49033471 — this
is the real, unedited output:
dependency override not applied in nested routers
17 relevant · 3122 excluded
fastapi/routing.py called by applications.py
fastapi/applications.py mentions applied
fastapi/param_functions.py called by oauth2.py
fastapi/dependencies/utils.py called by utils.py
tests/test_frontend.py defines record_dependency
fastapi/security/oauth2.py called by utils.py
fastapi/openapi/utils.py called by applications.py
fastapi/exceptions.py called by utils.py
+9 more · --all to list · -v for code excerpts
Excluded: 3122 files
⚠ 48 relevant files dropped -- the result list was already full
1 relevant file with nothing quotable to show
1372 files scanned, not relevant enough
1701 files not scanned (187 binary, 1507 exact duplicate of another file, 7 too large to scan)
Checks run: configuration_discrepancy, test_reference_gap
Two files were reached through imports, not text — --all marks
fastapi/openapi/utils.py and fastapi/exceptions.py ← via routing.py,
the file that actually implements dependency overrides. One doc page shows
up three times, correctly: testing-dependencies.md is genuinely
translated under docs/en, docs/hi, and docs/tr. Every file carries a
reason, and everything excluded is accounted for — including the 205 that
scored relevant but missed the result budget.
Try it yourself
git clone https://github.com/fastapi/fastapi.git && cd fastapi
python -m venv .venv && source .venv/bin/activate # fish: activate.fish
pip install opencontextually
gctx "dependency override not applied in nested routers" # ~2s
Flask clones the same way — gctx "session cookie is not set on redirect"
— in about 0.2s. No model, no API key, no network call; your code never
leaves your machine. Add -v to see the excerpt behind each match.
Already have a project open? Skip the clone:
gctx "where does authentication actually happen?"
gctx "what will break if I change the User model?"
Give it something you're actually working on — you'll know in seconds whether it's right, because it's your code. (More on what to do with a bad result under Help us break it.)
Search finds matches. Context needs relationships.
Search answers "where do these words occur?". That is a different question from "what should be read for this task?".
grep / ripgrep
task ──────────────────► keyword matches
OpenContextually
task ──► direct matches
│
├──► imported dependencies
├──► tests that exercise them
├──► relevant configuration
└──► governing documentation
│
▼
bounded context package
A task like fix the authentication bug can need a file that never
contains the words authentication or bug. OpenContextually starts from
direct matches, follows Python's own import graph, applies repository
boundaries, runs two deterministic checks, and explains every inclusion.
Most of the value, though, is ranking and compression of files search could already find: a grep for sqlfluff's "indentation rule fires on a templated line" matches 415 files; OpenContextually returns 12, each with a reason — reproducible from the corpus below.
Install
pip install opencontextually
Python 3.10+, one runtime dependency. To work on OpenContextually itself:
git clone https://github.com/gammalex-ai/opencontextually
cd opencontextually
pip install -e ".[dev]"
Using it
CLI
| Command | What you get |
|---|---|
gctx "task" |
Ranked files, each with a reason |
gctx "task" -v |
Adds the code excerpt that justified each file |
gctx "task" --all |
Every included file, not just the top slice |
gctx "task" --json |
Full machine representation, for handing to an agent |
gctx "task" --root PATH |
Search somewhere other than the current directory |
gctx is short for GammaLex Context. The same command is also installed
as octx (the original name, kept working) and opencontextually. Flags
compose (-v --all); --json is unaffected by either and is always full
fidelity.
Write tasks the way you'd describe the bug. Naming a specific behavior or symbol beats a directory-shaped noun.
Python
from opencontextually import get_context
package = get_context("fix the authentication bug")
print(package.render()) # the text above
package.to_dict() # the same content as JSON
MCP
Agents that speak MCP can call it directly. Requires the optional extra:
pip install "opencontextually[mcp]"
Point your MCP client at the opencontextually-mcp command:
{
"mcpServers": {
"opencontextually": {
"command": "opencontextually-mcp"
}
}
}
It exposes exactly one tool — get_context(task, root=".") — returning the
same shape as gctx --json.
Tested on real repositories
Scripted tests lock in fixes; they do not find them. Most real defects in
this project were found by running it against unfamiliar repositories and
reading the output, so a standing corpus is part of the project
(benchmarks/, with a runner that also checks determinism and sweeps for
leaked secrets).
What it selected, and what it missed
Fourteen repositories, each with a hand-checked answer key
(benchmarks/answer-keys.json): the files
that actually implement or test the behaviour the task names. Six were used
while tuning ranking. Eight were held out — keys written and committed
before the tool ran against them, nothing tuned afterward.
| Group | Repositories | Key files found | In the default view |
|---|---|---|---|
| Tuned | httpx, requests, flask, click, sqlfluff, django | 18/19 (95%) | 16/19 (84%) |
| Held out | black, rich, pydantic, fastapi, attrs, urllib3, pytest, scrapy | 22/29 (76%) | 19/29 (66%) |
| All fourteen | 40/48 (83%) | 35/48 (73%) |
76% and 66% — the held-out figures — are the ones to argue with: they predict a repository this project has never seen, and the default view (compact output shows eight files) matters more than the total.
Across all fourteen: zero fixture, vendor, generated or CI files selected, and 0.05%–2.1% of repository bytes delivered.
What the held-out repos caught that tuning missed:
- A bundled previous major version. pydantic ships Pydantic 1 inside
Pydantic 2 — six of eighteen slots went to
pydantic/v1/*. Fixed. - Repeated documents. rich's README translations, fastapi's
docs/en/docs/hi/docs/tr— genuinely different pages sharing a filename. Not fixed — a dedup cap was tried and reverted. - Vocabulary collisions. On django, rich ranks
progress.py(ProgressColumn) first for a table-width task. Tracked as issue #3.
The corpus
A 10-repository, timed subset of the fourteen above, reproducible with
benchmarks/dogfood.py:
| Repository | Commit | Files | Time | Task |
|---|---|---|---|---|
| encode/httpx | b5addb64 |
125 | 0.18s | redirect loses the authorization header |
| psf/requests | 5460f467 |
128 | 0.12s | session cookie persists across redirects |
| pallets/click | 36baa15f |
166 | 0.25s | option prompt does not hide the input |
| pallets/flask | d318b683 |
236 | 0.19s | session cookie is not set on redirect |
| psf/black | 8947c48e |
482 | 0.48s | string normalization changes the wrong quotes |
| Textualize/rich | 9d8f9a37 |
553 | 0.63s | table column width ignores the terminal size |
| pydantic/pydantic | f512b087 |
824 | 1.70s | field validator not called on assignment |
| fastapi/fastapi | 49033471 |
3,139 | 2.11s | dependency override not applied in nested routers |
| sqlfluff/sqlfluff | 642e2e4a |
5,955 | 2.18s | indentation rule fires on a templated line |
| django/django | 73cc09f1 |
7,085 | 7.52s | queryset filter drops the second condition |
All ten are MIT- or BSD-licensed, unaffiliated with this project, cloned
--depth 1 on 2026-08-30 at the commits above. 18,693 files total, but
only 16,331 are actually scanned — the rest excluded before reading, mostly
gitignored build output. Zero secret-shaped strings reached any
package; every run was byte-identical across repeats. Times are
best-of-three on an M-series Mac, Python 3.13, warm cache — treat as orders
of magnitude, not a benchmark.
Ecosystem & Community
Works with today
Verified by the test suite and by hand against a clean install — nothing here is aspirational.
| Surface | What it is | Status |
|---|---|---|
gctx CLI |
gctx "task", plus --json, -v, --all, --root |
Supported |
| Python API | get_context(task, root=".") returning a ContextPackage |
Supported |
| MCP server | opencontextually-mcp, stdio, one tool: get_context(task, root) |
Supported — see MCP |
| Any MCP-speaking client | Anything that can launch a stdio MCP server and call one tool | Should work; only the server is tested |
Dedicated integrations
OpenContextually already works with Claude Code, Cursor, Codex, MCP-compatible agents, and custom coding agents through the CLI and MCP.
Dedicated editor extensions, wrappers, and deeper integrations are still
early. --json and the MCP server are both stable, so anything below is
buildable today:
- an editor/IDE extension, or a wrapper for an agent harness (Cursor, Continue, OpenCode, Aider, your own)
- a GitHub Action posting the context package onto an issue's PR
- language support beyond Python's import graph — see GOOD_FIRST_CONTEXT.md
Nothing here yet? Build one. Tell us and we may feature it here.
The question this project is trying to answer
What should an agent know before it acts — and how do we prove it got the right context?
Every claim above is checkable against committed answer keys in ContextBench. Found a wrong-files case, or want to argue with a number? COMMUNITY.md has every way in.
What it deliberately does not do
- Follow imports outside Python. Expansion uses the stdlib
astmodule; other languages get lexical matching only. - Understand your code. Ranking is lexical scoring plus import expansion — weakest when a task's words are also the repo's naming convention, since filename matches then dominate.
- Find problems for you. Two narrow checks flag detectable conflicts — a config value contradicting docs, a symbol no test references — not arbitrary missing context. Quiet by default: zero findings across the six answer-key corpus tasks, one false positive (since fixed) across eleven real repos. A footer always names which checks ran.
- Guarantee secrets stay out of excerpts. Redaction masks secret-shaped keys and high-entropy strings, but it is best-effort pattern matching, not a secrets scanner. See SECURITY.md.
Scope, determinism, and safety
Discovery reads everything under --root minus what git already ignores —
honoring nested .gitignore files, .git/info/exclude, and the global
core.excludesFile, plus an optional .opencontextuallyignore. All
resolved without shelling out to git, so it works in directories that
aren't repositories at all.
Runs are deterministic: the same task and repository produce byte-identical output, which is asserted in the test suite and re-checked by the corpus runner. Nothing is written anywhere, and no network call is ever made.
Help us break it
OpenContextually is early. The most useful contribution right now isn't telling us it works — it's finding where it doesn't.
pip install opencontextually
gctx "the bug you're currently fighting"
Bad result? Bring us the context failure with the task, the files you expected, and the files it actually returned — that's exactly what shapes ContextBench and the next fixes.
Contributing
Bug reports, context failures, ContextBench cases, integrations, language support and documentation fixes are all welcome — CONTRIBUTING.md covers the workflow and the scope boundaries, GOOD_FIRST_CONTEXT.md lists concrete places to start, and COMMUNITY.md is where to find people.
License
MIT
Give your agent better context before it starts working.
pip install opencontextually
gctx "fix the bug"
⭐ Star OpenContextually · Built by GammaLex AI
Metadata
Release files for opencontextually 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| opencontextually-0.2.4.tar.gz | 174.4 kB | With provenance | Details for opencontextually-0.2.4.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| opencontextually-0.2.4-py3-none-any.whl | Python 3 | none | any | Details for opencontextually-0.2.4-py3-none-any.whl |
Total release size: 271.7 kB
Release files / opencontextually-0.2.4.tar.gz
| Download URL | opencontextually-0.2.4.tar.gz |
|---|---|
| Size | 174.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51c3839661c2dc02b78cfa3f985745134a3ff92cc75c6e9a0da5a27c5d7fd01c
|
|
BLAKE2b-256 checksum How to use checksums |
2bd8593ae194832a8a0219f20571ebfbe3e487d95cebe3b0c2ce86df2e71677f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / opencontextually-0.2.4-py3-none-any.whl
| Download URL | opencontextually-0.2.4-py3-none-any.whl |
|---|---|
| Size | 97.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
759caaf14800dc12accd4b1b7ddd5066f63f1da834c48ff03e7ae5198088048b
|
|
BLAKE2b-256 checksum How to use checksums |
15c02ffb5df3578efc8e4ad250a691831872130ad72064e4051d3edaeac18beb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logSecurity for opencontextually 0.2.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for opencontextually-0.2.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.