Skip to content

feat: Add MCP server#3577

Open
kichristensen wants to merge 3 commits intogetporter:mainfrom
kichristensen:mcpServer
Open

feat: Add MCP server#3577
kichristensen wants to merge 3 commits intogetporter:mainfrom
kichristensen:mcpServer

Conversation

@kichristensen
Copy link
Copy Markdown
Contributor

What does this change

Adds a porter mcp subcommand that starts an MCP (Model Context Protocol) server over stdio, allowing AI coding assistants (Claude Code, Cursor, VS Code Copilot, etc.) to interact with Porter using natural language.

Read-only tools (always available):

  • explain_bundle — show bundle parameters, credentials, outputs, and actions
  • list_installations / show_installation — browse installations
  • list_runs / get_logs — inspect execution history and logs
  • list_outputs / get_output — read run outputs (sensitive values masked)
  • list_credentials / show_credential — browse credential sets
  • list_parameters / show_parameter — browse parameter sets
  • analyze_failure — one-shot failure triage: fetches the last (or a specific) failed run's logs and outputs in a single call

Write tools (opt-in via --allow-write):

  • install_bundle, upgrade_bundle, uninstall_bundle, invoke_bundle

Example usage with Claude Code:

$ porter mcp
# or, to enable write tools:
$ porter mcp --allow-write

Configure in Claude Code:

claude mcp add porter -- porter mcp

What issue does it fix

Closes # (no existing issue)

This capability was identified as a natural fit for Porter: LLM agents can already reason about CNAB bundles conceptually, and exposing Porter's CLI operations as MCP tools lets them act on real installations with full context (logs, outputs, failure analysis) rather than just generating shell commands.

Notes for the reviewer

  • The MCP server uses github.com/modelcontextprotocol/go-sdk (the official Go SDK, v1.4.1).
  • Porter's plugin system starts subprocesses via exec.CommandContext. The MCP SDK cancels per-request contexts after each tool call, which would kill plugin subprocesses between calls. This is fixed by storing the server-lifetime context in MCPServer.ctx and using it for all Porter API calls.
  • porter.Out defaults to os.Stdout, which would corrupt the stdio JSON-RPC stream. It is redirected to os.Stderr in NewMCPServer, with a captureOutput helper that temporarily swaps to a buffer when write-tool output should be returned to the client.

Checklist

  • Did you write tests?
  • Did you write documentation?
  • Did you change porter.yaml or a storage document record? Update the corresponding schema file.
  • If this is your first pull request, please add your name to the bottom of our Contributors list. Thank you for making Porter better! 🙇‍♀️

Signed-off-by: Kim Christensen <kimworking@gmail.com>
License lives at repo root; subpackages have no own LICENSE
files, causing go-licenses to fail. Introduced transitively
via github.com/modelcontextprotocol/go-sdk.

Signed-off-by: Kim Christensen <kimworking@gmail.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new porter mcp CLI subcommand that runs a Model Context Protocol (MCP) server over stdio, exposing Porter read-only (and optionally write) operations as MCP tools for AI clients.

Changes:

  • Introduces a new pkg/mcp package implementing the MCP server and tool handlers (runs/logs, outputs, credentials, parameters, bundle ops, failure analysis).
  • Wires the new porter mcp Cobra command into the CLI and adds documentation pages describing usage and client configuration.
  • Adds the MCP Go SDK dependency and updates license-check workflow ignores.

Reviewed changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
pkg/mcp/server.go Core MCP server wrapper, stdio transport, output capture/masking helpers.
pkg/mcp/tools_bundle.go Registers bundle + installation tools; adds opt-in write tools with output capture.
pkg/mcp/tools_runs.go Adds run listing and log retrieval tools.
pkg/mcp/tools_outputs.go Adds output listing/get tools, including masking/sensitive blocking.
pkg/mcp/tools_creds.go Adds credential set list/show tools.
pkg/mcp/tools_params.go Adds parameter set list/show tools.
pkg/mcp/tools_analyze.go Adds analyze_failure tool aggregating run/log/output context.
cmd/porter/mcp.go Implements the porter mcp subcommand and --allow-write flag.
cmd/porter/main.go Registers the new mcp subcommand on the root command.
docs/content/docs/references/cli/porter.md Adds porter mcp to the CLI reference index.
docs/content/docs/references/cli/mcp.md Adds CLI reference page for porter mcp.
docs/content/docs/how-to-guides/work-with-ai-agents.md Adds a how-to guide for configuring MCP clients with Porter.
docs/content/docs/how-to-guides/_index.md Adds “Working with AI Agents” to the how-to guide cards.
go.mod Adds github.com/modelcontextprotocol/go-sdk v1.4.1 dependency.
go.sum Updates checksums for new dependencies.
.github/workflows/check-licenses.yaml Updates ignored modules list for license checking.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Validate required args server-side in list_runs,
  list_outputs (not just via JSON schema)
- Validate get_logs requires exactly one of
  installation or run_id
- Handle ok=false from GetInstallationLogs in
  analyze_failure
- Verify run ownership when run_id provided in
  analyze_failure
- Document segmentio/asm license in CI ignore comment
- Wrap JSON config example in fenced code block

Signed-off-by: Kim Christensen <kimworking@gmail.com>
@kichristensen kichristensen marked this pull request as ready for review March 27, 2026 22:48
@kichristensen kichristensen requested a review from a team as a code owner March 27, 2026 22:48
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