Pre-flight manual
Install Houston
Houston is a standard Laravel app. Clone it, run composer setup, give it a GitHub token, and keep a queue worker and the scheduler running. On a laptop that takes a few commands.
- MIT
- PHP 8.5.12+
- Node 22
- SQLite by default
- No Docker needed
Requirements
| PHP | 8.5.12 or newer |
|---|---|
| Composer | 2 |
| Node and npm | Node 22, to build the frontend |
| Database | SQLite by default; any database Laravel supports works |
| GitHub | The GitHub CLI, or a token that can read the repositories you want to measure |
Step 1
Clone and set up
git clone https://github.com/vistik/houston.git
cd houston
composer setup
composer setup runs these, in order:
- 1
composer installfor the PHP dependencies - 2copies
.env.exampleto.envif there is no.envyet - 3
php artisan key:generate - 4
php artisan migrate --forceto create the tables - 5
npm installandnpm run buildfor the frontend
Step 2
Connect GitHub
Houston talks to GitHub with one token. Pick one of the two.
On your own machine: the GitHub CLI
gh auth login
When GITHUB_TOKEN is empty, Houston uses the CLI's token (gh auth token).
On a server: a token in .env
GITHUB_TOKEN=[your token]
A classic token needs no scopes for public repositories and the repo scope for private ones.
| Permission | Used for |
|---|---|
| Metadata | Repository details |
| Pull requests | Pull requests and reviews |
| Actions | Workflow runs |
| Deployments | Deployments |
| Contents | Releases and commit timestamps |
Step 3
Run it
On your laptop
composer dev
This runs php artisan dev, which starts, side by side:
- web server php artisan serve
- scheduler php artisan schedule:work
- queue worker php artisan queue:listen
- log tail php artisan pail
- Vite npm run dev
Then open http://localhost:8000. If Laravel Herd already serves the app, its .test address works too.
On a long-running server
Serve the app like any Laravel app, then keep two processes running: a queue worker for the syncs, and the scheduler.
php artisan queue:work
For the scheduler, either keep php artisan schedule:work running, or add the usual Laravel cron entry:
* * * * * cd /path/to/Houston && php artisan schedule:run >> /dev/null 2>&1
What the scheduler runs
- houston:sync --queue
- every 15 minutes, never overlapping: refreshes every watched repository
- model:prune
- daily: prunes old system events
Step 4
Add repositories
- 1Open Houston and click Watch repository.
- 2Enter
owner/name, or paste the repository's GitHub URL.
A sync is queued straight away. The first one pulls the lookback window, 180 days by default, and can take a while on busy repositories. It pauses before it runs into GitHub's rate limits and resumes when they reset. Follow it under Settings → Syncs, where you can also change each repository's lookback window.
Want to see it work before pointing it at your own code? Watch a busy public repository such as laravel/framework.
From the command line:
php artisan houston:sync # every watched repository
php artisan houston:sync laravel/framework # one repository
php artisan houston:sync --queue # dispatch to the queue instead
Step 5
Teams and benchmarks
Teams
Create them under Settings → Teams and add people by their GitHub login, with the day they joined and, later, the day they left. Work counts for the team someone was on when they did it.
Benchmarks
Off until you set targets. Under Settings → Benchmarks, set your own, or add the 31 built-in standards (DORA, LinearB and suggested targets) with one click.
Step 6
Connect an AI assistant (MCP)
Houston runs a read-only MCP server with three tools (list-repositories, get-velocity-report, list-pull-requests) and a give-feedback prompt.
Locally, over stdio
Point your client at php artisan mcp:start houston. With Claude Code:
claude mcp add houston -- php /path/to/Houston/artisan mcp:start houston
Any other client, in its JSON config:
{
"mcpServers": {
"houston": {
"command": "php",
"args": ["/path/to/Houston/artisan", "mcp:start", "houston"]
}
}
}
Over HTTP, with a token
Set HOUSTON_MCP_TOKEN in .env to a long random string, then send it as a bearer token to /mcp:
claude mcp add --transport http houston http://localhost:8000/mcp \
--header "Authorization: Bearer $HOUSTON_MCP_TOKEN"
- No token set
- 404, endpoint off
- Wrong or missing
- 401
- Matching token
- read-only access
Step 7
Configuration
Everything Houston-specific lives in config/houston.php and can be set from .env. Report defaults (period, grouping and the timezone every report is shown in) and benchmarks are set in the app under Settings.
| Variable | Default | What it does |
|---|---|---|
| GITHUB_ | gh auth token | The token used to talk to GitHub. Empty falls back to the GitHub CLI's token. |
| HOUSTON_ | 50 | Syncs pause when fewer requests are left, leaving room for anything else using the token. |
| HOUSTON_ | 180 | Days of history a fresh sync pulls. Keep it at least twice the longest period you report on. Can be set per repository. |
| HOUSTON_ | 15 | Viewing a repository whose cache is older than this queues a refresh. |
| HOUSTON_ | 7 | Open pull requests without activity for this long are flagged as stale. |
| HOUSTON_ | 1,2,3,4,5 | Working days as ISO day numbers (1 is Monday). |
| HOUSTON_ | 00:00 / 24:00 | Working hours. Use all seven days and 00:00 to 24:00 to measure calendar time. |
| HOUSTON_ | /^(prod|production|live)\b/i | Deployments to a matching environment count for delivery metrics. Without them, published releases are used. |
| HOUSTON_ | /^(revert|hotfix|rollback)\b/i | Pull requests whose title, branch or label matches count as remediations, which drive the change failure rate. |
| HOUSTON_ | empty | Enables the MCP endpoint at /mcp for clients that send this bearer token. |
| HOUSTON_ | true | Asks for the single login before showing anything. php artisan houston:install creates the login; until then visitors see this guide. |
| HOUSTON_ | false | Shows this website at / and /install. The app is at /dashboard either way; without the website, / goes straight there. |
Security: authorized personnel only
- Houston asks for its single login by default, and shows this guide until the login exists:
php artisan houston:installcreates it, or turns the login off withHOUSTON_AUTH=false. There are no per-user accounts. - Only
/mcpis protected, byHOUSTON_MCP_TOKEN, and it is off until you set one. - Only turn the login off on localhost or a private network or VPN. On a public server, keep it on.
Houston standing by.
Star the repo to follow along, or open an issue if a step above didn't work for you.