Skip to content
archived Visibility internal Owner erik@uvilo.com Approver _ Created 2026-04-22 Updated 2026-04-22

Container Base Image Plan 4

Scope: Fix MCP server startup lag (env var access), eliminate constant package reinstalls, upgrade Node.js to v22, and comprehensively test all components, tools, MCP servers, and skills. Prior plan: Container Base Image Plan 3


Task 1 — Fix MCP server startup lag caused by env var access

The “MCP Server Lag Fix” conversation (2026-04-22) identified that when starting a new conversation, there is a 10–15 second delay before it appears. The root cause is that Railway env vars are NOT inherited by child processes (MCP stdio servers). The previous agent in that conversation discovered that env vars ARE accessible via /proc/1/environ, and a railway_env.py helper module already exists for this. But the npx-based MCP servers (the majority) don’t use this helper — they rely on LibreChat’s ${VAR} substitution in librechat.yaml, which injects vars via the env: block. The lag occurs because LibreChat must resolve these env vars at startup and start each MCP server process, and some servers (npx-based) re-download packages on first invocation (npx -y), adding significant delay. The startup: false flag exists for servers that shouldn’t auto-start, reducing initial load, but servers marked with startup: true (or without startup: false) all start on first conversation, causing the lag.

  1. Audit every MCP server in librechat.yaml — for each, determine whether it should have startup: false (deferred until first use) vs auto-start
  2. Set startup: false on any server that is not needed at session start (most of them — only uvilo-filesystem and uvilo-shell are needed immediately)
  3. Verify that the env: blocks in librechat.yaml correctly inject Railway env vars via ${VAR} substitution — confirm all 12 referenced vars (VERCEL_API_KEY, GITHUB_TOKEN, NEON_API_KEY, NOTION_TOKEN, LINEAR_ACCESS_TOKEN, RAILWAY_API_TOKEN, POSTHOG_API_KEY, COMPOSIO_SM_MCP_URL, COMPOSIO_API_KEY, SUPRSEND_SERVICE_TOKEN, TYPESENSE_HOST, TYPESENSE_SEARCH_KEY) are present in /proc/1/environ
  4. For Python MCP servers (uvilo-shell, uvilo-trash, uvilo-typesense, suprsend-mcp-proxy), verify railway_env.py is imported and inject_railway_env() is called before any env var access — these servers must NOT rely on os.environ alone
  5. Test: start a new conversation and verify the delay is reduced to under 5 seconds

Task 2 — Eliminate constant package reinstalls

The “Update Agents” conversation (2026-04-22) showed that running /update-agents required npx tsx which downloads tsx@4.21.0 every time. Similarly, every npx -y MCP server command downloads its package on each invocation. The npx cache at /root/.npm/_npx/ is ~412MB with 9 cached packages, but these are version-pinned hashes that may not match the requested version. The uvx commands also re-resolve on each spawn. These reinstalls waste time and bandwidth, and are the primary contributor to MCP server startup lag.

  1. Audit all npx-based MCP server commands in librechat.yaml to identify which packages are downloaded on each spawn
  2. Pre-install frequently-used npm packages globally in the Dockerfile so npx finds them locally instead of downloading:
    • npm install -g @modelcontextprotocol/server-filesystem @modelcontextprotocol/server-github @upstash/context7-mcp @notionhq/notion-mcp-server @touchlab/linear-mcp-integration @jasontanswe/railway-mcp mcp-remote vercel-mcp
    • Update the Dockerfile’s runtime stage to add this global install
  3. Pre-install frequently-used uvx packages in the Dockerfile so uvx finds them in the system Python:
    • Already done: mcp, pymongo, dnspython are installed via uv pip install --system
    • Add mcp-server-git if it can be pre-installed as a Python package
  4. Pre-install tsx globally (npm install -g tsx) so Forge scripts using npx tsx don’t download it each time
  5. Rebuild and push the Docker image with these changes
  6. Verify: run npx tsx --version without download delay, run a sample MCP server command without download delay
  7. Update Forge_Infrastructure.md to document the pre-installed packages

Task 3 — Comprehensive component, tool, MCP server, and skill testing

