Summary
Two modals on /admin/#llm-settings silently fail when clicking the Save button: Add LLM Provider (Providers tab) and Add LLM Model (Models tab). In both cases the modal closes, no provider/model is added, no error toast, no log line — nothing observable.
Root cause
mcpgateway/templates/admin.html has two <form> elements whose inline onsubmit references a bare global, but the bundled admin JS only exposes those handlers under the Admin namespace:
| Line |
Current |
Should be |
| 2081 |
<form id="llm-provider-form" onsubmit="saveLLMProvider(event)"> |
<form id="llm-provider-form" onsubmit="Admin.saveLLMProvider(event)"> |
| 2179 |
<form id="llm-model-form" onsubmit="saveLLMModel(event)"> |
<form id="llm-model-form" onsubmit="Admin.saveLLMModel(event)"> |
admin.js registers both as Admin.saveLLMProvider = saveLLMProvider / Admin.saveLLMModel = saveLLMModel, but neither is exposed as a window global. The bare reference therefore raises ReferenceError. With no return value preventing default, the form falls back to a normal browser submit → GET . → page silently re-renders → modal disappears, nothing is POSTed.
The same template uses onchange="Admin.onLLMProviderTypeChange()" / onchange="Admin.onModelProviderChange()" on the lines right next to these forms, which is consistent with how the bundle actually exposes these functions. Only the onsubmit calls were missed.
A quick scan of the rest of admin.html confirms these are the only two cases: every other inline handler (toggleBulkImportDropdown, submitUserInvitation, closeCreateTeamModal, …) refers to a function that is a real window global. Only saveLLMProvider / saveLLMModel are namespace-mismatched.
Reproduction
- Run
ghcr.io/ibm/mcp-context-forge:1.0.0 (or latest / main).
- Sign in as the platform admin.
- Navigate to
/admin/#llm-settings.
Provider:
4. Click Add Provider, fill Name + select Anthropic + paste any API key.
5. Click Save Provider.
Model (after a provider exists):
6. Switch to Models tab, click Add Model, pick the provider, fill Model ID + Display Name.
7. Click Save Model.
Expected: POST /llm/providers (or /llm/models) → 201 Created; entity appears in the list.
Actual: Modal closes, no network request fires, "0 Total" remains.
DevTools confirmation:
> typeof window.saveLLMProvider // "undefined"
> typeof window.Admin.saveLLMProvider // "function"
> typeof window.saveLLMModel // "undefined"
> typeof window.Admin.saveLLMModel // "function"
> new Function('event','saveLLMProvider(event)')(new Event('submit'))
Uncaught ReferenceError: saveLLMProvider is not defined
Fix
Two-line template change (PR follows): namespace both onsubmit calls.
- <form id="llm-provider-form" onsubmit="saveLLMProvider(event)">
+ <form id="llm-provider-form" onsubmit="Admin.saveLLMProvider(event)">
...
- <form id="llm-model-form" onsubmit="saveLLMModel(event)">
+ <form id="llm-model-form" onsubmit="Admin.saveLLMModel(event)">
Workaround (verified locally)
Bind-mount a patched admin.html with the two lines above. After that, both Save Provider and Save Model correctly fire POST /llm/providers / POST /llm/models → 201.
Affected versions
v1.0.0 (GA, 2026-05-01) — confirmed
main HEAD — same lines, same bug
Environment
- Container:
ghcr.io/ibm/mcp-context-forge:latest (currently == v1.0.0)
- Browser: Chrome (any), but the bug is a server-side template issue, not browser-specific.
- Auth:
PLATFORM_ADMIN user, all RBAC routers loaded normally.
Summary
Two modals on
/admin/#llm-settingssilently fail when clicking the Save button: Add LLM Provider (Providers tab) and Add LLM Model (Models tab). In both cases the modal closes, no provider/model is added, no error toast, no log line — nothing observable.Root cause
mcpgateway/templates/admin.htmlhas two<form>elements whose inlineonsubmitreferences a bare global, but the bundled admin JS only exposes those handlers under theAdminnamespace:<form id="llm-provider-form" onsubmit="saveLLMProvider(event)"><form id="llm-provider-form" onsubmit="Admin.saveLLMProvider(event)"><form id="llm-model-form" onsubmit="saveLLMModel(event)"><form id="llm-model-form" onsubmit="Admin.saveLLMModel(event)">admin.jsregisters both asAdmin.saveLLMProvider = saveLLMProvider/Admin.saveLLMModel = saveLLMModel, but neither is exposed as awindowglobal. The bare reference therefore raisesReferenceError. With no return value preventing default, the form falls back to a normal browser submit →GET .→ page silently re-renders → modal disappears, nothing is POSTed.The same template uses
onchange="Admin.onLLMProviderTypeChange()"/onchange="Admin.onModelProviderChange()"on the lines right next to these forms, which is consistent with how the bundle actually exposes these functions. Only theonsubmitcalls were missed.A quick scan of the rest of
admin.htmlconfirms these are the only two cases: every other inline handler (toggleBulkImportDropdown,submitUserInvitation,closeCreateTeamModal, …) refers to a function that is a realwindowglobal. OnlysaveLLMProvider/saveLLMModelare namespace-mismatched.Reproduction
ghcr.io/ibm/mcp-context-forge:1.0.0(orlatest/main)./admin/#llm-settings.Provider:
4. Click Add Provider, fill
Name+ selectAnthropic+ paste any API key.5. Click Save Provider.
Model (after a provider exists):
6. Switch to Models tab, click Add Model, pick the provider, fill
Model ID+Display Name.7. Click Save Model.
Expected:
POST /llm/providers(or/llm/models) →201 Created; entity appears in the list.Actual: Modal closes, no network request fires, "0 Total" remains.
DevTools confirmation:
Fix
Two-line template change (PR follows): namespace both
onsubmitcalls.Workaround (verified locally)
Bind-mount a patched
admin.htmlwith the two lines above. After that, both Save Provider and Save Model correctly firePOST /llm/providers/POST /llm/models → 201.Affected versions
v1.0.0(GA, 2026-05-01) — confirmedmainHEAD — same lines, same bugEnvironment
ghcr.io/ibm/mcp-context-forge:latest(currently == v1.0.0)PLATFORM_ADMINuser, all RBAC routers loaded normally.