Local Terraform infrastructure graph indexer for Constellations
Project description
Constellations
Just as ancient navigators used constellations to understand the night sky, Constellations maps relationships between infrastructure and code into a connected graph that can be explored, queried, and understood. Each resource is a star. Each dependency is a line. Together, they form a local map of the system.
Constellations is local-first. A developer runs one local Neo4j server, indexes one or more repositories into graph snapshots, merges those snapshots when cross-repository relationships matter, and queries the graph through the CLI or MCP.
What It Does
Constellations scans a service or infrastructure repository and creates a graph fragment for that repo.
Current extraction supports:
- Terraform
aws_lambda_function,aws_sqs_queue, andaws_lambda_event_source_mapping - Java Gradle repositories from
settings.gradle,settings.gradle.kts,build.gradle, andbuild.gradle.kts RepositoryandCodeModulenodes for Java modules${ENV_VAR}placeholders in baseapplication.ymlandapplication.yaml- Lambda environment variables from Terraform
- Evidence on nodes and relationships, including file path and line numbers
Current merge behavior can derive cross-repository relationships such as:
SQSQueue -[:TRIGGERS]-> LambdaFunctionLambdaFunction -[:RUNS_CODE]-> CodeModuleCodeModule -[:WRITES_TO]-> SQSQueue
The graph also preserves unresolved references and isolated nodes so users can see where more repo context is needed.
Install
pip install chewy-constellations
For local development in this folder:
pip install -r requirements.txt
Or with Poetry:
poetry install
Core Workflow
- Start Neo4j once on the developer machine.
- Index each service or infrastructure repo into a local graph snapshot.
- Merge indexed snapshots when questions need cross-repo traversal.
- Write the merged graph to Neo4j with
--neo4j. - Run the MCP server and ask questions from an MCP client.
Local Neo4j
Start the local Neo4j server:
constellations start
The bundled Docker Compose setup installs APOC Core for local development and
persists plugin jars under .constellations/neo4j/plugins.
Neo4j Browser:
http://localhost:7474
Default local connection:
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=constellations
Stop the local server:
constellations stop
Index A Repo
Run from a Terraform root or Java Gradle repository:
constellations index
You can also index a path without changing directories:
constellations index --path ../aggregator/wizmo-aggregator-lambda-terraform/terraform
Useful options:
constellations index \
--repo wizmo-aggregator-lambda-terraform \
--graph aggregator-infra \
--service aggregator
Force a repository type when auto-detection is not desired:
constellations index --repo-type terraform
constellations index --repo-type java
index writes repo-local artifacts:
.constellations/resources.json
.constellations/snapshot.json
.constellations/graphs.json
resources.jsonis the raw parsed input model.snapshot.jsonis the Constellations graph fragment with nodes, edges, evidence, and unresolved references.graphs.jsonregisters the snapshot locally and also updates the user-level registry at~/.constellations/graphs.json.--output-dirmust point to the indexed repository's.constellationsdirectory or under~/.constellations; other locations fail without writing metadata.
To index and immediately write that graph fragment to Neo4j:
constellations index --neo4j
Inspect And Review
Inspect defaults to .constellations/snapshot.json in the current directory:
constellations inspect
It can also inspect a repository directory or a snapshot file:
constellations inspect ../aggregator/wizmo-aggregator-lambda-terraform/terraform
constellations inspect ../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json
Use inspection and the generated JSON to review:
- which nodes and relationships were created
- which source files and line numbers support each graph fact
- which references remain unresolved
- which nodes are isolated after merge
- which relationships were extracted directly versus resolved during merge
List registered local and global graphs:
constellations graphs
constellations graphs --local
constellations graphs --global
Assign aliases to registered graphs:
constellations alias wizmo-consumers consumers-code
constellations alias wizmo-consumers-lambda-terraform consumers-infra
Merge For Multi-Repo Questions
Single-repo indexing remains the base workflow. Multi-repo composition happens by merging existing graph snapshots into a derived graph snapshot.
From a workspace directory, merge can discover one-level-deep snapshots:
constellations merge
It looks for:
./*/.constellations/snapshot.json
You can also pass repository directories:
constellations merge \
../api/wizmo-nebula2-terraform/terraform \
../aggregator/wizmo-aggregator-lambda-terraform/terraform \
../aggregator/wizmo-aggregator-lambda
Or pass snapshot files directly:
constellations merge \
../api/wizmo-nebula2-terraform/terraform/.constellations/snapshot.json \
../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json \
../aggregator/wizmo-aggregator-lambda/.constellations/snapshot.json
Or pass registered graph names and aliases:
constellations merge consumers-code consumers-infra --graph wizmo
When --graph or --name is omitted, the merged graph name defaults to:
merged_graph
When --output is omitted, the merged snapshot is written to:
~/.constellations/merged_graphs/<graph>.snapshot.json
Write the merged graph to Neo4j so the MCP server can query it:
constellations merge snapshot1.json snapshot2.json --neo4j
Use a custom graph name when needed:
constellations merge snapshot1.json snapshot2.json --graph wizmo-dev --neo4j
Refresh a previously registered merged graph from the same source snapshots:
constellations merge --refresh merged_graph --neo4j
Merged graphs are registered in the user-level registry:
~/.constellations/graphs.json
They do not create a .constellations/graphs.json in the directory where the
merge command happens to run.
Push An Existing Snapshot
push writes an existing snapshot into Neo4j. Use it when the snapshot already
exists and you do not need to rebuild it.
constellations push
push can also accept a repository directory or snapshot file:
constellations push ../aggregator/wizmo-aggregator-lambda-terraform/terraform
constellations push ../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json
The --neo4j flag is for commands that create snapshots, such as index,
from-json, and merge. The push command is already a Neo4j write.
MCP Server
Run the MCP server against the local Neo4j graph:
constellations mcp --graph merged_graph
If Neo4j contains exactly one Constellations graph, --graph can be omitted.
When multiple graphs exist, pass --graph to avoid ambiguity.
Useful connection options:
constellations mcp \
--neo4j-uri bolt://localhost:7687 \
--neo4j-user neo4j \
--neo4j-password constellations \
--graph merged_graph
Use With Codex
After installing the package and writing a graph to Neo4j, register the MCP server in Codex. Codex starts stdio MCP servers from its config, so the server does not need to be started separately in another terminal.
Add this to ~/.codex/config.toml, or to a trusted project's
.codex/config.toml:
[mcp_servers.constellations]
command = "constellations"
args = [
"mcp",
"--neo4j-uri", "bolt://localhost:7687",
"--neo4j-user", "neo4j",
"--neo4j-password", "constellations",
"--graph", "merged_graph",
]
Restart Codex or start a new Codex session after changing MCP config. In the
Codex CLI TUI, /mcp shows active MCP servers.
The MCP server exposes these tools:
list_graphs: list Constellations graphs currently stored in Neo4j.index_repo: index a local Java or Terraform repository and optionally write the indexed graph to Neo4j.merge_graphs: merge snapshot files, repository directories, registered graph names, or aliases and optionally write the merged graph to Neo4j.graph_summary: summarize labels, edge types, repositories, and unresolved references.find_resources: find nodes by text, label, isolated status, or inferred relationships.ask_graph: answer a natural-language question with bounded Neo4j traversal context.readonly_cypher: run a graph-scoped read-only Cypher query.
It also exposes resources:
constellations://graphs
constellations://graph/{graph}/summary
constellations://graph/{graph}/isolated
constellations://graph/{graph}/inferred
Architecture
For model details, relationship derivation, saved-resource rebuilds, and current scope, see docs/architecture.md.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chewy_constellations-0.1.1.tar.gz.
File metadata
- Download URL: chewy_constellations-0.1.1.tar.gz
- Upload date:
- Size: 39.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
655678f055bc6d81243a16f719791e449784c1b1a48afd02db1ce95449403c3a
|
|
| MD5 |
aef9b7cdcba36271d7d025ccdf12ee3a
|
|
| BLAKE2b-256 |
73ff9d163e7796e703cd4e18ce6f4bdc8fa24e4f76e0fd5febe6aec1658c61fa
|
File details
Details for the file chewy_constellations-0.1.1-py3-none-any.whl.
File metadata
- Download URL: chewy_constellations-0.1.1-py3-none-any.whl
- Upload date:
- Size: 48.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9cf40a54078a77dccfcf88a99192c944eacb70da0c5fdc7cbae855acd1dc4e2b
|
|
| MD5 |
1aaceb15582f2e3ffb4a89dd16642d0f
|
|
| BLAKE2b-256 |
b023b1b0be09945dada0d4bdfab272cf4aac38857ca593d413db8ce6e6bc7135
|