Skip to content

Make stdio MCPs Editable#1219

Open
grfwings wants to merge 10 commits into
RhysSullivan:mainfrom
grfwings:stdio-mcp-editable
Open

Make stdio MCPs Editable#1219
grfwings wants to merge 10 commits into
RhysSullivan:mainfrom
grfwings:stdio-mcp-editable

Conversation

@grfwings

Copy link
Copy Markdown
Contributor

Makes stdio MCP sources editable via the GUI.

I tried to match existing behavior so it should be pretty intuitive. After a STDIO MCP config is changed, we validate first with tool discovery (require successful tools/list), then if that succeeds run a transaction to remove policies scoped to the integration and update the integration config.

For legacy configs where there are no visible connections, connection org/default with template none and empty values will be created.

@greptile-apps

greptile-apps Bot commented Jun 29, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a full edit UI for stdio MCP sources, replacing the previous read-only view. When process-affecting fields change (command, args, env, cwd), the server runs a preflight tool-discovery check before committing the change in a transaction that also clears source-scoped policies, then does a best-effort tools refresh.

  • New stdio-config.ts module centralises argument and env parsing/formatting with round-trip-safe serialisation for the edit form; EditMcpSource.tsx is upgraded from a read-only display to a fully editable StdioEdit component.
  • Backend (plugin.ts) adds configureServer with preflight + transactional commit + best-effort refresh logic, plus a new refreshServerTools endpoint for retrying a stale tool cache.
  • Semantic change to env: environment variables supplied via env on addServer are now stored as static plaintext config rather than being migrated into a credential connection, and the legacy reconcileStdioConnections migration path has been updated accordingly.

Confidence Score: 5/5

Safe to merge; both findings are edge-case UX gaps, not correctness or data-safety regressions.

The preflight → transaction → best-effort refresh pipeline is well-structured and thoroughly tested. Both findings are minor edge-case gaps that do not affect the primary edit flow.

packages/plugins/mcp/src/sdk/plugin.ts — the zero-connections branch of refreshStdioConnections; packages/plugins/mcp/src/react/EditMcpSource.tsx — the missing retry UI for toolsRefreshFailed.

Important Files Changed

Filename Overview
packages/plugins/mcp/src/sdk/plugin.ts Core configureServer logic added with preflight validation, policy removal, and best-effort tools refresh; zero-connections branch of refreshStdioConnections creates a connection but skips discoverTools.
packages/plugins/mcp/src/sdk/stdio-config.ts New file providing parse/serialize helpers for stdio command args and env; round-trip correctness for single-quoted values is handled via canFormatStdioEnvValueBare identity check.
packages/plugins/mcp/src/react/EditMcpSource.tsx StdioReadOnly replaced with a full StdioEdit form; refreshMcpServerTools atom is exported but no retry button is wired up in this component, leaving the 'retry' user message without a corresponding UI action.
packages/plugins/mcp/src/sdk/plugin.test.ts Good new test coverage for configure + refresh flows, policy clearing, malformed config, missing secrets, and flaky-refresh retry scenarios.
packages/plugins/mcp/src/sdk/connection.ts connectionFailure refactored to an options object and now emits the full command string in the error message for stdio connections.
packages/plugins/mcp/src/react/atoms.ts refreshMcpServerTools atom added; not yet consumed by any component in this PR.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as StdioEdit (UI)
    participant API as configureServer API
    participant Plugin as mcpPlugin
    participant DB as Storage/Policies
    participant Proc as stdio subprocess

    UI->>API: POST /mcp/servers/:slug/config
    API->>Plugin: configureServer(slug, config)
    Plugin->>DB: get integration record
    DB-->>Plugin: current config

    alt process config unchanged
        Plugin->>DB: integrations.update(config)
        Plugin-->>API: toolsRefreshFailed false
    else process config changed
        Plugin->>Proc: preflightStdioConfig discoverTools
        Proc-->>Plugin: tools list OK or error
        alt preflight fails
            Plugin-->>API: error
            API-->>UI: 4xx
        else preflight OK
            Plugin->>DB: transaction removePolicies and update config
            DB-->>Plugin: committed
            Plugin->>Proc: refreshStdioConnections
            Proc-->>Plugin: OK or failure
            Plugin-->>API: toolsRefreshFailed true or false
            API-->>UI: 200
        end
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as StdioEdit (UI)
    participant API as configureServer API
    participant Plugin as mcpPlugin
    participant DB as Storage/Policies
    participant Proc as stdio subprocess

    UI->>API: POST /mcp/servers/:slug/config
    API->>Plugin: configureServer(slug, config)
    Plugin->>DB: get integration record
    DB-->>Plugin: current config

    alt process config unchanged
        Plugin->>DB: integrations.update(config)
        Plugin-->>API: toolsRefreshFailed false
    else process config changed
        Plugin->>Proc: preflightStdioConfig discoverTools
        Proc-->>Plugin: tools list OK or error
        alt preflight fails
            Plugin-->>API: error
            API-->>UI: 4xx
        else preflight OK
            Plugin->>DB: transaction removePolicies and update config
            DB-->>Plugin: committed
            Plugin->>Proc: refreshStdioConnections
            Proc-->>Plugin: OK or failure
            Plugin-->>API: toolsRefreshFailed true or false
            API-->>UI: 200
        end
    end
Loading

Reviews (5): Last reviewed commit: "Don't use lossy args.join for StdioEdit,..." | Re-trigger Greptile

Comment thread packages/plugins/mcp/src/sdk/stdio-config.ts Outdated
Comment thread packages/plugins/mcp/src/sdk/plugin.ts Outdated
Comment thread packages/plugins/mcp/src/sdk/plugin.ts
Comment thread packages/plugins/mcp/src/sdk/stdio-config.ts Outdated
Griffin Evans added 3 commits June 29, 2026 15:18
Comment thread packages/plugins/mcp/src/sdk/plugin.ts Outdated
Griffin Evans added 2 commits June 29, 2026 18:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants