Skip to content

feat: add MCP control server to Quay - #52

Merged
dhhieu113pro merged 47 commits into
mainfrom
feat/mcp-server
Sep 6, 2026
Merged

dhhieu113pro merged 47 commits into
mainfrom
feat/mcp-server

Conversation

@dhhieu113pro

Copy link
Copy Markdown
Owner

Summary

Adds the approved design and implementation plan for making Quay controllable by MCP-capable LLMs and agents.

Target architecture:

  • embedded Rust MCP 2026-07-28 Streamable HTTP server using official rmcp 3.x
  • localhost-only endpoint
  • structured quay.* tools over the existing Quay/WSLC backend
  • destructive actions require one-shot human approval
  • MCP calls are audited with secret redaction
  • no generic shell / quay.exec capability in v1

Plan

Implementation follows docs/superpowers/plans/2026-09-06-quay-mcp-server.md using TDD and staged commits.

This PR will be updated with implementation commits and verification results before merge.

@dhhieu113pro
dhhieu113pro marked this pull request as ready for review September 6, 2026 01:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2331ede842

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/operations/mod.rs Outdated
Comment on lines +72 to +73
fs::rename(&temp_path, path)
.map_err(|error| OperationError::backend_failure(format!("could not replace MCP config: {error}")))?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Replace existing MCP config safely on Windows

On Windows, std::fs::rename does not replace an existing destination, so after the first successful save creates mcp.json, every later toggle or port update fails here. In particular, a user who enables MCP cannot disable it through the UI; a failed port update can also leave the newly started runtime detached because it is created before this save fails. Use a Windows-safe atomic replacement strategy.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in follow-up PR #53. MCP config replacement now uses Windows MoveFileExW with MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH, with a repeated-save regression test. The same safe replacement path is also used for Cube registry persistence.

Comment on lines +124 to +126
"quay.cube.list" | "quay.cube.inspect" | "quay.cube.start" | "quay.cube.stop" | "quay.cube.create" | "quay.cube.clone" => {
Err(OperationError::backend_failure("Cube definitions are still frontend-owned; backend cube synchronization is required before MCP cube execution"))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Wire the advertised Cube tools to their implementation

The server publishes the Cube tools in list_tools, but every non-delete Cube invocation is unconditionally rejected by this branch, while quay.cube.delete is likewise rejected below. Consequently MCP clients cannot list, inspect, start, stop, create, clone, or delete Cubes despite these being advertised capabilities; the added cube_tools.rs implementation is not declared or dispatched anywhere.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in follow-up PR #53. cube_tools is now registered in the MCP module and server.rs routes all quay.cube.* calls to the Cube adapter, including destructive delete after confirmation. Added regression coverage for the routing.

Comment on lines +45 to +47
} catch (error) {
toast.error(error instanceof Error ? error.message : "Could not resolve MCP action");
} finally {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear confirmation dialogs after requests expire

If the user responds after the 60-second backend timeout, mcpConfirm returns a conflict and this catch leaves the expired request selected. The controlled dialog then cannot be approved, rejected, or dismissed, and later pending requests remain inaccessible behind it. Clear the stale request and fetch the next pending confirmation on this error path.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in follow-up PR #53. The dialog now clears the stale request and reloads the next pending confirmation on both success and error paths, so an expired backend request cannot block the queue.

@dhhieu113pro
dhhieu113pro merged commit 0d96845 into main Sep 6, 2026
2 checks passed
@dhhieu113pro
dhhieu113pro deleted the feat/mcp-server branch September 6, 2026 02:04
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.

1 participant