Inventory

Documentation

Inventory keeps your servers, applications, dependencies, pull requests and todos in one place. This page explains how to set it up. The full endpoint list is in the API reference.

Getting started

  1. Sign in. Inventory has no passwords: enter your email on the sign-in page and open the link we send you. During early access you need an invitation (request access), or an admin of your organization invites you.
  2. Add your servers under Servers → New server: name, provider, location, IP addresses, operating system and notes. Everything except the name is optional.
  3. Add your applications under Applications → New application, with the repository and app URL. On the application page, record where it runs: a server and an environment such as production, staging or a customer name.
  4. Track dependencies: on the application's Dependencies tab, upload a lockfile, or push it from CI (below).
  5. Connect a forge to see pull requests and issues (below), then link repositories on the application's Pull requests & issues tab.
  6. Add todos on the application page. Todos have a status, a priority, an assignee (a member or an agent), markdown notes and a link to a pull request.
  7. Invite your team under Settings → Members. Members can edit servers, applications and todos; admins also manage members, forges and API tokens.

Forge connections

Admins add connections under Settings → Forges. A connection is a base URL (https on the standard port 443, a public address) and an access token. Inventory only reads: it never writes to your forge, so a read-only token is enough and is what we recommend. Tokens are encrypted (AES-256-GCM) with a key that exists only on the server, are never shown again (only the last four characters) and are never logged or returned by the API.

A background job fetches the open pull requests (merge requests) and issues of every linked repository. It uses conditional requests, so an unchanged repository costs one cheap request. CI status and changed files are looked up only when a pull request gets a new commit.

GitHub (github.com and GitHub Enterprise Server)

  • Base URL: leave it empty for github.com. For GitHub Enterprise Server, enter the address you open in the browser, for example https://github.example.com; Inventory uses its API at /api/v3.
  • Token: a fine-grained personal access token (GitHub → Settings → Developer settings → Fine-grained tokens). Under Repository access, choose only the repositories you want to link. Under Repository permissions, set these to Read-only: Pull requests, Issues, Metadata (always required) and Checks (for the CI status of pull requests). Nothing else.
  • Repositories owned by an organization may need the organization to approve fine-grained tokens. Older Enterprise Server versions without fine-grained tokens can use a classic token with the repo scope, but that grants write access, so use a dedicated machine user.

GitLab (gitlab.com and self-hosted)

  • Base URL: leave it empty for gitlab.com. For a self-hosted GitLab, enter its address, for example https://gitlab.example.com, or with a relative URL root https://example.com/gitlab. Inventory uses the API at /api/v4.
  • Token: a personal, group or project access token with only the read_api scope. Group and project tokens need at least the Reporter role to read merge requests and issues.

Forgejo and Gitea (Codeberg, self-hosted)

  • Base URL: the address you open in the browser, for example https://codeberg.org or https://git.example.com. Installations under a sub-path work too, for example https://example.com/forgejo; Inventory uses the API at /api/v1 below it.
  • Token: user settings → Applications → Generate new token, with the scopes read:repository, read:issue and read:user (the last one shows which user the token belongs to). Choose read, not write, for each.

Linking repositories

On an application's Pull requests & issues tab, enter a repository URL (or owner/repo; GitLab: group/subgroup/project) and pick the connection. Several applications can share one repository: with a monorepo path, an application only shows pull requests that change files under that path, and with a label only the issues that carry it.

Not supported

  • Self-signed or private TLS certificates. The forge must have a certificate from a public certificate authority (Let's Encrypt is fine).
  • Plain HTTP. Base URLs must start with https://.
  • Forges on private networks. The hosted Inventory only connects to forges reachable over the public internet via HTTPS. Addresses in private, loopback or link-local ranges are refused (checked on the resolved address, so DNS tricks do not help), and redirects are not followed. If your forge is behind a firewall, allow our outgoing addresses (ask us at hello@metastic.ch).

Dependencies and end of life

Inventory understands Gemfile.lock, package-lock.json and npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock (classic and Berry), go.mod, requirements*.txt, poetry.lock, and the runtime files .ruby-version, .nvmrc, .node-version, .python-version, .go-version and .tool-versions.

A lockfile is parsed when you upload it and then discarded: only package names, versions and the file path are stored. For each public package, Inventory looks up the latest version (RubyGems, npm, the Go module proxy, PyPI) and known vulnerabilities (OSV). Runtime and framework versions (Ruby, Node.js, Python, Go, PHP, Rails, Django, Laravel, PostgreSQL, MySQL, MariaDB, Redis) are matched to their release cycles from endoflife.date. Only the package name and version are sent; the lookups are shared across all users and never reveal which organization uses a package.

Upload in the browser on the application's Dependencies tab, or push from CI with a deploy (or write) token. The path label identifies the file, and uploading an unchanged file is a no-op:

curl -fsS -X PUT \
  -H "Authorization: Bearer $INVENTORY_TOKEN" \
  -H "Content-Type: text/plain" \
  --data-binary @Gemfile.lock \
  "https://inventory.metastic.ch/api/v1/apps/app_…/manifests?path=Gemfile.lock"

In GitHub Actions or GitLab CI, store the token as a secret and run the same command after the tests pass on your main branch. Several files can be sent in one JSON request, see the API reference.

REST API and CLI

Admins create API tokens under Settings → API tokens. A token belongs to one organization and only ever sees its data. Pick the smallest scope: read tokens list and get; agent tokens (for coding agents) also create, claim and update todos, add notes and set PR links, but cannot change apps or servers; deploy tokens (for CI) can only report deploys and upload manifests; write tokens can do everything. Tokens can expire after 1, 7, 30, 90 or 365 days. They are shown once and stored hashed; revoking one takes effect immediately.

export INVENTORY_TOKEN=inv_…
curl -fsS -H "Authorization: Bearer $INVENTORY_TOKEN" https://inventory.metastic.ch/api/v1/apps
curl -fsS -H "Authorization: Bearer $INVENTORY_TOKEN" "https://inventory.metastic.ch/api/v1/todos?assignee=drover&status=open"

Ids are random strings with a type prefix (app_…, srv_…, todo_…); an id of another organization behaves exactly like one that does not exist. The rate limits are 300 requests per minute per token and 600 per minute per organization. All endpoints, objects and an agent walkthrough are in the API reference.

CLI: inv is a small shell script (POSIX sh, curl and jq) for agents and scripts: inv next, claim, show, note, pr, done, release. It reads INVENTORY_API_BASE and INVENTORY_API_TOKEN and is a thin wrapper around the endpoints above. Download it from /cli/inv; the checksum is on Connect your Drover.

Agent assignees

AI coding agents such as Drover can work on your todos. Each organization has a list of agent assignees (by default drover), which admins edit under Settings → Agent assignees. Agent names are suggested in the assignee field, get an agent badge, and get their own filter on the todo list.

An agent with an agent token claims an open todo with POST /api/v1/todos/{id}/claim. Without an assignee in the body, the todo is assigned to the organization's first agent assignee. A claim answers 409 when the todo is no longer open, so two agents never work on the same todo. The agent then posts progress notes, links its pull request and sets the status to done, or gives the todo back to a human with a note.

Your own Drover: Connect your Drover explains the setup step by step and generates a ready-to-paste goal for GitHub, GitLab or Forgejo.

Export and deletion

  • Export: admins download all data of the current organization under Settings → Export and deletion → Download export.json. The file contains the organization, members and pending invites, servers, and per application its deployments with the deploy history, todos with their notes, dependency manifests with packages and runtimes, and repository links. Forge tokens, API tokens (and their hashes or prefixes), invitation links and any encrypted data are never included.
  • Delete an organization: admins open Settings → Delete organization…, which lists what will be deleted, and confirm by typing the organization's name. All its data is deleted immediately, including forge connections with their tokens, API tokens, invitations and memberships. Members keep their accounts.
  • Delete your account: under Your account in the account menu, confirm with your email address. API tokens you created are revoked; servers, applications and todos stay in your organizations without your email. If you are the only admin of an organization, delete it or make another member an admin first.

Deleted data disappears from backups within 30 days. See the privacy policy.