feat(agent): template referencing for mcp integrations - #3125
feat(agent): template referencing for mcp integrations#3125jordan-umusu wants to merge 1 commit into
Conversation
|
✅ No security or compliance issues detected. Reviewed everything up to 07b9fc8. Security Overview
Detected Code Changes
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 90a3516437
ℹ️ 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".
90a3516 to
e86a5b8
Compare
e86a5b8 to
ba9fb57
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba9fb57720
ℹ️ 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".
| vars_map = await get_workspace_variables( | ||
| variable_exprs=collected.variables, | ||
| role=role, |
There was a problem hiding this comment.
Thread action environment into MCP variable resolution
HTTP MCP header templates now resolve VARS.*, but this helper fetches variables without the effective workflow/action environment. build_agent_args_activity computes that environment for normal agent args (tracecat/dsl/action.py:694-705), then resolves MCP integrations with only the role (tracecat/dsl/action.py:715-717), and get_workspace_variables(..., environment=None) searches all environments. If a workspace has the same variable name in default and an overridden environment, the new remote header expression can pick the wrong value or depend on DB row order, sending credentials or tenant headers for another environment; thread the resolved environment through this MCP resolution path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a48d133173
ℹ️ 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".
| secrets = await secrets_manager.get_action_secrets( | ||
| secret_exprs=collected.secrets, | ||
| action_secrets=set(), | ||
| ) |
There was a problem hiding this comment.
Resolve MCP secrets from the effective environment
When an MCP header or stdio env value references SECRETS.* and the action/workflow runs outside the default environment, this lookup still uses secrets_manager.get_action_secrets() without applying effective_environment; that helper fetches via AuthSandbox(environment=get_runtime_env()), and these MCP trusted-edge/activity paths do not set ctx_run to the action override. The adjacent VARS lookup is environment-scoped, so a mixed header like Authorization: ${{ SECRETS.api.TOKEN }} and X-Tenant: ${{ VARS.tenant.id }} can send a staging tenant with a default-environment credential.
Useful? React with 👍 / 👎.
| if environment is not None: | ||
| http_ref["environment"] = environment |
There was a problem hiding this comment.
Carry preset-agent environments into MCP refs
The new ref field is only populated when environment is passed, but preset-backed agents never pass their effective action environment when resolving the preset's saved mcp_integrations (_version_to_agent_config() still calls resolve_mcp_integration_refs(version.mcp_integrations) with no environment). In an ai.preset_agent step that overrides environment and uses a preset MCP server with VARS.* or environment-scoped SECRETS.* in headers/env, the trusted edge will re-resolve from the default environment instead of the action environment, selecting the wrong tenant or credentials.
Useful? React with 👍 / 👎.
a48d133 to
07b9fc8
Compare
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |

Summary by cubic
Adds environment-aware templating for MCP integrations. Remote header values and
stdioenv vars now resolve${{ SECRETS.* }}and${{ VARS.* }}at runtime with strict, fail‑closed behavior; OAuth Authorization stays authoritative.authorizationis dropped when OAuth is used, and unresolved/malformed templates raiseMCPConfigurationErrorinstead of being sent.stdioMCP env values using a shared, strict resolver; missing or invalid references fail closed and literals are preserved.resolve_templated_mappingadds environment‑scoped resolution, value‑only mode for headers, reference counting, and sanitized errors; used by the MCP HTTP resolver and presetstdioenv resolution. Extra guard rejects any header that still contains${{ ... }}.@SECRETS/@VARSautocomplete with template pills;CodeEditorsupportsadditionalExtensionsand disables default completion when provided. Docs updated to reflect header value templating.Written for commit 07b9fc8. Summary will update on new commits.