-
Notifications
You must be signed in to change notification settings - Fork 615
[FEATURE][UI]: Flexible UI sections for embedded contextsΒ #2075
Description
ποΈ Feature: Flexible UI Sections for Embedded Contexts
Goal
Enable the Admin UI to be embedded in external applications with configurable section visibility. Operators can hide sections (logout, team selector, prompts, resources) without breaking navigation, and hidden sections won't load unnecessary data.
Why Now?
- Embedding Requirements: Partners want to embed CF UI in their platforms with customized navigation
- White-Label Support: Some deployments need minimal UI without team management features
- Performance: Hidden sections shouldn't trigger data loading (API calls, DB queries)
- Security: Embedded contexts may need to hide sensitive controls like logout or team switching
π User Stories
US-1: Operator - Configure Hidden Sections via Environment
As a Platform Operator deploying Context Forge
I want to configure which UI sections are hidden via environment variables
So that I can customize the UI for my deployment without code changes
Acceptance Criteria:
Scenario: Hide specific sections via environment variable
Given MCPGATEWAY_UI_HIDE_SECTIONS="prompts,resources,teams"
When the Admin UI loads
Then the navigation should not show "Prompts", "Resources", or "Teams" tabs
And navigating to "#prompts" via URL should redirect to the default section
And no API calls should be made to /prompts, /resources, or /teams endpoints
Scenario: Hide header items via environment variable
Given MCPGATEWAY_UI_HIDE_HEADER_ITEMS="logout,team_selector"
When the Admin UI loads
Then the header should not show the logout button
And the header should not show the team selector dropdown
And the user identity (email) should still be visible
Scenario: Embedded mode enables default hides
Given MCPGATEWAY_UI_EMBEDDED=true
And no other hide settings are configured
When the Admin UI loads
Then logout and team_selector should be hidden by default
And all navigation sections should still be visibleTechnical Requirements:
- Add
MCPGATEWAY_UI_EMBEDDEDboolean setting - Add
MCPGATEWAY_UI_HIDE_SECTIONSCSV setting - Add
MCPGATEWAY_UI_HIDE_HEADER_ITEMSCSV setting - Apply settings in
admin.pycontext and Jinja templates
US-2: Operator - Override Visibility per Request
As a Platform Operator
I want to override visibility settings via URL parameters
So that different embedded contexts can have different configurations
Acceptance Criteria:
Scenario: URL parameter hides additional sections
Given MCPGATEWAY_UI_HIDE_SECTIONS is not set
When I navigate to "/admin?ui_hide=prompts,resources"
Then prompts and resources tabs should be hidden
And the setting should persist for the session
Scenario: URL parameter combines with environment setting
Given MCPGATEWAY_UI_HIDE_SECTIONS="teams"
When I navigate to "/admin?ui_hide=prompts"
Then both "teams" and "prompts" should be hidden
Scenario: Invalid section names are ignored
Given I navigate to "/admin?ui_hide=invalid_section,tools"
When the page loads
Then "tools" should be hidden
And no error should occur for "invalid_section"Technical Requirements:
- Parse
ui_hidequery parameter - Merge with environment settings
- Store in session or pass through all navigation
US-3: Developer - Hidden Sections Don't Load Data
As a Developer optimizing performance
I want hidden sections to not trigger API calls
So that the UI loads faster and doesn't fetch unnecessary data
Acceptance Criteria:
Scenario: Hidden section data not loaded
Given MCPGATEWAY_UI_HIDE_SECTIONS="prompts,resources"
When the Admin UI loads
Then no XHR requests should be made to /admin/prompts/*
And no XHR requests should be made to /admin/resources/*
And the network tab should show fewer requests
Scenario: Navigating to hidden section via hash is blocked
Given prompts section is hidden
When I manually change URL to "#prompts"
Then I should be redirected to the default visible section
And no prompt data should be loadedTechnical Requirements:
- Check visibility config before triggering HTMX loads
- Block hash navigation to hidden sections
- Remove hidden sections from Alpine.js tab state
US-4: Admin - Non-Admin Sections Remain Hidden
As a Non-Admin User
I want admin-only sections to remain hidden
So that the existing permission-based visibility is preserved
Acceptance Criteria:
Scenario: Non-admin user doesn't see admin sections
Given a user without is_admin=true
And no UI hide settings configured
When the user accesses the Admin UI
Then admin-only sections should not be visible
And this behavior should not change with embedded mode
Scenario: Embedded mode doesn't override permission checks
Given MCPGATEWAY_UI_EMBEDDED=true
And a non-admin user
When the user accesses the Admin UI
Then admin-only sections should still be hidden
And embedded mode hides only apply on top of permission checksTechnical Requirements:
- Visibility config is additive to existing permission checks
- Never show sections user doesn't have permission for
- Admin flag check happens before visibility config
π Architecture
Visibility Configuration Model
flowchart TD
A[Environment Variables] --> D[Visibility Config]
B[URL Parameters] --> D
C[User Permissions] --> E[Final Visibility]
D --> E
subgraph "Environment"
A1[MCPGATEWAY_UI_EMBEDDED]
A2[MCPGATEWAY_UI_HIDE_SECTIONS]
A3[MCPGATEWAY_UI_HIDE_HEADER_ITEMS]
end
subgraph "Request"
B1[?ui_hide=prompts,teams]
end
subgraph "Permission Check"
C1[is_admin check]
C2[team membership]
end
Configuration Hierarchy
1. Built-in defaults (nothing hidden)
2. MCPGATEWAY_UI_EMBEDDED=true applies default embedded hides
3. MCPGATEWAY_UI_HIDE_SECTIONS adds to hidden list
4. MCPGATEWAY_UI_HIDE_HEADER_ITEMS adds to hidden header items
5. ?ui_hide= URL parameter adds more hides
6. Permission checks (is_admin) always enforced on top
Configurable Sections
| Section ID | Tab Name | Can Hide |
|---|---|---|
servers |
Servers | Yes |
gateways |
Gateways | Yes |
tools |
Tools | Yes |
prompts |
Prompts | Yes |
resources |
Resources | Yes |
teams |
Teams | Yes |
users |
Users | Yes (admin only anyway) |
agents |
A2A Agents | Yes |
tokens |
API Tokens | Yes |
settings |
Settings | Yes |
Configurable Header Items
| Item ID | Element | Can Hide |
|---|---|---|
logout |
Logout button | Yes |
team_selector |
Team dropdown | Yes |
user_identity |
Email display | Yes |
theme_toggle |
Dark/light toggle | Yes |
π Implementation Tasks
Phase 1: Configuration Settings
- Add
MCPGATEWAY_UI_EMBEDDED: bool = Falseto config.py - Add
MCPGATEWAY_UI_HIDE_SECTIONS: List[str] = []to config.py - Add
MCPGATEWAY_UI_HIDE_HEADER_ITEMS: List[str] = []to config.py - Add field validators for valid section/header item names
- Document settings in
.env.example
Phase 2: Backend Context
- Create
get_ui_visibility_config()function in admin.py - Parse
ui_hidequery parameter from request - Merge environment settings with URL overrides
- Pass visibility config to Jinja template context
- Apply embedded mode defaults when enabled
Phase 3: Template Updates
- Update
admin.htmlnavigation to check visibility config - Conditionally render tabs based on
hidden_sections - Update header to check
hidden_header_items - Remove HTMX triggers for hidden sections
- Add default section redirect logic
Phase 4: JavaScript Updates
- Update Alpine.js tab component to exclude hidden sections
- Block hash navigation to hidden sections
- Add redirect to default section when hidden section accessed
- Ensure no API calls for hidden sections
Phase 5: Testing
- Unit tests for visibility config parsing
- Unit tests for config merging logic
- Playwright tests for hidden sections not appearing
- Playwright tests for hash redirect behavior
- Playwright tests for no API calls to hidden sections
- Test embedded mode defaults
βοΈ Configuration Example
# .env.example additions
# Enable embedded mode (hides logout and team_selector by default)
MCPGATEWAY_UI_EMBEDDED=false
# Comma-separated list of sections to hide
# Valid values: servers, gateways, tools, prompts, resources, teams, users, agents, tokens, settings
MCPGATEWAY_UI_HIDE_SECTIONS=
# Comma-separated list of header items to hide
# Valid values: logout, team_selector, user_identity, theme_toggle
MCPGATEWAY_UI_HIDE_HEADER_ITEMS=
# Example: Minimal embedded configuration
# MCPGATEWAY_UI_EMBEDDED=true
# MCPGATEWAY_UI_HIDE_SECTIONS=prompts,resources,teams,users,settings
# MCPGATEWAY_UI_HIDE_HEADER_ITEMS=logout,team_selectorβ Success Criteria
- Non-admin users never see admin-only sections (existing behavior preserved)
-
MCPGATEWAY_UI_EMBEDDED=truehides logout and team_selector by default -
MCPGATEWAY_UI_HIDE_SECTIONScorrectly hides specified sections -
MCPGATEWAY_UI_HIDE_HEADER_ITEMScorrectly hides specified header items - Hidden sections are removed from navigation (not just hidden via CSS)
- Hash navigation to hidden sections redirects to default
- Hidden sections do not trigger API calls
- URL parameter
?ui_hide=works and merges with env config - Default UI unchanged when no config is set
- Playwright tests pass for all visibility scenarios
π Definition of Done
- Configuration settings added to config.py
- Backend visibility config logic implemented
- Templates updated with conditional rendering
- JavaScript updated for hash handling
- Unit tests written and passing
- Playwright tests written and passing
- Code passes
make verify - Settings documented in
.env.example - PR reviewed and approved
π Additional Notes
Security Considerations
- Hidden sections are a UI convenience, not a security boundary
- API endpoints still require authentication and authorization
- Hiding "users" section doesn't prevent API access to /admin/users
- For true access control, use RBAC permissions
Performance Impact
- Positive: Fewer API calls when sections hidden
- Positive: Smaller DOM when sections removed
- Neutral: Minimal overhead for visibility config parsing
π Related Issues
- Related to multi-tenant UI customization
- Related to white-label deployment requirements