GitVelocity CLI
Overview
The GitVelocity CLI (gv) is a thin command-line client over the MCP Server. Same tools, same auth, same payloads — but driven from the shell, where you can pipe it through jq, loop it, and run it from CI. It hits the same /mcp endpoint and authenticates with the same OAuth flow, so every read-only tool you can call from Claude is also a gv subcommand.
Install
brew install headlinevc/tap/gitvelocity
gv version
Prebuilt binaries for Windows and air-gapped installs are also published on the dist repo's Releases page.
Quick start
gv auth login # opens browser, OAuth + PKCE loopback
gv auth whoami --pretty # confirm who you are and which org
gv tools --pretty # list every available tool
gv get_dashboard_overview --pretty # run a tool
Tools are called by name. Pass arguments as one JSON object with --json '{...}', or as per-property flags:
gv get_engineer_velocity --json '{"username":"alice","days":30}'
gv get_engineer_velocity --username alice --days 30
Authentication
The CLI authenticates against the MCP server with OAuth 2.0 authorization_code + PKCE (S256). Running gv auth login opens your browser and starts a loopback listener on an ephemeral local port; once you sign in and pick an organization, the callback completes and the token is captured.
Tokens are stored in your OS keyring — macOS Keychain, Windows Credential Manager, or libsecret on Linux — falling back to a 0600 file when no keyring is available. Dynamic Client Registration (RFC 7591) means no admin has to mint a client_id for you; the CLI registers itself.
| Command | Purpose |
|---|---|
gv auth login |
Browser OAuth flow; stores tokens in the keyring |
gv auth whoami |
Show the authenticated user and organization |
gv auth refresh |
Refresh the access token without re-authorizing |
gv auth logout |
Remove stored tokens from the keyring |
Configuration
The CLI reads configuration from environment variables. It also loads ~/.env on startup, so you can keep these there instead of exporting them per shell.
| Variable | Default | Purpose |
|---|---|---|
GV_URL |
https://gitvelocity.dev |
Base URL of the GitVelocity instance to talk to |
GV_TOKEN |
(none) | Pre-minted MCP token for CI / non-interactive use — bypasses the browser flow |
GV_CLIENT_ID |
(none) | Pre-registered OAuth client ID (skip DCR); requires GV_OAUTH_PORT |
GV_OAUTH_PORT |
(ephemeral) | Pin the loopback callback port instead of using a random one |
Non-interactive / CI
For CI and other non-interactive contexts, set GV_TOKEN to a pre-minted MCP token and run any tool directly. No gv auth login, no browser, no keyring:
GV_TOKEN=<mcp-token> gv get_dashboard_overview --pretty
Available tools
The CLI exposes the same read-only tool set as the MCP server. See the MCP Server doc for the full tool table and what each one returns. For live schemas, use:
gv tools # list all tools
gv <tool> --help # show one tool's parameters
Examples
Every response is JSON. The samples below are truncated (…) — run with --pretty to see the full payload.
Scored activity feed
gv get_activity --limit 2 --pretty
{
"items": [
{
"score_id": 187668,
"repo": "acme-corp/backend",
"pr_number": 482,
"score": 14,
"title": "Gate optimistic association UI on server success",
"html_url": "https://github.com/acme-corp/backend/pull/482",
"state": "closed",
"merged": true,
"author_login": "alice",
"username": "alice",
"source_type": "pr",
"model": "claude-sonnet-4-6",
"created_at": "2026-06-23T17:04:00.000Z",
},
// … one more item
],
"total": 2437,
"page": 1,
"limit": 2,
"totalPages": 1219,
"metadata": {
"repositories": [{ "repo": "acme-corp/backend", "count": 807 }],
"authors": [{ "login": "alice", "displayName": "Alice", "count": 719 }],
"scoreRange": { "min": 1, "max": 89 },
// … activityRange
},
}
Full score breakdown
gv get_score_details --owner acme-corp --repo backend --pr_number 482 --pretty
{
"repo": "acme-corp/backend",
"prNumber": 482,
"sourceType": "pr",
"totalScore": 14,
"totalFactors": "36 × 0.4 (Small ESF) = 14.4 → 14",
"rubric": {
"scope": {
"score": 8,
"maxScore": 20,
"factors": "6 meaningful files across a single vertical slice; no new APIs"
},
"architecture": {
"score": 5,
"maxScore": 20,
"factors": "New shared predicate centralizes the success-check contract; no new dependencies"
},
"implementation": {
"score": 7,
"maxScore": 20,
"factors": "Fixes a subtle async response-propagation bug; null/error guards added"
},
"risk": {
"score": 6,
"maxScore": 20,
"factors": "Behavioral change to gated UI updates; additive; no migrations or auth changes"
},
"quality": {
"score": 9,
"maxScore": 15,
"factors": "Test file added with good edge cases; missing integration-level tests"
},
"perfSecurity": {
"score": 1,
"maxScore": 5,
"factors": "Basic input validation; no specific perf or security work"
}
},
"schemaVersion": "v5",
"createdAt": "2026-06-23T17:04:32.020Z"
}
One engineer's velocity
gv get_engineer_velocity --username alice --days 30 --pretty
{
"averageScore": 26,
"totalPRs": 45,
"maxScore": 78,
"minScore": 1,
"scoreDistribution": { "high": 0, "medium": 10, "low": 40 },
"monthlyTrends": [{ "month": "2026-06", "score": 26, "prCount": 50 }],
"recentActivity": [
{
"repo": "acme-corp/backend",
"pr_number": 482,
"score": 14,
"title": "Gate optimistic association UI on server success",
"merged": true,
"created_at": "2026-06-23T17:04:32.020Z",
// … more fields per PR
},
// … more PRs
],
"username": "alice",
"repositoriesContributed": ["acme-corp/backend", "acme-corp/web"],
}
Output contract
- stdout is always JSON. Add
--prettyto indent it; pipe the compact form straight intojqotherwise. - stderr is human progress. Suppress it with
--quiet. - Mutating tools support
--dry-run(none of today's read-only tools mutate state, but the flag is honored where applicable).
Exit codes:
| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error |
2 |
Usage error |
3 |
Not found |
4 |
Permission denied |
5 |
Conflict |
7 |
Transport error |
Troubleshooting
- The browser login keeps looping. Re-run
gv auth login. If a stale token is in the way,gv auth logoutfirst, then log in again. Make sureGV_URLpoints at the right instance. permission_denied(exit code 4) in CI. TheGV_TOKENyou supplied is missing, revoked, or scoped to the wrong organization. Mint a fresh MCP token and update the secret.transporterrors (exit code 7). The CLI couldn't reach the/mcpendpoint. Check network access and thatGV_URLhas no trailing path after the host.
If anything else looks broken, reach out via the in-app chat or support@headline.com.