You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .planning/PROJECT.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,6 +39,7 @@ authenticate, authorize, audit, and proxy every tool call in the company.
39
39
- ✓ Upstream tool discovery and proxy (Phase 02) - `tools/list` and `tools/call` forwarded to correct upstream provider; upstream tools namespaced by provider; `NotificationQueue` with TTL eviction for `tools/list_changed` replay on reconnect; `sendToClient` SSE real-time dispatch
40
40
- ✓ API key authentication gate (Phase 03) - inbound M2M clients validated via inline env-var API keys before session establishment; `ClientAuthGate` runs after enterprise auth, before any upstream connection; `SessionData.clientPrincipal` populated with resolved identity (`subject`, `authType`, `scopes`); HMAC-SHA256 timing-safe comparison; fail-fast profile-load validator
41
41
- ✓ upstream_mcp singular constraint (Phase 03.1) - Profile.upstream_mcp narrowed from UpstreamMcpServerConfig[] to UpstreamMcpServerConfig; Zod schema rejects array shape at parse time with migration hint; all call sites (mcp-server.ts, http-transport.ts, profile-resolver.ts) narrowed; BREAKING CHANGE: profile JSON must use `upstream_mcp: {...}` not `upstream_mcp: [{...}]`
42
+
- ✓ Admin-supplied HTML profile descriptions (Phase 03.2) - `MCP4_PROFILES_DESCRIPTION` env var (JSON object: profile key → HTML string) parsed once at startup; keys matched against profileId/profileName/aliases; resolved adminDescription stored per-profile and rendered raw (no escaping) in HTML index detail card before the profile's own description; duplicate-key resolution and invalid JSON cause process exit at startup (fail-fast); sidebar list view unchanged
42
43
43
44
### Active
44
45
-[ ] Upstream tool discovery and proxy - tools/list and tools/call forwarded to correct upstream
@@ -110,7 +111,7 @@ authenticate, authorize, audit, and proxy every tool call in the company.
110
111
| Tool namespacing by upstream provider | Prevents tool name collisions across providers; makes audit logs and policy rules unambiguous | - Pending |
111
112
112
113
---
113
-
*Last updated: 2026-05-02 after Phase 03.1 completion — upstream_mcp narrowed from array to singular; BREAKING CHANGE for profile JSON format*
114
+
*Last updated: 2026-05-03 after Phase 03.2 completion — MCP4_PROFILES_DESCRIPTION env var for admin HTML profile descriptions; fail-fast startup validation; raw-HTML rendering in detail card*
### Phase 03.2: Profile env-var description field (INSERTED)
74
+
75
+
**Goal:** Add optional admin-supplied HTML description per profile via a server-wide `MCP4_PROFILES_DESCRIPTION` env var (JSON map of profile-id/name/alias → HTML string). Description renders raw (no sanitization) in the HTML index detail card immediately before the profile's own description. Sidebar list view is unchanged. Fail-fast at startup on invalid JSON or duplicate-resolution conflicts.
76
+
**Requirements**: TBD (locked decisions D-01..D-12 in 03.2-CONTEXT.md serve as acceptance criteria)
77
+
**Depends on:** Phase 03
78
+
**Plans:** 3/3 plans complete
79
+
80
+
Plans:
81
+
-[x] 03.2-01-PLAN.md — Pure module: parseProfilesDescriptionEnv + resolveProfileAdminDescriptions helpers + unit tests (D-01..D-09)
-[x] 03.2-03-PLAN.md — HTML template patch: raw-HTML adminDescription div in renderDetail before profile.description; sidebar untouched; end-to-end raw-HTML pass-through tests (D-06, D-10, D-11, D-12)
84
+
73
85
### Phase 03.1: Odstranění multi upstream mcp supportu (INSERTED)
74
86
75
87
**Goal**: Profile.upstream_mcp narrowed end-to-end from UpstreamMcpServerConfig[] to UpstreamMcpServerConfig (singular). The runtime single-provider constraint already exists in profile-loader (D-03 check); this phase relocates it into the type system (Zod + TS), removes the now-dead loader runtime check, and migrates all consumers + test fixtures to the singular shape. Breaking change for end-user profile JSON/YAML using array syntax.
Copy file name to clipboardExpand all lines: .planning/STATE.md
+18-10Lines changed: 18 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,13 +3,13 @@ gsd_state_version: 1.0
3
3
milestone: v1.0
4
4
milestone_name: milestone
5
5
status: Ready to plan
6
-
stopped_at: Phase 03.2 context gathered
7
-
last_updated: "2026-05-03T20:29:04.939Z"
6
+
stopped_at: Completed 03.2-03-PLAN.md
7
+
last_updated: "2026-05-03T22:56:32.129Z"
8
8
progress:
9
9
total_phases: 7
10
-
completed_phases: 4
11
-
total_plans: 14
12
-
completed_plans: 14
10
+
completed_phases: 5
11
+
total_plans: 17
12
+
completed_plans: 17
13
13
---
14
14
15
15
# Project State
@@ -19,11 +19,11 @@ progress:
19
19
See: .planning/PROJECT.md (updated 2026-03-26)
20
20
21
21
**Core value:** A security boundary between internal AI clients and all upstream MCP servers - one place to authenticate, authorize, audit, and proxy every tool call.
@@ -98,6 +101,11 @@ Recent decisions affecting current work:
98
101
-[Phase 03.1-odstran-n-multi-upstream-mcp-supportu]: validateUpstreamProvider path changed to 'upstream_mcp' (no [N] index) - all error paths are now upstream_mcp.transport.url, upstream_mcp.auth.header_name, etc.
99
102
-[Phase 03.1-odstran-n-multi-upstream-mcp-supportu]: hasUpstreamMcpFlag lives in upstream-mcp-config.ts (semantic owner of all upstream_mcp logic) not profile-resolver.ts
100
103
-[Phase 03.1-odstran-n-multi-upstream-mcp-supportu]: Legacy-array tolerance preserved at MIGRATION-CLEANUP sites: env-var collector (reads raw JSON pre-Zod) and hasUpstreamMcpFlag (list-view UX) for migration period
104
+
-[Phase 03.2-profile-env-var-description]: Parse-time D-05 conflict detection skipped: profile list unavailable at parse time; deferred to resolveProfileAdminDescriptions which receives both map and profiles
105
+
-[Phase 03.2-profile-env-var-description]: adminDescription field rides inside existing safeJsonForHtml(enriched) blob — no separate template variable needed; Plan 03 reads it client-side from the JSON payload
106
+
-[Phase 03.2-profile-env-var-description]: null -> undefined conversion at HttpTransport call site (this.profileAdminDescriptions ?? undefined) so setter accepts Map|null while buildProfileIndexPayload signature uses Map|undefined
107
+
-[Phase 03.2-profile-env-var-description]: Admin description inserted between profile-title and profile-subtitle via ternary (not ||) — both undefined and empty string suppress the div
108
+
-[Phase 03.2-profile-env-var-description]: safeJsonForHtml escapes only '<' not '>'; test assertions must use literal '>' for tag closings in expected rendered output
0 commit comments