import { PlusIcon, XIcon } from "lucide-react"; import { Button } from "@executor-js/react/components/button"; import { CardStack, CardStackContent, CardStackEntryField, } from "@executor-js/react/components/card-stack"; import { FieldError } from "@executor-js/react/components/field"; import { Input } from "@executor-js/react/components/input"; import { emptyHeaderRow, isValidHeaderName, type McpHeaderRow } from "./request-headers"; // --------------------------------------------------------------------------- // Request headers editor — the name/value pairs sent on every request to a // remote MCP server, including the connection check. // // Deliberately plain: two mono fields and a remove control per row, matching // the metadata voice the rest of the add flow uses. Rows are keyed by index // because the values are fully controlled, exactly as the shared placement // editor does it. // --------------------------------------------------------------------------- export function McpRequestHeadersEditor(props: { readonly rows: readonly McpHeaderRow[]; readonly onChange: (rows: McpHeaderRow[]) => void; /** Re-run the connection check with the headers as typed. */ readonly onTest?: () => void; readonly testing?: boolean; }) { const { rows, onChange } = props; const set = (index: number, patch: Partial): void => onChange(rows.map((row, j) => (j === index ? { ...row, ...patch } : row))); const remove = (index: number): void => onChange(rows.filter((_row, j) => j !== index)); const hasInvalidName = rows.some((row) => !isValidHeaderName(row.name)); return ( {rows.length > 0 && (
{rows.map((row, index) => (
set(index, { name: (e.target as HTMLInputElement).value })} placeholder="CF-Access-Client-Id" className="h-8 min-w-0 flex-1 font-mono text-xs" aria-invalid={isValidHeaderName(row.name) ? undefined : true} /> set(index, { value: (e.target as HTMLInputElement).value })} placeholder="Value" className="h-8 min-w-0 flex-1 font-mono text-xs" />
))}
)} {hasInvalidName && ( A header name cannot contain spaces or a colon. )}
{props.onTest && rows.length > 0 && ( )}

Stored with the integration and sent verbatim. Use these for endpoint-level access tokens, such as a Cloudflare Access service token. A per-account credential belongs in an auth method instead.

); }