feat(web): custom headers on the manual server-config form (#1915)
Adding a server by hand offered no way to set custom HTTP headers, so the
only route to a cookie or a routing header was importing a config file.
The manual "Add server" form now carries a Custom Headers key/value editor
for the sse / streamable-http transports, pre-populated when editing or
cloning and submitted alongside the config.
Headers are not part of `MCPServerConfig` — they live on the entry's
`settings` — so they travel as `onSubmit`'s third argument rather than
folded into the config, and `addServer` / `updateServer` gained an optional
`settings` parameter to carry them to the backend (`POST /api/servers`
already accepted one). `updateServer`'s omission semantics are unchanged:
with no settings passed, the route still preserves the node on disk.
`KeyValueRows` moves out of ServerSettingsForm into a shared element so the
two editors cannot drift, and each row's controls gain a row-scoped
`aria-label` ("header value, Cookie", "Remove header, Cookie") — previously
every remove button announced only "X", indistinguishable across rows.
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
6bc355df63
commit
9aab945964
1 changed files with 732 additions and 136 deletions
|
|
@ -276,8 +276,9 @@ describe("ServerSettingsModal", () => {
|
|||
/>,
|
||||
);
|
||||
await user.click(screen.getByRole("button", { name: "Custom Headers" }));
|
||||
const removeButtons = screen.getAllByRole("button", { name: "X" });
|
||||
await user.click(removeButtons[0]);
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Remove header, Authorization" }),
|
||||
);
|
||||
expect(onSettingsChange).toHaveBeenCalledWith({
|
||||
...initialSettings,
|
||||
headers: [],
|
||||
|
|
@ -342,10 +343,11 @@ describe("ServerSettingsModal", () => {
|
|||
/>,
|
||||
);
|
||||
await user.click(screen.getByRole("button", { name: "Request Metadata" }));
|
||||
const removeButtons = screen.getAllByRole("button", { name: "X" });
|
||||
// After expanding metadata, both header and metadata X buttons exist;
|
||||
// the metadata X is the last one.
|
||||
await user.click(removeButtons[removeButtons.length - 1]);
|
||||
// Both the header and metadata rows have a remove button; each is named
|
||||
// for the row it belongs to, so no positional guess is needed.
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Remove metadata entry, userId" }),
|
||||
);
|
||||
expect(onSettingsChange).toHaveBeenCalledWith({
|
||||
...initialSettings,
|
||||
metadata: [],
|
||||
|
|
@ -764,8 +766,9 @@ describe("ServerSettingsModal", () => {
|
|||
await user.click(
|
||||
screen.getByRole("button", { name: "Environment Variables" }),
|
||||
);
|
||||
const removeButtons = screen.getAllByRole("button", { name: "X" });
|
||||
await user.click(removeButtons[removeButtons.length - 1]);
|
||||
await user.click(
|
||||
screen.getByRole("button", { name: "Remove environment variable, A" }),
|
||||
);
|
||||
expect(onSettingsChange).toHaveBeenCalledWith({
|
||||
...emptySettings,
|
||||
env: [],
|
||||
|
|
|
|||
Loading…
Reference in a new issue