Goaltree

io.github.furkanYanteri1Published by GitHub account furkanYanteri1v0.6.2Updated Nov 3, 2026

A multi-parent goal graph where value propagates, so what more things depend on ranks higher

Overview

AI-generated overview

Builds and queries a multi-parent goal graph where value propagates from parents to children, so goals that more work depends on rank higher.

What you can do
  • Create, load and reset a goal graph rooted in one goal, adding goals with multiple parents
  • Link goals to related files and backend artifacts such as database tables
  • List goals ranked by propagated value, and mark or clear the goal currently being worked on
  • Open a local live dashboard that highlights the active goal and files with uncommitted changes
When to use it
Useful when planning work that does not fit a clean hierarchy, such as a feature or bug fix that matters to several initiatives at once, and you want an assistant to build and re-rank that graph while it works in a codebase.
Requirements
Runs locally over stdio as a Python package (goaltree, Python 3.10+), typically installed with the mcp extra and launched via uvx or the plugin. The core engine needs networkx; the dashboard needs the mcp extra. No accounts, API keys or environment variables are declared. Optional LLM-based weighting would need a model provider.
Before you install
The tree auto-saves to a .goaltree folder inside the project root, so add it to .gitignore if it should not be committed. The dashboard runs a local web server on 127.0.0.1 and a hook reports tool names and file paths to it, though commands are not sent. Optional LLM weighting can trigger many model calls per edit and its convergence is unproven. File-to-goal matching is heuristic.

Installation

In SourceWeft

  1. Open Goaltree in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

GoalT (Goal Tree)

A multi-parent, value-propagating goal graph. Concept-stage, open source, looking for people to poke holes in it.

[PyPI] [Python] [License] [Open in Colab]

The idea

Most prioritization tools assume a clean hierarchy: one goal breaks into sub-goals, which break into sub-sub-goals, and so on. Real work rarely looks like that. A feature can depend on two other things at once; a bug fix can matter to three different initiatives for three different reasons. Trees don't capture that. A graph might.

GoalT is a small engine for exactly that:

  • One root goal. Everything traces back to it.
  • Any goal can have multiple children and multiple parents. It's a DAG, not a tree.
  • Every parent distributes exactly 1.0 of value across its children.
  • A goal with multiple parents accumulates value from each of them — so goals that genuinely matter to more things naturally float to the top.
  • Adding a goal only recomputes the part of the graph it affects, not the whole thing.
  • Cycles are rejected explicitly, not silently allowed to loop.

Value redistribution (how a parent splits its value among children) is pluggable. By default it's a simple equal split — deterministic, no API key needed, always converges. You can swap in an LLM to decide weights based on context instead (e.g. "speed matters more than polish this sprint"). The engine never trusts the LLM's numbers directly: whatever comes back gets validated and re-normalized so the graph stays mathematically consistent even if the model returns something odd.

Try it without installing anything

Click the "Open in Colab" badge above. It opens demo.ipynb in your browser, no setup required. Run the cells top to bottom.

Local install

Requirements: Python 3.10+ (the mcp package, needed for the Claude Code server, requires it). If you're on macOS and pip install fails with errors like "Requires-Python >=3.10" or "No matching distribution found for mcp", you likely have more than one Python installed and pip is pointing at the wrong one (common with the Python bundled in Xcode Command Line Tools). Check with python3 --version, and if it's 3.10+, use python3 -m pip install ... instead of a bare pip install ..., which guarantees packages land in the same Python that will actually run the server.

bash
python3 -m pip install goaltree

The core engine only needs networkx. The heavier pieces are extras, so you install what you actually use:

bash
python3 -m pip install "goaltree[viz]"   # + matplotlib, for visualize.drawpython3 -m pip install "goaltree[mcp]"   # + the Claude Code MCP server and dashboardpython3 -m pip install "goaltree[all]"   # everything

Or from source:

bash
git clone https://github.com/GOAL-T/goaltree.gitcd goaltreepython3 -m pip install -e ".[all]"
python
from goaltree import GoalGraph
g = GoalGraph()g.add_root("root", "Ship v2 of the product")g.add_goal("a", "Improve onboarding", parents=["root"])g.add_goal("b", "Improve performance", parents=["root"])g.add_goal("c", "Fix export bug", parents=["a", "b"])  # depends on both
print(g)
GoalGraph(root='root')  1.000  Ship v2 of the product (root)  1.000  Fix export bug (c)  0.500  Improve onboarding (a)  0.500  Improve performance (b)

Note that c lands on 1.000 while the root is also 1.000, and that a, b and c sum to more than the root. That's intentional, not a bug: value is conserved per parent (each parent splits exactly 1.0 among its children), not globally across the graph. A goal serving two parents accumulates from both.

So the number isn't a share of a fixed budget, and comparing it to the root's 1.0 doesn't mean anything. It's a pull-weight: it answers "how much is riding on this," not "what fraction of the project is this." Here, the export bug is load-bearing for both sub-goals, so nothing else in the graph can be done without it mattering — which is exactly what a 1.000 is saying.

See demo.ipynb for the full walkthrough, including the LLM-backed redistribution example.

Use it inside Claude Code

GoalT ships as a Claude Code plugin: an MCP server (build and query a tree in conversation) plus a live dashboard that auto-starts with the server and highlights, in real time, which goal Claude is currently working on.

Install as a plugin (recommended)

First install the server's dependencies once:

bash
python3 -m pip install "goaltree[mcp]"

Then, inside Claude Code:

/plugin marketplace add GOAL-T/goaltree/plugin install goalt@goalt-marketplace

This wires up both the MCP tools and the activity hook automatically. GoalT deliberately never installs packages for you when the server starts: a plugin that runs pip install on startup pulls code from the network outside the repository you just reviewed, and nobody should have to trust a plugin that much. If the dependencies are missing, the server says exactly which command to run instead of installing anything behind your back.

Manual install (no activity hook, still works)

bash
git clone https://github.com/GOAL-T/goaltree.gitcd goaltreeclaude mcp add --transport stdio goalt -- bash "$(pwd)/bootstrap.sh"

This gets you the tools but not the automatic "Claude is currently..." activity pulse -- that part relies on the plugin's hook, which is only registered via the plugin install path above.

Using it

Onboarding an existing codebase: run the /goalt:start slash command in the project you want to plan. Claude explores the repo (README, package manifest, folder structure, database migrations if present), identifies real functional areas, and builds a tree with genuine descriptions -- linking the files and backend artifacts (database tables, edge functions, etc.) it's confident actually implement each goal, rather than fabricating structure.

Starting from scratch, in a Claude Code session:

"Create a goal tree for shipping v2 of our product, with onboarding and performance as sub-goals, and a shared bug fix that depends on both. Show me the priorities and open the dashboard."

