feat: add opt-in Coder identity headers for MCP servers (#25153)

This commit is contained in:
Kyle Carberry
2026-05-12 08:54:53 -04:00
committed by GitHub
parent f1d160c7f4
commit b0b07536fc
22 changed files with 563 additions and 58 deletions
+18
View File
@@ -3071,6 +3071,11 @@ export interface CreateMCPServerConfigRequest {
readonly enabled: boolean;
readonly model_intent: boolean;
readonly allow_in_plan_mode: boolean;
/**
* ForwardCoderHeaders, when true, forwards Coder identity
* headers on every outgoing MCP request. See MCPServerConfig.
*/
readonly forward_coder_headers: boolean;
}
// From codersdk/organizations.go
@@ -4775,6 +4780,14 @@ export interface MCPServerConfig {
readonly enabled: boolean;
readonly model_intent: boolean;
readonly allow_in_plan_mode: boolean;
/**
* ForwardCoderHeaders forwards the same Coder identity headers we
* send to LLM providers (X-Coder-Owner-Id, X-Coder-Chat-Id, and the
* optional X-Coder-Subchat-Id and X-Coder-Workspace-Id) to this
* MCP server on every request. Off by default to avoid leaking
* chat identity to third-party servers.
*/
readonly forward_coder_headers: boolean;
readonly created_at: string;
readonly updated_at: string;
/**
@@ -8230,6 +8243,11 @@ export interface UpdateMCPServerConfigRequest {
readonly enabled?: boolean;
readonly model_intent?: boolean;
readonly allow_in_plan_mode?: boolean;
/**
* ForwardCoderHeaders, when set, updates whether Coder identity
* headers are forwarded on every outgoing MCP request.
*/
readonly forward_coder_headers?: boolean;
}
// From codersdk/notifications.go
@@ -707,6 +707,7 @@ const makeMCPServer = (
enabled: overrides.enabled ?? true,
model_intent: overrides.model_intent ?? false,
allow_in_plan_mode: overrides.allow_in_plan_mode ?? false,
forward_coder_headers: overrides.forward_coder_headers ?? false,
created_at: overrides.created_at ?? now,
updated_at: overrides.updated_at ?? now,
auth_connected: overrides.auth_connected ?? false,
@@ -757,6 +757,7 @@ const sampleMCPServers = [
enabled: true,
model_intent: false,
allow_in_plan_mode: false,
forward_coder_headers: false,
auth_connected: true,
created_at: "2025-01-01T00:00:00Z",
updated_at: "2025-01-01T00:00:00Z",
@@ -34,6 +34,7 @@ const createServerConfig = (
enabled: overrides.enabled ?? true,
model_intent: overrides.model_intent ?? false,
allow_in_plan_mode: overrides.allow_in_plan_mode ?? false,
forward_coder_headers: overrides.forward_coder_headers ?? false,
created_at: overrides.created_at ?? now,
updated_at: overrides.updated_at ?? now,
auth_connected: overrides.auth_connected ?? false,
@@ -347,6 +347,7 @@ interface MCPServerFormValues {
enabled: boolean;
modelIntent: boolean;
allowInPlanMode: boolean;
forwardCoderHeaders: boolean;
toolAllowList: string;
toolDenyList: string;
customHeaders: Array<{ key: string; value: string }>;
@@ -377,6 +378,7 @@ const buildInitialValues = (
enabled: server?.enabled ?? true,
modelIntent: server?.model_intent ?? false,
allowInPlanMode: server?.allow_in_plan_mode ?? false,
forwardCoderHeaders: server?.forward_coder_headers ?? false,
toolAllowList: joinList(server?.tool_allow_list),
toolDenyList: joinList(server?.tool_deny_list),
customHeaders: [],
@@ -435,6 +437,7 @@ const ServerForm: FC<ServerFormProps> = ({
enabled: values.enabled,
model_intent: values.modelIntent,
allow_in_plan_mode: values.allowInPlanMode,
forward_coder_headers: values.forwardCoderHeaders,
...(values.authType === "oauth2" && {
oauth2_client_id: values.oauth2ClientID.trim(),
oauth2_client_secret: effectiveOAuth2Secret,
@@ -933,7 +936,8 @@ const ServerForm: FC<ServerFormProps> = ({
Behavior
</h3>
<p className="m-0 text-xs text-content-secondary">
Availability, model intent, and tool governance.
Availability, model intent, identity headers, and tool
governance.
</p>
</div>
{showBehavior ? (
@@ -1017,6 +1021,31 @@ const ServerForm: FC<ServerFormProps> = ({
/>
</div>
<div className="flex items-start justify-between gap-4">
<div className="min-w-0 space-y-1">
<Label
htmlFor={`${formId}-forward-coder-headers`}
className="text-sm font-medium text-content-primary"
>
Forward Coder identity headers
</Label>
<p className="m-0 text-xs text-content-secondary">
When enabled, every outgoing MCP request includes the
Coder owner, chat, subchat, and workspace IDs as
<code>X-Coder-*</code> headers. Off by default. Only
enable for first-party or trusted MCP servers.
</p>
</div>
<Switch
id={`${formId}-forward-coder-headers`}
checked={form.values.forwardCoderHeaders}
onCheckedChange={(v) => {
form.setFieldValue("forwardCoderHeaders", v);
}}
disabled={isDisabled}
/>
</div>
<div className="grid items-start gap-4 sm:grid-cols-2">
<Field
label="Tool Allow List"
@@ -33,6 +33,7 @@ const createServerConfig = (
enabled: overrides.enabled ?? true,
model_intent: overrides.model_intent ?? false,
allow_in_plan_mode: overrides.allow_in_plan_mode ?? false,
forward_coder_headers: overrides.forward_coder_headers ?? false,
created_at: overrides.created_at ?? now,
updated_at: overrides.updated_at ?? now,
auth_connected: overrides.auth_connected ?? false,