Plans 1–3 validated the Debian-slim deployment at a high level (MCP servers start, basic tool calls work). But the lag fix conversation revealed that some MCP servers weren’t actually working correctly at runtime (env vars missing, servers crashing). This task performs a thorough end-to-end test of every component. Crucially, LibreChat logs must be examined for thrown errors — silent failures in MCP server startup or tool execution often only surface in logs, not in the agent’s conversation output.

  1. Examine LibreChat logs — Before any testing, capture and review the LibreChat container logs for errors:

    • cat /proc/1/environ | tr '\0' '\n' — verify env vars are present
    • Check container logs for MCP server startup errors, connection failures, or unhandled rejections
    • Fix any errors found before proceeding with functional tests — a broken server must be repaired before it can be meaningfully tested
    • Re-check logs after each fix to confirm the error is resolved
  2. MCP server tests — For each of the 17 MCP servers in librechat.yaml, perform a meaningful functional test (not just “starts”):

    #MCP ServerTest ActionExpected Result
    1uvilo-filesystemread/write/search filesFile operations succeed
    2uvilo-shellexecute a commandCommand output returned
    3uvilo-typesensesearch_knowledgeSearch results returned
    4uvilo-trashtrash and untrash a test fileFile moved to .trash and restored
    5vercelgetDeploymentsDeployment list returned
    6githubtool_searchTools available
    7context7resolve-library-idLibrary found
    8railwaytool_searchTools available
    9neontool_searchTools available
    10notiontool_searchTools available
    11lineartool_searchTools available
    12posthoginsights-listInsights returned
    13playwrightbrowser_navigatePage loaded
    14surveymonkeytool_searchTools available
    15suprsend-devtool_searchTools available
    16suprsend-stagingtool_searchTools available
    17suprsend-prodtool_searchTools available
  3. Skill tests — Test each Forge skill that has a runnable action:

    #SkillTest ActionExpected Result
    1Update_Agents/update-agents --dry-runDry run completes
    2Deploy_Configvalidate configValidation passes
    3Reindex_Typesenserun indexing scriptIndex updated
    4NPMverify pinned depsNo floating versions
  4. Tool tests — Verify environment tools:

    #ToolTest
    1gitcommit, push, pull
    2python3import mcp, pymongo, dns
    3npxruns without download delay
    4uvxruns without download delay
    5tsxruns without download delay
  5. Record all test results in State 4


Task 4 — Upgrade Node.js from v20 to v22

The current Dockerfile uses FROM node:20-slim, which provides Node.js 20.20.2. Astro 6 (used by the documentation site at .internal/) requires Node ≥22.12.0. The current astro check and astro build commands fail with: Node.js v20.20.2 is not supported by Astro! Please upgrade Node.js to a supported version: ">=22.12.0". This blocks the sidebar build verification step and any future Astro upgrades. Node 20 is also approaching EOL (April 2026 for the 20.x LTS line).

  1. Update Forge/Configs-debian/Dockerfile.librechat:
    • Change FROM node:20-slim (both builder and runtime stages) to FROM node:22-slim
    • Verify the 3-stage build pattern still works: source (Alpine) → builder (Node 22) → runtime (Node 22)
    • The source stage still uses the Alpine LibreChat image (ghcr.io/danny-avila/librechat:v0.8.5-rc1) — this is fine, it only copies /app
  2. Rebuild and push the Docker image locally:
    • docker build --pull --platform linux/amd64 -f Dockerfile.librechat -t ghcr.io/erikdakoda/librechat-git:debian-slim .
    • Verify Node version: docker run --rm ghcr.io/erikdakoda/librechat-git:debian-slim node --versionv22.x.x
    • Push: docker push ghcr.io/erikdakoda/librechat-git:debian-slim
  3. Redeploy on Railway and verify:
    • Container starts successfully with Node 22
    • LibreChat serves correctly
    • All MCP servers start (Node 22 may have different native module requirements — npm rebuild in the builder stage handles this)
    • astro check and astro build now succeed inside the container
  4. Update Forge_Infrastructure.md to reflect Node 22
  5. Verify npm install -g for pre-installed packages (Task 2) works on Node 22

Task 5 — Update infrastructure documentation

Reflect all changes from Tasks 1–3 in Forge_Infrastructure.md.

  1. Update “MCP Server Details” section with any startup behavior changes
  2. Update “Debian-slim Container Notes” with the list of pre-installed global npm packages
  3. Document the startup: false strategy for MCP servers
  4. Document the railway_env.py injection pattern as the standard for Python MCP servers
  5. Remove or update any outdated Alpine-specific references

Task 5 — Create State document

Create the State document tracking this Plan’s tasks for the implementing agent.

  1. Copy Forge/Skills/Project_Create/templates/State_Template.md to Container_Base_Image_State_4.md
  2. Convert each Task in this Plan into a checkbox item, with subtasks as nested checkboxes
  3. Set the Related plan link to point to this Plan document