fix(settings): MCP server add — POST as multipart/form-data, not JSON (#107)
routes/mcp_routes.py declares POST /api/mcp/servers with FastAPI
Form(...) params. The Save handler in static/js/settings.js was
sending application/json, so the Form parser saw no fields and
returned 422 with "Field required" for every input — clicking Save
did nothing visible.
Build a FormData object and let the browser set the multipart
Content-Type. args/env are JSON-stringified per the controller
contract (defaults "[]" / "{}"); bad JSON still falls back to
defaults, same as before.
Also check r.ok and surface non-2xx in the form-status span — the
previous code never checked status, so a 422 looked like success.
Matches the FormData pattern already used in this file (uf-mcp-toggle,
~L4036) for the toggle-enable PATCH against the same controller.
Co-authored-by: Toji <ccryptoji@gmail.com>
This commit is contained in:
@@ -4106,17 +4106,26 @@ async function initUnifiedIntegrations() {
|
||||
el('uf-mcp-cancel').addEventListener('click', () => { formEl.style.display = 'none'; });
|
||||
el('uf-mcp-save').addEventListener('click', async () => {
|
||||
const transport = el('uf-mcp-transport').value;
|
||||
const body = { name: el('uf-mcp-name').value, transport };
|
||||
// routes/mcp_routes.py uses FastAPI Form(...) — send multipart, not JSON.
|
||||
const fd = new FormData();
|
||||
fd.append('name', el('uf-mcp-name').value);
|
||||
fd.append('transport', transport);
|
||||
if (transport === 'stdio') {
|
||||
body.command = el('uf-mcp-cmd').value;
|
||||
try { body.args = JSON.parse(el('uf-mcp-args').value || '[]'); } catch (_) { body.args = []; }
|
||||
try { body.env = JSON.parse(el('uf-mcp-env').value || '{}'); } catch (_) { body.env = {}; }
|
||||
fd.append('command', el('uf-mcp-cmd').value);
|
||||
let args = '[]'; try { args = JSON.stringify(JSON.parse(el('uf-mcp-args').value || '[]')); } catch (_) {}
|
||||
let env = '{}'; try { env = JSON.stringify(JSON.parse(el('uf-mcp-env').value || '{}')); } catch (_) {}
|
||||
fd.append('args', args);
|
||||
fd.append('env', env);
|
||||
} else {
|
||||
body.url = el('uf-mcp-url').value;
|
||||
fd.append('url', el('uf-mcp-url').value);
|
||||
}
|
||||
try {
|
||||
await fetch('/api/mcp/servers', { method: 'POST', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
||||
el('uf-mcp-msg').textContent = 'Saved'; formEl.style.display = 'none'; await renderList();
|
||||
const r = await fetch('/api/mcp/servers', { method: 'POST', credentials: 'same-origin', body: fd });
|
||||
if (r.ok) {
|
||||
el('uf-mcp-msg').textContent = 'Saved'; formEl.style.display = 'none'; await renderList();
|
||||
} else {
|
||||
el('uf-mcp-msg').textContent = `Failed (${r.status})`;
|
||||
}
|
||||
} catch (_) { el('uf-mcp-msg').textContent = 'Failed'; }
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user