Replace the GraphQL-based LoginSession flow and hyper HTTP server with
standard OAuth 2.0: Authorization Code + PKCE for browser login, and
Device Authorization Grant (RFC 8628) for browserless. Adds automatic
token refresh before commands, CSRF state verification, and proper
error variants. Removes hyper, hyper-util, http-body-util, and hostname
dependencies in favor of raw TCP + sha2 for PKCE.
Browser login hardened with OS-assigned port, looped callback handler
for preconnect resilience, 5-minute timeout, and prompt=consent to
ensure refresh tokens are always issued.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add GraphQL queries and mutations for MCP server
Add Metrics and Templates queries for service observability and template
search. Add ServiceInstanceUpdate mutation for updating service settings
like build command, replicas, and health check path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Extract upload logic from up command into controller
Move tarball creation and upload logic into src/controllers/upload.rs so
it can be reused by both the up CLI command and the MCP deploy tool.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Change log callbacks from Fn to FnMut
The MCP log handler collects logs into a Vec, which requires mutating
captured state. Fn closures don't allow this — FnMut does. Existing
callers are unaffected since every Fn is a valid FnMut.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add MCP server for AI-agent access to Railway
Expose Railway operations (deploy, logs, variables, domains, templates,
metrics, etc.) as MCP tools so AI agents can manage infrastructure
programmatically. Uses the rmcp crate for the MCP protocol.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add more fields to update_service MCP tool
Expose cron_schedule, dockerfile_path, healthcheck_timeout,
restart_policy_type, restart_policy_max_retries, pre_deploy_command,
region, railway_config_file, and watch_patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix MCP server: deploy resolution, linked-context precedence, and workspace auto-detect
- Return clear error with available services when deploy gets an unknown service name
- Prefer locally-linked project over token-derived project in MCP context resolution
- Auto-detect team workspace when create_project is called without workspace_id
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix docs_search and split into search + fetch tools
- Replace GitHub API (401 auth failures) with public sitemap for page listing
- Fix content path from src/docs/ to content/ to match actual repo structure
- Use plain HTTP client for external fetches (Railway auth headers caused GitHub 401s)
- Split into docs_search (returns top 5 URLs) and docs_fetch (reads full page)
- Improve scoring: exact path segment matches rank higher than substrings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Hide confirm field from MCP schema to prevent AI agents from auto-setting it
AI agents were reading "Requires confirm: true" in tool descriptions and
auto-populating confirm on the first call, bypassing the destructive action
safety guard. Fix by adding #[schemars(skip)] to the confirm field on
RemoveServiceParams, RemoveBucketParams, and RemoveVolumeParams so it's
hidden from the JSON schema (serde still deserializes it, defaulting to
false). Updated descriptions to say "Returns a preview first" instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Reject create_service when both source_repo and source_image are provided
The backend silently picks repo over image when both are set (via an
if/else chain in the serviceCreate resolver), dropping the image with
no error or warning. This is confusing for MCP agents that may not
realize one source was ignored. Validate early in the MCP layer to
give a clear, actionable error instead of silent precedence.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Add help text for mcp command
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Drop vulnerable time crate by disabling unused serde_with features
serde_with was pulling in the time crate (RUSTSEC-2026-0009, DoS via
stack exhaustion in RFC 2822 parsing) through default features. We only
use skip_serializing_none from the macros feature, so disable defaults
and enable only macros. This removes time and several other unused
transitive deps (hex, indexmap v1, deranged, powerfmt, num-conv).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When trying to use the Railway CLI behind an HTTP proxy that requires
a custom certificate ( such as some VPNs ), the CLI would previously
fail with a certificate error. This adds the `rustls-tls-native-roots`
feature reqwest to trust the native platform's system certificate store to
fix that.
Railway commands that require a websocket connection were also
failing to go through the proxy, because while `reqwest` automatically
sends requests through the proxy `async-tungstenite` would not. This
removes `async-tungstenite` in favor of `reqwest-websocket` which is
simpler and uses `reqwest` to properly send the initial HTTP request
through the proxy before the websocket upgrade.
* it works
* remove useless comment
* fix conflicts, make it work again
* update schema
* cli side work is becoming a lot closer
* organise environment command
* more cleanup
* todos
* filter out old regions from scale non-interactively
* add non-interactive options for everything
* make trait variable handling more consistent for things that require custom value parsers
* begin work on porting to other way non-interactively
* it works
* add all interactive options and fix issue with --service flag in scale command
* add build command and start command and fix some parsing errors in non-interactive
* add placeholders for env being duplicated
* add edit command
* simplify and ux
* address comments
* remove interactive auto update
* feat: Add mouse-based text selection in TUI logs
Implement custom text selection with mouse drag support in the `railway dev` TUI:
- Click and drag to select log text with visual highlighting
- Auto-copy selected text to clipboard on mouse release
- Auto-follow when scrolling back to bottom while paused
- Prevent screen flicker when scrolling down in follow mode
- Restore log buffering for better selection and scroll support
* fix: address code review issues in TUI text selection
- Consolidate LogRef enum to log_store.rs (was duplicated)
- Add clipboard failure feedback to user
- Fix prefix color logic when selection spans across prefix
- Make convert_color private
- Add comment explaining .take(2) limit in info pane
* refactor: optimize TUI log rendering and simplify selection
- Add LogRef::parts() to reduce duplication in log extraction
- Only collect visible logs instead of all logs (skip/take)
- Simplify selection rendering with explicit span regions
- Fix magic number defaults for log area bounds
- Remove unused Selection::contains method
* Add TUI log viewer for dev command
- ratatui-based interface with tabs: Local, Image, per-service
- 100k line scrollback, follow mode, vim-style navigation
- Docker logs streamed alongside code services
- Opt-out via --no-tui flag (TUI is default)
- Auto-disables when stdout is not a terminal
* Fix TUI scroll behavior and filter railway-proxy logs
- Enable mouse capture for native scroll support
- Fix scroll jump when exiting follow mode by syncing scroll_offset
- Filter out railway-proxy infrastructure logs from docker output
* Batch scroll events to eliminate momentum lag
Drain queued events before rendering to prevent macOS trackpad
inertia from causing gradual scroll movement across render cycles.
* Add service info pane and improve TUI tab visibility
- Change tab colors from DarkGray to Gray (unselected) and Cyan (selected)
- Add info pane showing service URLs and var counts
- Display both private and public URLs separated by pipe when HTTPS enabled
- Info pane content changes based on current tab (Local/Image/Service)
* Skip service summary output in TUI mode and fix terminal cleanup
- Only print service summaries in non-TUI mode (info now shown in TUI pane)
- Fix terminal cleanup order: restore before disabling mouse capture
* Fix --no-tui to only stream code service logs
* Kill process groups on shutdown and fix panic terminal cleanup
- Use process_group(0) to create new process groups for spawned processes
- Use killpg instead of kill to terminate entire process groups
- Add panic hook to restore terminal on panic
- Extract setup_terminal/restore_terminal helpers for consistent cleanup
* Fix terminal corruption on TUI exit by isolating child stdin
Child processes were inheriting stdin from the terminal. When receiving
SIGTERM during shutdown, they could write escape sequences directly to
the terminal, bypassing piped stdout/stderr and corrupting cursor state.
* Improve post-TUI shutdown output
Clear terminal after TUI exits to remove confusing scrollback,
suppress docker compose output, show clean service count summary
* Refactor dev up command with DevSession struct
Extract TUI/service execution logic from up_command() into DevSession
struct with focused methods: start(), run(), shutdown()
* Move DevSession to controllers/develop/session.rs
- Move DevSession struct and impl to session.rs alongside DevelopSessionLock
- Move print_code_service_summary to output.rs
- Update imports in dev.rs
* Remove test script and unnecessary comments