See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
The exact scope, per provider
GitHub: a fine-grained personal access token scoped to the single repository, with the repository permission Contents set to Read-only. GitHub adds Metadata Read-only automatically, and that pair is the entire requirement. A classic token with the repo scope also works but carries write access, so it is the worse choice for a read-only integration.
GitLab: a personal access token with the read_api scope. That is what covers listing branches and tags, listing the repository tree, and reading raw file contents on gitlab.com.
Azure DevOps: a personal access token with Code set to Read, documented by Microsoft as vso.code, for the organization that owns the project. It is presented as basic authentication with an empty username, which is the shape the API expects.
Public repositories on all three hosts need no token at all. The connection simply reads what anyone can read.
Provider Scope Public repo
github Contents: Read-only no token
(fine-grained, one repo)
gitlab read_api no token
azure_devops Code: Read no tokenWhat happens to the token after you paste it
It is validated immediately, by listing the branches and tags of the repository. That is the cheapest call that proves both that the credential works and that it can see this specific repo, so a wrong scope fails at connect time instead of failing silently at the first sync three hours later.
It is then encrypted at rest with AES-256-GCM under a key derived by HKDF-SHA256 with an info string reserved for repository tokens, so it is not the key that protects the rest of the application secrets. The stored blob is base64 of a 12-byte random initialization vector, the ciphertext, and the 16-byte GCM authentication tag, which means a tampered or wrong-key value fails loudly at decrypt instead of yielding bytes that would then be sent to a provider as a header. Only the last four characters ever come back to the interface, and error messages are built from URL paths and HTTP status codes alone, so a token cannot end up quoted in a log line or an API response.
Every other stored credential in the product is a one-way SHA-256 hash. Provider tokens are the exception because they have to be replayed to GitHub, GitLab, or Azure DevOps on every fetch, which is exactly why they get their own key derivation rather than riding along with the rest.
Deleting a connection removes the stored token and all of the diagrams linked through it, while every project survives with its last synced content. Rotating is the same shape: revoke at the provider, create a fresh token with the same scope, and reconnect.
It never writes
What actually leaves the repository
Not the whole repo. The reading step selects up to 40 files and 250KB in total, in priority order: infrastructure as code, containers and orchestration, data definitions, API specs, CI pipelines, dependency manifests, then prose. Each class carries its own ceiling on top of that, 12 infrastructure files, 12 deployment manifests, 10 API definitions, 8 CI pipelines, 8 dependency manifests and so on, so no one class can spend the whole budget. Files past 30KB are truncated with a visible marker and anything over 400KB is skipped outright. Lockfiles are dropped by name, and node_modules, vendor, dist, build, .next, target, .terraform, coverage, __pycache__ and virtual environment directories are never walked.
What comes back is a diagram and an architecture.md grounded in those files. The generated doc is instructed to state that a section is unanswered rather than fill it in, which is what makes it reviewable against the repo it came from.
There is also a path where nothing leaves the repository at all. Over MCP, your coding agent reads the code locally and sends only the structure it chose to draw, node names, zones, and edges, because no tool in the server accepts source files. Teams that cannot connect a repository at all often run that path instead, and the two land on the same canvas.
The two failure states, and what each one means
A connection that turns to auth_failed means the provider rejected the credential: revoked, expired, or missing the read scope. The fix is a fresh token with the exact scope above, entered on the connection.
A connection that turns to not_found means the provider says no such repository exists for this token. On GitHub that is usually a fine-grained token that was not granted access to this particular repository, since fine-grained tokens list their repositories explicitly. It also covers a renamed repo, a deleted one, and the case where a public repo went private while the connection had no token at all.
Neither state touches the existing diagram. A failed sync leaves the previous canvas exactly as it was, and the error is shown with the link so the reason is visible next to the thing that stopped updating.
FAQ
What is the minimum GitHub permission needed to diagram a private repo?
Is my source code stored?
How is the access token protected at rest?
What happens if I revoke the token at the provider?
Can I get a diagram without connecting the repository at all?
Does deleting the connection delete my diagrams?