Skip to main content

Project-scoped Railway MCP server — reads RAILWAY_TOKEN from .env.local, no login needed

Project description

railguey

Project-scoped Railway MCP server.
Reads RAILWAY_TOKEN from each project's .env.local — no railway login needed.

PyPI Tests Python License


railguey is for teams and businesses that need reliable Railway deployments. It is not the simplest way to deploy — Railway's built-in GitHub app is simpler. But railguey is more reliable, because it draws a cleaner engineering boundary.

Why not just use Railway's GitHub App?

Railway's GitHub App is fast to set up: connect your repo, push to main, and your service deploys. For prototyping, that speed is genuinely great. But speed of setup and quality of engineering are different things.

The GitHub App bundles five responsibilities into one opaque chain: watch for code changes, authenticate to GitHub, receive a webhook, clone the repo, build and deploy. When the chain works, it feels like magic. When it doesn't — and it has broken four times in four months — there is no observability, no retry, and no notification. Your push goes in. Nothing comes out. You find out when a customer does.

Railway GitHub App: the fragile chain

Every decision diamond in this diagram is a place where the chain can silently break. Missed webhooks, lost build triggers, GitHub App auth failures — all produce the same result: nothing happens, and nobody tells you.

This isn't a bug. It's an architectural choice. Railway chose to own the entire pipeline from push to deploy, which means every failure in GitHub's webhook delivery becomes Railway's problem — and yours.

How railguey fixes this

railguey separates concerns. GitHub Actions watches your repo (GitHub watching GitHub — the thing it was built for). railguey handles the deploy via Railway's API using project-scoped tokens. Railway builds and runs your service (the thing it was built for). Each system does one job.

railguey: token-based deploy pipeline

If CI fails, GitHub tells you. If the deploy fails, the CLI returns an error. If the service is unhealthy, railguey doctor catches it. Every step is observable, retryable, and owned by the system best suited to do it.

Fast delivery and good engineering aren't opposites — but Railway's GitHub App trades the second for the first. railguey gives you both.

Doc What it covers
WHY-NOT-RAILWAY-APP.md The architectural argument — why coupling CI/CD triggering with deployment is a design flaw, not just a bug
WHY-RAILGUEY.md The evidence — four incidents, community reports, and what the project-token pattern does differently
WHY-RAILGUEY.md#case-study Real-world case study — ghost GitHub repo links silently blocked env var operations across 5 services

When to use railguey

  • You manage Railway services from AI agents (Claude Code, Cursor, etc.) and want them to deploy, rollback, and read logs without railway login
  • You run multiple Railway projects and want one auth pattern across local dev, CI/CD, and AI tooling
  • Deploy reliability matters — production services, client projects, anything where a silently missed deploy costs you
  • You're already using GitHub Actions and want Railway deploys in the same pipeline as your tests

When NOT to use railguey

  • Quick demos and hobby projects. Railway's GitHub app is genuinely convenient for push-and-forget deploys. If you're prototyping and don't care about deploy reliability, the built-in integration is fine.
  • You don't use an MCP client or CLI. railguey includes both an MCP server and a CLI. But if you only deploy once in a while from the terminal, the Railway CLI with a project token is enough.
  • You're happy with the dashboard. If you deploy once a week and check status manually, railguey adds complexity you don't need.

Known limitations

  • All tools depend on Railway's Backboard GraphQL API, which isn't officially documented. The schema could change without notice.
  • No Railway CLI required. All 21 tools use pure GraphQL with project-scoped tokens. The CLI backend module still exists for backward compatibility but is no longer used by any tool.
  • One token per project. Project-scoped tokens can't query across projects. If you manage 10 projects, you need 10 .env.local files in 10 workspaces. This is by design (isolation), but it's more setup than a user-level login.

Install

Requires Python 3.10+. No Railway CLI needed.

pip install railguey

Or run without installing:

uvx railguey --help
Install from source
git clone https://github.com/eidos-agi/railguey.git
cd railguey
pip install -e .

CLI usage

pip install railguey gives you the railguey command with all 21 tools as subcommands:

railguey status ~/repos/my-app
railguey logs ~/repos/my-app cerebro --lines 50
railguey deploy ~/repos/my-app web
railguey deployments ~/repos/my-app cerebro --limit 5
railguey doctor ~/repos/my-app
railguey variables ~/repos/my-app web
railguey service-info ~/repos/my-app cerebro

Every command takes a workspace path — the directory containing .env.local with RAILWAY_TOKEN.

Configure Claude Code (MCP)

The recommended setup uses the Claude Code CLI to register railguey as a user-level MCP server:

pip install railguey
claude mcp add --scope user railguey -- railguey serve

This makes railguey available in every Claude Code session, across all projects. The --scope user flag writes to ~/.claude.json so it persists globally.

Manual config (alternative)

Add to ~/.claude.json under mcpServers:

{
  "mcpServers": {
    "railguey": {
      "command": "railguey",
      "args": ["serve"]
    }
  }
}
From source (development)
git clone https://github.com/eidos-agi/railguey.git
cd railguey
pip install -e .
claude mcp add --scope user railguey -- railguey serve

Or manually in ~/.claude.json:

{
  "mcpServers": {
    "railguey": {
      "command": "python3",
      "args": ["-m", "railguey.mcp"]
    }
  }
}

First deploy of a fresh service

A brand-new Railway service needs both a serviceCreate mutation (with environmentId so the per-env instance materializes) AND a source upload to be deployable. railguey collapses this to one verb:

railguey service-bootstrap /path/to/repo my-service

Under the hood: serviceCreate with the project-token's environmentId (Railway requires this), then a gzipped tarball of the workspace POSTed to https://backboard.railway.com/project/{p}/environment/{e}/up?serviceId={s} — both project-token-only, no GitHub-Railway link, no account-level auth.

The tarball respects .gitignore, .dockerignore, and .railwayignore (90% of .gitignore semantics — no negation, no nested **); .git, node_modules, .venv, and *.cache directories are always excluded. Hard-cap of 256MB; use .railwayignore to trim larger workspaces.

For subsequent deploys, use railguey upload-source (just upload — service already exists) or railguey deploy (redeploy from existing source).

Tools

21 tools, all pure GraphQL. No Railway CLI required — just a project-scoped token.

Tool What it does
railguey_status Project overview — all services, deploy status, domains
railguey_services List services with IDs
railguey_logs Fetch recent deploy or build logs (with optional filter)
railguey_deploy Trigger a deploy from linked source
railguey_redeploy Redeploy latest deployment (rebuilds from source)
railguey_restart Restart latest deployment (no rebuild, fast)
railguey_variables List env vars for a service
railguey_variable_set Set an env var (triggers redeploy)
railguey_domain Generate a railway.app domain or add a custom domain
railguey_environment_create Create a new environment (staging, preview, etc.)
railguey_deployments Deployment history with IDs, statuses, timestamps, rollback eligibility
railguey_rollback Roll back to a specific deployment
railguey_service_info Full service config — build/start commands, healthcheck, region, replicas
railguey_http_logs HTTP request logs — status codes, latency, paths
railguey_deployment_logs Logs for a specific deployment by ID (deploy or build, with filter)
railguey_unlink_repo Disconnect a service from GitHub repo linking
railguey_service_create Create a service bound to the project token's environment
railguey_upload_source Tarball workspace + POST to Railway /up — deploy via project token
railguey_service_bootstrap One-call first deploy: service_create + upload_source
railguey_service_delete Delete a service from the Railway project (irreversible)

Coaching tools

Tool What it does
railguey_doctor Audit a workspace for deployment best practices (4-point check)

railguey_doctor checks:

  1. RAILWAY_TOKEN exists in .env.local
  2. .env.local is in .gitignore
  3. GitHub Actions deploy workflow exists with token-based CI/CD
  4. No services linked to GitHub repos

Every tool requires a workspace parameter — the absolute path to a project directory that has a .env.local (or .env) containing RAILWAY_TOKEN.

Example

CLI:

railguey logs ~/repos/my-app web --lines 50

MCP (via AI agent):

railguey_logs(workspace="/Users/you/repos/my-app", service="web", lines=50)

Python library:

from railguey.lib import tools
result = await tools.logs("/Users/you/repos/my-app", "web", lines=50)

All three read /Users/you/repos/my-app/.env.local, extract the token, and run:

RAILWAY_TOKEN=<token> railway logs --service web --lines 50

The project-token pattern

Railway lets you create project-scoped tokens — API keys that authenticate to a single project without any user login. These tokens work the same way everywhere:

Context How the token is used
Local dev .env.localrailway logs, railway up, etc.
AI agents (railguey) Read from .env.local at the workspace path
GitHub Actions CI/CD Repository secret → RAILWAY_TOKEN env var
Any CI system Same — export the token, run railway up

One mechanism. No OAuth. No repo linking. No webhook fragility.

GitHub Actions deploy workflow (copy-paste)

Add RAILWAY_TOKEN as a repository secret, then:

# .github/workflows/deploy.yml
name: Deploy to Railway

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Railway CLI
        run: curl -fsSL https://railway.com/install.sh | sh

      - name: Deploy
        env:
          RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
        run: railway up --service ${{ vars.RAILWAY_SERVICE }} --detach

Set RAILWAY_SERVICE as a repository variable. More examples in examples/.

Token discovery

  1. Looks for RAILWAY_TOKEN= in {workspace}/.env.local
  2. Falls back to {workspace}/.env
  3. Raises a clear error if not found

Supports bare values, single-quoted, and double-quoted values.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

railguey-0.2.10.tar.gz (4.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

railguey-0.2.10-py3-none-any.whl (53.3 kB view details)

Uploaded Python 3

File details

Details for the file railguey-0.2.10.tar.gz.

File metadata

  • Download URL: railguey-0.2.10.tar.gz
  • Upload date:
  • Size: 4.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for railguey-0.2.10.tar.gz
Algorithm Hash digest
SHA256 c467c21fbe01ea677b8aeea85c7bead5683e6b87baa332de1d242573d722b51f
MD5 99f3f8f5d634a50ff92aed7157a789a9
BLAKE2b-256 d12c8a6e44ba608444f43282a7fcac95d45f204fc37453ca5f2664bae24c0e40

See more details on using hashes here.

Provenance

The following attestation bundles were made for railguey-0.2.10.tar.gz:

Publisher: publish.yml on eidos-agi/railguey

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file railguey-0.2.10-py3-none-any.whl.

File metadata

  • Download URL: railguey-0.2.10-py3-none-any.whl
  • Upload date:
  • Size: 53.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for railguey-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 5f1281bf3a7e821f9478efd1e158767d9388eda391fb8a1b092112ffa5368e4e
MD5 388e98728c07a0254c4f0ba26cf3daa9
BLAKE2b-256 62a0e4125be9f07af3e2fc97f2da9e3fe0eb6e585b8e7947783dd03a40758958

See more details on using hashes here.

Provenance

The following attestation bundles were made for railguey-0.2.10-py3-none-any.whl:

Publisher: publish.yml on eidos-agi/railguey

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page