Skip to content

feat(codex): support MCP workspace file uploads - #558

Open
wanghaojie124 wants to merge 2 commits into
OpenCSGs:mainfrom
wanghaojie124:dev
Open

feat(codex): support MCP workspace file uploads#558
wanghaojie124 wants to merge 2 commits into
OpenCSGs:mainfrom
wanghaojie124:dev

Conversation

@wanghaojie124

Copy link
Copy Markdown
Collaborator
  • add a turn-scoped dynamic tool for uploading workspace files to configured MCP servers
  • validate workspace paths, upload sizes, content types, same-origin targets, redirects, and cancellation
  • guard unresolved runtime input files before media-type handling
  • localize the AGENT-ERR-25 pending sensitive-check response in the Web UI
  • extend runtime and frontend coverage for the new behavior

- add a turn-scoped dynamic tool for uploading workspace files to configured MCP servers
- validate workspace paths, upload sizes, content types, same-origin targets, redirects, and cancellation
- guard unresolved runtime input files before media-type handling
- localize the AGENT-ERR-25 pending sensitive-check response in the Web UI
- extend runtime and frontend coverage for the new behavior
@xxx7xxxx

xxx7xxxx commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Will handle this issue after #557 is merged.

@xxx7xxxx

xxx7xxxx commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

@wanghaojie124 Please fix the conflict

@wanghaojie124

Copy link
Copy Markdown
Collaborator Author

Resolved the conflicts against the latest origin/main and pushed the merge commit to the dev branch. The full go test ./... suite passes.

if !ok {
return appServerDynamicToolResponse(false, "file upload is unavailable outside an active turn"), nil
}
if err := uploadAppServerWorkspaceFile(uploadCtx, live.spec, args); err != nil {

@xxx7xxxx xxx7xxxx Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Enforce read-only mode before executing uploads

This branch executes host filesystem reads and HTTP PUTs even when live.spec.ExecutionMode is read_only. EnsureEngineSession registers the upload tool for read-only agents too, bypassing that mode's filesystem deny policy and rejection of external mutations. A local reproduction through the dynamic request handler successfully uploaded workspace contents from a read-only session. Reject uploads in read-only mode and omit this tool from its registration.

if err := json.Unmarshal(params.Arguments, &args); err != nil {
return appServerDynamicToolResponse(false, "invalid upload arguments"), nil
}
uploadCtx, ok := live.appServerTurnContext(params.ThreadID)

@xxx7xxxx xxx7xxxx Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bind upload contexts to the requesting turn

Server requests run asynchronously, so a delayed request from canceled turn A can execute after turn B starts on the same thread. This lookup ignores params.TurnID, retrieves B's uncanceled context, and performs A's upload. A deterministic reproduction using the asynchronous dispatch path confirms that the HTTP PUT succeeds in this interleaving. Validate both thread and turn IDs and atomically retrieve the matching active context.

return fmt.Errorf("open Runtime workspace: %w", err)
}
defer root.Close()
file, err := root.Open(cleaned)

@xxx7xxxx xxx7xxxx Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reject non-regular files without a blocking open

root.Open blocks when the workspace path refers to a FIFO without a writer, before the regular-file check or HTTP timeout can apply. Canceling the turn also cannot interrupt that open. A local FIFO reproduction remains blocked after cancellation and returns only after a writer connects. Use a nonblocking open with descriptor validation, or another race-safe approach that rejects special files without waiting for a writer.

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