Claude calls create_tree, add_goal, and list_priorities, then open_dashboard gives you a URL (http://127.0.0.1:8765) to open in your browser. From there:

  • Watch mode: leave the dashboard open while Claude works. The header shows a live "Claude is currently..." indicator on every tool call -- guaranteed, wired through a Claude Code hook.
  • File-edit highlighting (guaranteed): once a goal has related_files linked, editing one of those files automatically highlights that goal with a glowing green border -- no extra tool call needed, the hook matches the edited path against every goal's related files.
  • Self-reported highlighting (best-effort): for goals that don't map cleanly to specific files, Claude can call set_active_goal with a reason. Best-effort only -- it happens if Claude chooses to call it, not guaranteed.
  • Uncommitted-changes tracking: if project_root was set when the tree was created, a background thread polls git status every few seconds and marks goals with an amber border if any of their related files have uncommitted changes -- independent of whether anything is being actively edited right now.
  • Click any node to open a side panel with two tabs: Description (the goal's description plus its related files/backend artifacts) and Changes (files currently being edited and/or with uncommitted changes, for this specific goal). Clicking a node that's currently active or has uncommitted work opens straight to the Changes tab.
  • Open files in VS Code: every file listed in Related files or Changes is a clickable link (vscode://file/...) that opens it directly in VS Code -- works out of the box if VS Code is installed, no setup needed. Files with uncommitted changes also get a Diff button that opens a proper side-by-side diff (HEAD vs working copy). On macOS this launches VS Code directly (no PATH setup needed, works if VS Code is simply installed); elsewhere it uses the code CLI if it's on PATH. If neither is available, the button tells you exactly what to do instead of failing silently.
  • Drag nodes to rearrange them -- positions stick, they won't snap back on the next update. Click "Reset layout" to let the graph re-lay itself out.

Available tools: load_tree, create_tree, add_goal, link_artifacts, list_priorities, set_active_goal, clear_active_goal, open_dashboard, reset_tree.

Current limitations:

  • The tree auto-saves to <project_root>/.goalt/tree.json on every change and auto-loads on the next session (either a best-effort guess at startup, or reliably via load_tree once Claude knows the actual project root -- the system instructions point it there first). Add .goalt/ to your project's .gitignore if you don't want to commit it.
  • File-to-goal matching (goals_for_file) is a heuristic suffix match, not exact-path resolution -- it can mismatch on ambiguous relative paths in unusual project layouts.
  • Uncommitted-changes tracking assumes a single git repository at project_root and re-polls on a fixed interval (a few seconds), so there's a small lag between a change happening and it showing up.

What's actually in this repo

  • goaltree/goal_tree.py -- the core engine: graph construction, cycle detection, deterministic value propagation, and the pluggable LLM redistribution hook. The only module with no optional dependencies, and the only one re-exported from goaltree directly.

  • goaltree/visualize.py -- a thin matplotlib/networkx wrapper used by demo.ipynb to draw a static graph image. Needs the [viz] extra.

  • demo.ipynb -- an interactive, runnable walkthrough (works in Colab, no local setup).

  • goaltree/mcp_server.py -- the MCP server: tools for building/querying the tree, plus best-effort active-goal tracking. Starts the dashboard automatically on load. Needs the [mcp] extra.

  • goaltree/dashboard.py -- the live, interactive web dashboard (FastAPI + vis-network, single file, no build step), including the hook endpoint Claude Code's PreToolUse hook calls. Needs the [mcp] extra.

  • pyproject.toml -- packaging metadata; also defines the goalt-mcp console script, which is just python -m goaltree.mcp_server under a shorter name.

  • .claude-plugin/plugin.json, .claude-plugin/marketplace.json, .mcp.json, hooks/hooks.json -- plugin packaging so the whole thing installs with two commands (see above).

  • commands/start.md -- the /goalt:start slash command that onboards GoalT onto an existing codebase.

  • bootstrap.sh -- the plugin's actual entry point (see .mcp.json). Finds a Python 3.10+ interpreter at runtime, so no machine-specific path is hardcoded anywhere, checks that the server's dependencies are importable, and refuses to start with a copy-pasteable install command if they aren't. It installs nothing itself, by design.

  • hooks/hooks.json, hooks/pulse.py -- the activity pulse. Claude Code hands a PreToolUse hook the whole tool payload, which for a Write contains the entire file being written; pulse.py projects that down to the tool name and the file path before POSTing it to the dashboard on 127.0.0.1. Commands are never sent, not even a preview, so a shell call shows up as "Running: Bash". Nothing else leaves the hook process.

  • tests/ -- 62 tests covering the core engine, the dashboard's API/hook logic, and the MCP tools end-to-end (via a real MCP client, the same way Claude Code talks to it). See "Running tests" below.

No CLI yet -- a natural next step if there's interest.

Running tests

bash
python3 -m pip install -e ".[dev]"pytest

62 tests across three files:

  • tests/test_goal_tree.py -- the core engine (multi-parent value propagation, cycle handling, artifact linking, file matching, save/load round-trips), no I/O.
  • tests/test_dashboard.py -- pure helper functions, real git fixtures for uncommitted-changes detection, the VS Code diff fallback chain (mocked, no GUI needed), and the FastAPI endpoints via TestClient.
  • tests/test_mcp_server.py -- integration tests: a real MCP client talking to a real goaltree.mcp_server subprocess over stdio, covering the actual tools (create_tree, add_goal, link_artifacts, set_active_goal, load_tree/persistence, reset_tree). Slower (~30s total) since each test spawns a real process, but it's what actually exercises the tool layer Claude Code calls into.

Known open questions

Being upfront about this instead of overselling it:

  • Convergence with LLM-driven weights. The deterministic fallback always converges by construction. Whether repeated LLM-driven re-weighting stays stable across many edits on a large graph hasn't been proven, only observed on small examples.
  • Global value isn't conserved. Because a node can have multiple parents, the sum of all node values in the graph is not 1.0 overall — only locally, per parent, do children's weights sum to 1.0. That's intentional (it's the mechanism that makes "more real dependencies = more pull" work), but worth understanding before reading too much into raw numbers.
  • Cost at scale. With a real LLM plugged in, every add_goal call can trigger one redistribution call per affected parent. On a large, deep graph that could mean a lot of API calls per edit. Caching / batching isn't implemented yet.
  • No benchmark yet. This hasn't been compared against classical prioritization methods (AHP, weighted scoring, plain OKR cascading) on a real backlog. That comparison is a natural next step, not a claim already made.
  • Cycle detection is currently a defensive backstop, not an active safeguard. Through the public add_goal API alone, a cycle is impossible by construction (a new node has no outgoing edges yet). The check matters for a planned future feature — linking two already-existing goals together — where cycles become genuinely reachable.
  • Startup auto-load is a guess, not a guarantee. At server startup, GoalT tries loading a saved tree using its own process's working directory as a guess for project_root -- this works when Claude Code happens to launch the MCP server rooted at the project, but isn't guaranteed. The reliable path is the explicit load_tree tool, which the system instructions tell Claude to call first with the actual project root before assuming no tree exists.
  • Relationship to existing work. The value-propagation mechanism is closely related to PageRank-style algorithms on DAGs. If you know prior art that solves this better, please open an issue — genuinely interested, not trying to reinvent something that already exists.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md. Breaking it is as useful as extending it; if you find a case where the graph produces something wrong or unstable, that's exactly the kind of feedback this needs right now.

License

Apache 2.0 — see LICENSE. Use it, fork it, build on it, commercial or not.

Source: README.md at commit 2165192

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

1
  1. v0.6.2LatestSep 16, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts