Skip to content

[EPIC][PLUGINS]: External plugin STDIO launch options (cmd/env/cwd) #2535

@crivetimihai

Description

@crivetimihai

🔌 Epic: External Plugin STDIO Launch Options (cmd/env/cwd) for MCP Plugins

Goal

Enable external MCP plugins to run via STDIO with flexible launch options:

  • cmd: full command + args (language-agnostic)
  • env: per‑plugin environment overrides (e.g., PLUGINS_CONFIG_PATH)
  • cwd: working directory for the plugin process

This makes external plugins easy to run without extra infrastructure, while preserving HTTP/SSE options.

Why Now?

External plugins are already supported in ContextForge, but STDIO launch is currently too limited for real-world usage:

  1. Language Diversity: Go/Rust/Node MCP servers are blocked or require wrapper scripts
  2. Local Isolation: STDIO is the simplest isolation mode, but needs per‑plugin env/cwd
  3. Operational Simplicity: Avoid containers and extra HTTP ports for local dev/testing
  4. Parity with MCP Ecosystem: Many MCP servers are delivered as binaries or CLI tools
  5. Reliability: Hardcoding python can break in environments where PATH doesn’t include it

Adding STDIO launch options makes external plugins first‑class and unlocks cross‑language MCP without extra infra.


📖 User Stories

US‑1: Platform Admin - Launch a Go/Rust MCP server via STDIO

As a Platform Administrator
I want to run an external MCP plugin as a local stdio process using a command
So that I can integrate non‑Python plugins without wrapper scripts

Acceptance Criteria:

Given the gateway has an external plugin configured
And the plugin sets:
  mcp:
    proto: STDIO
    cmd: ["/opt/plugins/go-filter", "--config", "/etc/plugin/config.yaml"]
When the gateway starts
Then the plugin process should be spawned using the specified cmd
And the gateway should establish a stdio MCP session
And the plugin hooks should execute successfully
US‑2: Platform Admin - Per‑plugin config using env/cwd

As a Platform Administrator
I want to set plugin‑specific env and cwd for stdio plugins
So that each plugin can load its own config and resources cleanly

Acceptance Criteria:

Given an external plugin configured with
  mcp:
    proto: STDIO
    cmd: ["python", "-m", "my_plugin.server"]
    env:
      PLUGINS_CONFIG_PATH: "/opt/plugins/my_plugin/config.yaml"
    cwd: "/opt/plugins/my_plugin"
When the gateway starts
Then the plugin process runs with the provided env and cwd
And the plugin reads its config successfully
US‑3: Operator - Safe Validation and Clear Errors

As an Operator
I want configuration validation to prevent invalid transport settings
So that misconfiguration fails fast with clear errors

Acceptance Criteria:

Given a plugin with proto: STREAMABLEHTTP
When script/cmd/env/cwd is set
Then validation should fail with a clear error

Given a plugin with proto: STDIO
When both script and cmd are set
Then validation should fail with a clear error
US‑4: Developer - Use STDIO without PATH issues

As a Developer
I want .py scripts to launch using the current interpreter
So that it works even if python isn’t on PATH

Acceptance Criteria:

Given mcp.proto=STDIO and script: path/to/server.py
When the gateway launches the plugin
Then it should use sys.executable for the interpreter

✅ Acceptance Criteria (Epic)

  • cmd, env, cwd supported for mcp.proto=STDIO
  • Transport validation rejects incompatible fields (url vs stdio options)
  • script and cmd are mutually exclusive
  • .py scripts launch via sys.executable
  • Docs updated (architecture + usage + examples)
  • Config schema updated
  • Unit tests cover new behaviors

🧠 Design Notes

Config Shape

plugins:
  - name: "ExternalFilter"
    kind: "external"
    mcp:
      proto: STDIO
      cmd: ["/opt/plugins/go-filter", "--config", "/etc/plugin/config.yaml"]
      env:
        PLUGINS_CONFIG_PATH: "/opt/plugins/config.yaml"
      cwd: "/opt/plugins"

Launch Resolution

  1. If cmd is provided: use cmd[0] + cmd[1:].
  2. Else if script:
    • .pysys.executable + script
    • .shsh + script
    • executable → run directly

Validation Rules

  • STDIO: requires script or cmd (not both)
  • HTTP/SSE: requires url and forbids script/cmd/env/cwd
  • cwd must exist and be a directory
  • env must be a non‑empty dict of strings

🧰 THE WORKS! (Implementation Checklist)

  • Add cmd, env, cwd to MCP client config schema
  • Implement config validation rules
  • Update stdio client to pass env/cwd to process
  • Resolve .py scripts with sys.executable
  • Update docs (architecture + lifecycle + usage examples)
  • Update config schema JSON artifacts
  • Add tests for:
    • cmd validation
    • env/cwd validation
    • .py launch via sys.executable
    • stdio client with cmd
  • Add ADR documenting design decision

🔗 Related

  • ADR: External Plugin STDIO Launch with Command/Env Overrides
  • External plugins via MCP (architecture docs)
  • Plugin framework (loader + registry)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestepicLarge feature spanning multiple issuespluginspythonPython / backend development (FastAPI)

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions