How to use Flywheel

Add to a graph you don't own

Add a result under a node you can read, find your fork, and decide who can see your addition.

You can add a child under any node you can read without joining its repository. Your addition goes into your fork: a repository the server creates for you on your first addition to that person's repository, then reuses for later additions to its graphs. The original node stays where it is and becomes your node's boundary parent, a parent in another repository. This is different from a branch, which creates a child node.

A node in your fork starts private unless you have added members to that fork. Repository members' roles reach every node in the repository. Linking to someone's graph does not give them access to your addition: the graph's owner sees it under their node only when they can read it. Leave sharing unchanged unless you want to share the new node.

Choose where to work

  • Already inside a local repository? Create and link the node there, then commit locally. The local workflow does not publish anything.
  • Adding directly to a hosted graph? Use the CLI or an MCP agent and let the server choose the repository. Do not clone someone else's repository or ask for membership just to add a node.
  • Want a local copy afterwards? Clone your fork, not their repository.

Web app

Open the parent node to read its content and graph. The canvas's Set as source action followed by a double-click on empty canvas creates a child when you can write the source. The current web branch action can refuse a read-only source with “This shared node is read-only. Branch this node to continue.” If you encounter that refusal, use the CLI or MCP steps below; you do not need repository membership.

After creating the child, open its node URL in the web app to edit it or use Share node to choose its audience. Sharing your addition below explains how to let the original graph's owner see it without sharing an entire repository.

CLI

Read the parent first:

flywheel hosted:node:get "<parent-node-id>" --format=json

can_write: false is expected for someone else's read-only node. Keep its repository_id for the local alternative and its owner_email if you later want to share your addition with that person.

Create your addition without --repository-id:

flywheel hosted:node:create --parent "<parent-node-id>" --title "My result" --format=json

Use --values-file node.json instead of --title for the full node content; see hosted:node:create for the file format. Alternatively, hosted:node:branch creates a child that copies the parent's title:

flywheel hosted:node:branch "<parent-node-id>" --format=json

Both commands return node_id, repository_id, and placement. Report those values from the answer, not by comparing repository IDs:

placementWhere the new node landed
parent_repositoryThe parent's repository, where you hold a write role
forkYour fork of the parent's repository
default_workspaceYour default workspace, for a root created with no parent

The explicit --repository-id forms commit into that named repository; they do not ask the server to choose a fork. Do not use them for this workflow.

Read the new node for its slug_name and actual visibility; creation does not return visibility:

flywheel hosted:node:get "<new-node-id>" --format=json

Report the node, repository, placement and visibility. Do not make the node public merely because its parent is public.

Find shared and public graphs

Unscoped node listings show your own nodes. Request other readable scopes explicitly; --access_scopes accepts a comma-separated list of owned, shared, and public:

flywheel hosted:node:list --access_scopes shared --format=table
flywheel hosted:node:list --access_scopes public --format=table
flywheel graph:get --access_scopes shared --format=json
flywheel graph:get --access_scopes public --filter include:visibility:public --format=json

The node table includes owner_email. Follow node-list pagination and graph next_cursor while has_more is true. A graph read anchored by --node_id "<parent-node-id>" without an access-scope flag already reads every scope you can read. Without a node ID, its default is your own nodes.

Visibility filters narrow the requested scopes; they do not add one. graph:get --filter include:visibility:public alone does not discover other people's public graphs: include --access_scopes public.

MCP agents

Ask your agent to add your result under the node's URL. The bundled skills use this sequence:

  1. Read the parent with flywheel_get_node. can_write: false does not prevent adding a child.
  2. Call flywheel_commit_new_node with the parent's ID in parent_ids, a caller-generated local_temp_node_id, and the full staged_payload. Alternatively, call flywheel_branch_node with the parent's ID and its current revision as expected_revision. Neither request chooses a repository.
  3. Report the answer's node_id, repository_id, and placement: parent_repository means the parent's repository, fork means your fork, and default_workspace means your default workspace. In the flywheel_commit_new_node answer, node_id is inside node while repository_id and placement are top-level fields. Do not infer placement by comparing repository IDs.
  4. Read the new node with flywheel_get_node for its slug_name and visibility, and report those too. Leave sharing unchanged.

If a creation response is lost, retry with the same local_temp_node_id, unchanged content and the same MCP session. The saved answer keeps the original repository and placement.

Inside a local repository

Keep the selected local repository as your destination. Read the hosted parent with hosted:node:get to obtain its repository_id. Inspect repo:status first so your commit does not include unrelated staged work. Then create a node here and link it to the parent there:

flywheel repo:node:create --repo "<repository-path>" --title "My result" --format=json
flywheel repo:lineage:add "<parent-node-id>" "<new-node-id>" --parent-repository-id "<parent-repository-id>" --repo "<repository-path>" --format=json
flywheel repo:diff --repo "<repository-path>" --staged --format=json
flywheel repo:commit --repo "<repository-path>" --message "Add result under readable parent" --format=json

The new node stays in your local repository. Its parent stays in the other repository; repo:lineage:list shows the relationship with boundary: true. A local commit publishes nothing, so it has no hosted visibility or server-decided placement to report yet.

Push only when you want to publish. Agents first show the repo:push --dry-run summary and wait for your approval. Publication checks that you can still read the parent; it never redirects the push into another repository.

Clone your fork

After your first hosted addition, find your fork:

flywheel hosted:repository:list --format=table

Choose the row with kind: fork, your owner_email, and the parent's repository as upstream_repository_id. Its repository_id is also the one returned by creation. Other kinds are default_workspace for your new roots and other for other repositories, including those owned by someone else.

flywheel repo:clone "<your-fork-repository-id>" "<repository-path>" --format=json

Reading a public node does not grant access to clone its whole repository. You can clone your fork because you own it.

Share your addition

Only share when you choose to. To let the original graph's owner see the result, open the new child, choose Share node, and add the parent's owner_email under Collaborators with the Viewer role. Keep the existing people and audience setting. You can instead choose Unlisted for people with the URL or Public for discovery by anyone, if that is what you intend.

An MCP agent must first call flywheel_get_node_sharing, then send the current sharing_mode and all existing collaborators along with the requested change to flywheel_set_sharing_for_node, and confirm the result with another sharing read. The setter replaces the whole policy; omitting existing people removes them.

The CLI's nodes:sharing:set cannot send collaborators. Use the web dialog for named people or when existing collaborators must be preserved, rather than replacing the policy with a CLI call that drops them.

Sharing a node never makes anyone a repository member. It does not let them clone your fork or read your other private nodes. See Repositories for repository-wide membership and access.