Uvilo OS Plan Infrastructure
Status: Partially implemented. The Railway + LibreChat + MCP setup is live. The
uvilo-git-remotecustom Python FastMCP server (push/pull/fetch) is not captured in the original plan below. For current operational procedures, see Uvilo OS Setup. Key deviation from plan: switched from@cyanheads/git-mcp-server(Node.js) to the official Pythonmcp-server-gitdue to an incompatibility with LibreChat’s MCP SDK.
Current Setup (Verified)
- Project:
uvilo-libre-chaton Railway - Services: LibreChat, MongoDB, Meilisearch, RAG API, VectorDB — all running successfully
- Domain:
librechat.uvilo.ai - Config:
librechat.yamlatForge/Configs/LibreChat_Service/librechat.yamlin the repo, read from the volume at runtime viaCONFIG_PATH - Deployment: Railway template (Docker image, not a GitHub repo deploy)
- MCP status: A placeholder
my-remote-mcpSSE server is configured but failing (points toexample.com) - Multi-user: Needed soon
Architecture
Key Constraint: Template Deployment
Since LibreChat was deployed via Railway template, we’re working with a pre-built Docker image — not a GitHub repo we control. This means:
- We cannot modify the Dockerfile to add git, python, or custom startup scripts directly
- We CAN customize the start command in Railway’s service settings
- We CAN mount a volume to the service
- We CAN configure MCP servers via
librechat.yamlon the volume (cloned from the repo)
The constraint is whether the LibreChat Docker image already has the tools we need:
npx(Node.js) — almost certainly yes (LibreChat is a Node.js app)git— likely yes (many Docker images include it)uvx/python— possibly not (needed for the Python-based git MCP server)
If python/uvx aren’t available, we use the Node.js-based @cyanheads/git-mcp-server instead (runs via npx).
Implementation Steps
Step 1: Verify container capabilities
Before adding anything, SSH into the running LibreChat container and check what tools are available:
This determines whether we can use the Python git MCP server or need the Node.js one.
Step 2: Create Railway volume
Attach a persistent volume to the LibreChat service:
- Mount path:
/workspace - This can be done via the Railway dashboard (recommended for first time) or CLI
Key facts about Railway volumes:
- Data written at build time does NOT persist — must write at runtime
- Volumes are not mounted during pre-deploy commands
- Only one deployment can mount a volume at a time (brief downtime on redeploy)
- Non-root Docker images may need
RAILWAY_RUN_UID=0
Step 3: Set up git clone at startup
Add environment variables to the LibreChat service:
GITHUB_TOKEN— GitHub fine-grained PAT with Contents (read/write) forErikDakoda/uvilo-osGIT_AUTHOR_NAME=Erik DakodaGIT_AUTHOR_EMAIL=erikschannen@gmail.com- Update
CONFIG_PATHto/workspace/erik/uvilo-os/Forge/Configs/LibreChat_Service/librechat.yaml
Override the LibreChat start command to clone/fetch the repo into a per-user directory:
The per-user directory structure (/workspace/erik/) means adding future users is just a matter of adding another clone block — no reorganization needed. The exec npm start (or whatever the default start command is) ensures LibreChat still starts normally after the git setup. We need to check the existing start command first.
Step 4: Update librechat.yaml with MCP servers
Update Forge/Configs/LibreChat_Service/librechat.yaml in the repo with working MCP servers. CONFIG_PATH will point to the volume copy at /workspace/erik/uvilo-os/Forge/Configs/LibreChat_Service/librechat.yaml:
Commit and push the change, then restart LibreChat. Since CONFIG_PATH points to the volume copy, the new config is picked up on restart.
Step 5: Validate end-to-end
Test the full workflow in LibreChat at librechat.uvilo.ai:
- Filesystem test: Select the
uvilo-filesystemMCP, ask to list files in the repo root - Read test: Ask to read
Architecture/Uvilo_OS/Uvilo_OS_Spec.md - Git status: Select
uvilo-gitMCP, ask forgit status - Branch + edit + commit:
- Create branch
work/erik/test-mcp-2026-03-07 - Edit a test file via filesystem MCP
- Stage, commit, and push via git MCP
- Create branch
- Verify on GitHub: Check that the branch appears at
github.com/ErikDakoda/uvilo-os
Step 6: Multi-user expansion
The directory structure is already per-user from day one:
To add a new user:
- Add a clone block to the startup script for the new user directory
- Duplicate the MCP server entries in librechat.yaml with the new path
- Or use
{{LIBRECHAT_USER_ID}}in paths if LibreChat supports it in MCP args
- Or use
- Restart LibreChat
LibreChat supports {{LIBRECHAT_USER_ID}} in MCP server headers and env vars. If it also supports it in args, the MCP config can be user-agnostic:
This needs testing — if it works, multi-user is nearly free.
Risks and Mitigations
| Risk | Mitigation |
|---|---|
| Docker image lacks git/python | Check with railway shell; fall back to Node.js MCP servers |
| Volume not accessible to MCP child processes | stdio processes inherit parent filesystem; test immediately |
| Start command override breaks LibreChat | Test in a staging environment first; keep original command noted |
| Config lives in repo at Forge/Configs/LibreChat_Service/librechat.yaml, version-controlled and editable via MCP | — |
| MCP server errors spam logs (like current placeholder) | Remove placeholder immediately; monitor logs after deploying real servers |
| Git conflicts in shared working directory | Per-user dirs from day one prevents this |
Immediate Action: Fix the MCP Spam
The placeholder my-remote-mcp SSE server is generating error logs every 2 seconds. It will be removed when we update the config in the repo.
Playwright MCP — Browser Automation
A separate Railway service running the official Microsoft Playwright MCP Docker image provides headless Chromium browser capabilities to the AI assistant.
- Service name:
playwright-mcp - Image:
mcr.microsoft.com/playwright/mcp - Custom Start Command:
node cli.js --headless --browser chromium --no-sandbox --port 8931 --host 0.0.0.0(overrides the image’s ENTRYPOINT in exec form) - Serverless: Enabled — sleeps after 10 min inactivity, wakes on private network traffic (~5–15s cold start)
- Transport:
streamable-httpover Railway private network - Internal URL:
http://playwright-mcp.railway.internal:8931/mcp - Memory: 512MB–1GB recommended
- No public domain — internal only
LibreChat connects via mcpSettings.allowedDomains whitelist and type: streamable-http.
See Playwright MCP Research for full evaluation.
TinaCMS — Deferred
TinaCMS adds significant complexity (separate Next.js app, content schema, database, auth) and is not on the critical path. The core editing workflow is fully covered by LibreChat + MCP servers. Revisit after Phases 1-2 are validated.
Estimated Timeline
| Step | Effort | Dependencies |
|---|---|---|
| 1. Verify container capabilities | 10 min | Railway shell access |
| 2. Create volume | 5 min | Railway Pro plan |
| 3. Set up git clone at startup | 30 min | GitHub PAT, start command |
| 4. Update librechat.yaml | 30 min | Step 1 results (choose git MCP server) |
| 5. Validate end-to-end | 30 min | Steps 1-4 complete |
| 6. Multi-user expansion | 1-2 hours | Test {{LIBRECHAT_USER_ID}} in args |
Total for working single-user setup: ~2 hours
Agentic Execution — Orchestrator
Overview
An external orchestrator script will chain LibreChat agent sessions to implement projects autonomously across multiple sessions. This is separate from the existing MCP infrastructure which provides per-session file and git access.
Architecture
The orchestrator is a Python script running as a separate Railway service (or cron job on the LibreChat service). It:
- Reads
Project_Name_State.mdfiles from projects in the repo - Determines the next actionable task (unchecked or
[STARTED]) - Calls LibreChat’s Agents API with the task prompt + session log context
- Monitors agent progress via streaming responses
- On completion/timeout, updates the State document and
session_log.md - Optionally starts the next session or waits for a schedule/trigger
LibreChat Agents API Setup
The Agents API is gated behind the remoteAgents interface configuration in librechat.yaml:
Once enabled, users can generate API keys from the LibreChat UI. The orchestrator uses these keys to call the OpenAI-compatible chat completions endpoint or the Open Responses endpoint.
Orchestrator Invocation Example
Prerequisites
- Enable
remoteAgentsin librechat.yaml - Create a LibreChat agent with Uvilo OS system prompt and MCP tools attached
- Generate an API key from LibreChat UI
- Deploy orchestrator script on Railway
LibreChat 2026 Roadmap Alignment
LibreChat’s Q2 2026 roadmap includes “agent workflows that run on a schedule and/or triggered by other agents, enabling automation and background processing.” When this ships, it may replace the external orchestrator with a native LibreChat feature.