feat(mcp): add official publisher styling (LSC-24) - #1074
Conversation
Co-authored-by: octo-loop-agent <loop@deepminer.com.cn>
Jerry-Xin
left a comment
There was a problem hiding this comment.
Approve — official MCP identification is derived from a reliable server-side signal (visibility === "system"), fails closed, and the badge is purely cosmetic (no authz/trust gating), with creator attribution correctly suppressed.
✅ Highlights
- Official signal is reliable, not spoofable.
isOfficialMcp()inpackages/dmworkmcp/src/utils/publisher.tskeys solely onitem.visibility === "system".visibilityis a server-provided enum (public | private | system), andsystemis not client-settable:toWireParamsomitsvisibilityfrom create/edit payloads (proven bypackages/dmworkmcp/src/api/mcpService.visibility.test.ts). This is exactly the reliable signal recommended on PR #1026, where the sibling skillmarket official-publisher work was flagged 🟡 (non-blocking) for falling back to a spoofable display-name match. Here that pattern is resolved:source: "system"alone is correctly rejected, and any missing/unknown visibility fails closed. - No XSS surface. The badge label renders a static i18n key
t("mcp.card.officialPublisher")via React text nodes; theShieldCheckglyph is an inline SVG. NodangerouslySetInnerHTML, no publisher-provided string or href in the new markup. The official path additionally hides the creator name and creator match reasons. - CSS tokens all defined and dark-mode safe. The new
.wk-mcp-card--officialrules inpackages/dmworkmcp/src/index.cssuse only semantic tokens —--wk-ai-border,--wk-ai-surface,--wk-color-accent,--wk-text-accent— each defined inpackages/dmworkbase/src/theme/semantic.csswith both light and dark blocks. No hardcoded color literals in the new official styling (the only added color literals are a prettier line-wrap of a pre-existingbox-shadowrule). Hover/focus-visible states covered. - i18n complete, no orphans.
card.officialPublisheradded to bothen-US.jsonandzh-CN.jsonand actually consumed. No dead code; existing human/bot/import publisher rendering preserved; no permission/authz change. - Test coverage.
publisher.test.tsandMcpOfficialPublisher.test.tsxcover official rendering, non-system rejection, creator-identity suppression, detail rendering, and keyboard activation.
💬 Non-blocking
packages/dmworkmcp/src/components/McpCard.stories.tsx:14sets the global locale at module load; this can make stories order-dependent. Consider a story decorator or Storybook locale parameter instead.packages/dmworkmcp/src/utils/publisher.test.ts:5could add an explicit unknown-value case (e.g."SYSTEM"/"unknown") to document the fail-closed contract beyondundefined.
Note: the pr-title-lint check is red on title formatting only (not code/tests); worth fixing before merge but not a code-review blocker.
mochashanyao
left a comment
There was a problem hiding this comment.
[Octo-Q · automated review]
Verdict: Approve — no blocking findings; notes below (data-flow traced).
Code Review — PR #1074 (octo-web)
Reviewer: Octo-Q (automated review)
Summary
This PR adds official-publisher styling for MCPs with visibility: "system". A new isOfficialMcp utility gates rendering: official cards show a ShieldCheck icon with a localized "Official publisher" label instead of the creator's identity, and get a distinct border/background treatment via CSS custom properties already established in the theme. The McpVisibility union gains "system" (server-side only — never user-settable in create/edit payloads), and McpSource is extracted into a named type alias. Storybook stories, unit tests, and i18n keys for both locales round out the change.
Verification
Static analysis only at head 941eaa3d55a6b5865edf1ee32cb3071afdf19088; build and tests not executed in this environment.
- ✅ Single source of truth for official check —
isOfficialMcpinpackages/dmworkmcp/src/utils/publisher.ts:3is the only place that comparesvisibility === "system"; bothMcpCard.tsx:94andMcpDetailModal.tsx:270call it. - ✅ Creator identity hidden on all display surfaces —
McpCardsetsowner = nulland passeshideCreator={isOfficial}toMatchReasons;McpDetailModalsetsowner = nulland uses anif (isOfficial)/else if (owner?.botName)/owner?.humanNamecascade that skips human attribution when official. - ✅ Type safety preserved —
McpVisibilityextended to"public" | "private" | "system"atpackages/dmworkmcp/src/types/mcp.ts:246.CreateMcpParams/UpdateMcpParamsintentionally exclude visibility (confirmed bymcpService.visibility.test.ts:21), so users cannot set"system"through the form.McpDetail extends McpListItemso the detail modal inherits thevisibilityfield. - ✅ MatchReasons filtering correct —
hideCreatoratMcpCard.tsx:44filterscreator:*reasons while still surfacingtool:*andusage_example:*matches; test at__tests__/McpOfficialPublisher.test.tsx:80asserts "search" appears but "Internal Admin" does not. - ✅ CSS variables pre-existing —
--wk-ai-border,--wk-ai-surface,--wk-color-accent,--wk-text-accentare all used elsewhere inindex.cssand defined by the theme layer. - ✅ i18n parity —
officialPublisherkey added to bothen-US.json:90andzh-CN.json:90. - ✅ Test coverage —
publisher.test.tscovers all four visibility values (system/public/private/undefined);McpOfficialPublisher.test.tsxcovers card rendering, non-official fallback, keyboard activation, and detail modal. - ✅
McpSourceextraction — inline literal"system" | "space" | "mine"replaced with namedMcpSourcetype attypes/mcp.ts:131; bothMcpListItem.sourceandListMcpParams.sourcesreference it.
Findings
No P0/P1 issues. The change is well-scoped, consistently applied across both display surfaces, and covered by tests that exercise the production rendering path (not just the helper).
Nit — Shared CSS class names across card and modal (McpDetailModal.tsx:276-277)
The detail modal reuses card-specific class names (wk-mcp-card__owner-name, wk-mcp-card__owner-official-icon) for its official-publisher row. This works today but creates a silent coupling: a future card restyle that changes font-size or icon sizing under those selectors would also affect the modal. Not blocking — the shared classes are purely presentational and the alternative (duplicating rules) is worse — but worth noting if the card and modal styles diverge later.
Things I checked that are fine
resolveOwneris still exported and used by non-official paths; skipping it for official items is a clean short-circuit, not a mutation.invalidVisibilityi18n string ("Visibility must be Public or Only me") is unaffected — "system" is server-set and never appears in user forms.McpMarketListPage.tsx:431passesvisibilitythrough without special handling, which is correct (data relay, not rendering).- CSS whitespace-only changes at
index.css:563and:864-865are harmless formatting normalization. - Storybook stories correctly import and register i18n namespace before rendering, matching the production i18n setup path.
Data-Flow Traceback
| Consumed data | Upstream source | Verified flow |
|---|---|---|
item.visibility |
Server API response → McpListItem.visibility (optional McpVisibility) |
Flows through isOfficialMcp() at both card and modal render points |
isOfficialMcp() return |
publisher.ts:4 — strict === comparison |
Returns true only for "system"; undefined/"public"/"private" all return false |
owner variable |
resolveOwner() at McpCard.tsx:72 or null when official |
Null when official, so all owner?.botName / owner?.humanName guards correctly skip |
hideCreator prop |
isOfficial boolean at McpCard.tsx:196 |
Flows to MatchReasons filter at :44, removes creator:* entries only |
Blind-spot Checklist (C1–C6)
- C1 (Dual-path parity): Card and modal both use
isOfficialMcp()as the single gate; rendering branches are symmetric (official badge → no owner → hide creator matches). Clear. - C2 (Control-flow ordering):
isOfficialMcpis a pure function with no side effects; no nested/reentrant call risk. Clear. - C3 (Authorization boundary): No auth/permission changes.
"system"visibility is server-assigned; client only renders it. N/A. - C4 (Auth lifecycle / container-member cascade): No auth lifecycle touched. N/A.
- C5 (Build ≠ runtime): CSS variables are already used in production styles; i18n keys follow the established
t()path. No build-only validation risk. Clear. - C6 (Governance/docs self-consistency): No governance or policy docs changed. N/A.
Cross-round Blocker Recheck (R6)
N/A — first review of this PR.
[Octo-Q] verdict: APPROVE — Clean, well-scoped UI feature with consistent rendering across card and modal surfaces, proper type narrowing, and good test coverage. No correctness, security, or data-flow issues found.
Co-authored-by: octo-loop-agent <loop@deepminer.com.cn>
Co-authored-by: octo-loop-agent <loop@deepminer.com.cn>
yujiawei
left a comment
There was a problem hiding this comment.
Code Review — PR #1074 (octo-web)
Reviewed at head SHA 941eaa3d55a6b5865edf1ee32cb3071afdf19088. Verified locally: checked out the exact head, ran the changed package's tests and the i18n gate.
1. Spec compliance
Spec: ✅
The diff matches the stated scope 1:1, with nothing extra:
- Official gate is exactly
visibility === "system"—utils/publisher.tsisOfficialMcp()returnstrueonly for"system", andfalsefor"public","private", andundefined. Fail-closed for missing/unknown visibility, as claimed. - Creator identity replaced with shield + localized label on both list cards (
McpCard.tsx) and the detail modal (McpDetailModal.tsx). When official,owneris set tonull, so no human/bot name renders. - Creator match-reason chip hidden for official —
MatchReasonsgainshideCreator, wired only throughisOfficial; non-creator reasons (tool/usage_example) still show. - Normal human/bot/import rendering preserved — the non-official branch is unchanged;
resolveOwnerstill handles bot/human/import exactly as before. - Type widening is contained —
McpVisibilitygains"system", andMcpSource/sourcesare extracted to a named alias with no behavioral change.
No missing requirements, no out-of-scope additions, no divergence from the approach.
2. Code quality
Quality: Approved
The implementation is clean and well-guarded. Tests are meaningful: they assert the official label renders, the creator name does not leak into card/detail DOM, non-system rows keep normal rendering, and keyboard activation still fires. All 134 package tests pass; i18n check passes; both zh-CN and en-US carry card.officialPublisher.
No P0/P1 issues. A few non-blocking notes:
-
P2 — the strip is display-only; creator identity still ships to the client.
mapListItem/mapDetailinapi/mcpService.tsmapcreator_name(andcreated_by_*) unconditionally, so for an official MCP the underlying publisher name is still present in the network payload and in JS memory — it is simply not rendered. This is correct for a frontend-only change (the client can't decide what the API returns), but since this is the privacy-facing part of the feature, a reviewer with backend visibility should confirm whether the API is expected to omit/redactcreator_nameforvisibility=systemrows, or whether client-side hiding is the intended contract. Not a defect in this diff. -
P2 (nit) — icon class naming. The detail modal reuses
wk-mcp-card__owner-official-icon/wk-mcp-card__owner-name(card-namespaced) inside awk-mcp-detail__owner--officialspan. It works because those rules are element-agnostic, but the mixedcard/detailprefixes are slightly inconsistent with the rest of the detail styles. Cosmetic only.
3. Overall verdict
APPROVE — Spec ✅ AND Quality Approved.
4. Suggestions
- Consider adding a short comment on
mapListItemnoting thatcreator_nameis intentionally still mapped for official rows and that redaction (if any) is a backend concern — so a future reader doesn't assume the field is unused for system MCPs.
5. Additional observations (security-sensitive review)
This PR was routed as security-sensitive. Points a human may want to manually verify — none are frontend defects:
- Server-side authority of
visibility. The official badge is purely a function of the server-providedvisibility.toWireParamscorrectly omitsvisibilityfrom create/edit payloads (covered bymcpService.visibility.test.ts), so a user cannot self-promote an MCP to "official" through this UI. Confirm the backend likewise never accepts/echoes a client-suppliedvisibility=systemon any write path. - Payload redaction (see P2 above) — the only place real creator identity for an official MCP could still be observed is the raw API response, not the rendered UI.
yujiawei
left a comment
There was a problem hiding this comment.
Code Review — PR #1074 (octo-web) — re-review at head 4ca73820
Re-review after two new commits pushed since the prior approval (which was bound to 941eaa3d). Current head: 4ca73820d5fe688e64a4f33fa8f722df951147ac.
What changed since the last review
The two new commits are test/evidence only — no production source was touched:
apps/web/e2e-kit/tests/C37-mcp-official-publisher.spec.ts(new) — Playwright integration spec driving the real render path.apps/web/e2e-kit/msw-handlers/mcp-official.ts(new) — MSW fixture for that spec.apps/web/src/mocks/handlers.ts(+6/-1) — registers the fixture in the mock list.
The production diff (McpCard.tsx, McpDetailModal.tsx, types/mcp.ts, utils/publisher.ts, i18n, CSS) is byte-identical to the previously-approved head — verified via git compare; no production file appears in the range.
Assessment of the new files
- No production runtime impact. MSW is double-gated:
handlers.tsis only imported whenVITE_E2E_MOCK=1(tree-shaken from dev/prod, perindex.tsx:91), and every handler inmcp-official.tsreturnsundefined(pass-through) unlesssessionStorage.__e2e_scenario === "mcp-official". Adding the fixture to the default handler array is therefore inert outside the e2e scenario. - The e2e spec strengthens the privacy guarantee. It exercises the production render path end-to-end and asserts the official card/modal show the localized "官方发布" label while the redacted creator (
[redacted-admin]) does not appear, and that a normal (public) card still shows its human creator. It also assertswk-mcp-card--officialclass presence/absence and zero console/page/network errors.
Spec compliance
Spec: ✅ — unchanged from prior review. Official gate remains exactly visibility === "system" (fail-closed); creator identity and creator match-reason chip hidden only for official; normal human/bot/import rendering preserved; users cannot self-assign system (create/edit omit visibility, test-covered). New commits add no scope.
Code quality
Quality: Approved — unchanged. 134 package unit tests pass and i18n check passes against the (identical) production code; the added integration spec + fixture are well-structured and correctly gated. The only note remains a non-blocking P2: the detail modal reuses card-namespaced CSS classes (wk-mcp-card__owner-*) — cosmetic coupling, not a defect.
Note on the earlier P2 (creator identity still shipped over the wire): the new fixture sends creator_name: "[redacted-admin]", i.e. a redacted value, which is consistent with — but does not itself resolve — the open question of whether the real backend redacts creator_name for visibility=system rows. Still a backend-contract item for human confirmation, not a frontend defect.
Overall verdict
APPROVE — Spec ✅ AND Quality Approved, re-affirmed against head 4ca73820.
lml2468
left a comment
There was a problem hiding this comment.
Review: #1074 @ 4ca73820 — LSC-24 official publisher styling for MCPs
复核当前 live head 4ca73820(触发消息的 941eaa3d 已过期,期间追加了 e2e 集成用例)。13 文件 +525/−17。merge:CLEAN。
ℹ️ 该 PR 目前为 DRAFT。
结论:APPROVE ✅
Gate 1 — 规格符合度 ✅
LSC-24:仅以 visibility === "system" 认定官方 MCP;官方卡/详情用 ShieldCheck + 本地化「官方发布 / Official publisher」替换作者身份、隐藏官方 MCP 的 creator 命中原因、加 token 化官方样式;普通 human/bot/import 作者渲染保留;缺失/未知 visibility fail-closed。与描述一致,无 over-build。
Gate 2 — 代码质量 ✅(重点:官方信号可信、不可仿冒)
- 可信信号(正是 #1026/#1078 名字匹配问题的正解):
isOfficialMcp(item) = item.visibility === "system"(publisher.ts:4)—— 只认服务端枚举,非可仿冒的显示名。且承 #1066:toWireParams建/改 MCP 根本不带visibility字段 → 客户端无法自封system,官方身份服务端权威、不可伪造;缺失/未知一律非官方(fail-closed)。McpVisibility已扩为"public"|"private"|"system"。 - 纯装饰、不控权限:
isOfficial只影响展示(owner 置 null + ShieldCheck 标签、hideCreator={isOfficial}隐藏命中原因、wk-mcp-card--official类名),不涉任何鉴权/信任放行。 - CSS 全用语义 token(按 #1067 教训核):官方样式用
var(--wk-ai-border)/--wk-ai-surface/--wk-color-accent/--wk-text-accent,零硬编码 hex/rgb;四个 token 在theme/*.css均有定义(经 purple 调色板,亮/暗两套)→ 暗色安全。 - 无 XSS:标签走 i18n 文本节点,图标为内联
ShieldCheckSVG,aria-hidden;零dangerouslySetInnerHTML。
构建 / 测试 / i18n(实跑 @ 4ca73820):pnpm --filter @octo/web build ✅ 3.42s;pnpm i18n:check ✅「locale keys healthy」(官方文案中英齐全);@dmwork/mcp 12 files / 134 tests 全绿;含 publisher.test.ts。附全应用 MSW Playwright 集成用例(C37,PR 描述有证据)。
🟡 非阻断(peers)
pr-title-lint(标题 Conventional Commits)红灯 —— 非代码问题,合并前改下即可(Steve)。- 建议给
publisher.test.ts补一条「未知/缺失 visibility → 非官方」显式 fail-closed 用例(Jerry-Xin);Story 全局 locale 设置建议改 decorator。 - 详情弹窗复用卡片 CSS 类名,未来样式变更需注意联动(mochashanyao);
mapListItem建议注释说明 creator_name 仍传输、后端脱敏(yujiawei)。 - DRAFT —— 待转正式。
官方标识用服务端 visibility==="system" 可信信号(客户端无法自封,fail-closed),纯装饰不控权限,CSS 全语义 token(暗色安全)、无 XSS,构建/134 测试/i18n 通过。正好把 #1026/#1078 那条可仿冒显示名的 🟡 用可靠信号做对了。可合并 —— APPROVE(DRAFT 转正式 + 顺手过 pr-title-lint 即可)。
Jerry-Xin
left a comment
There was a problem hiding this comment.
🔄 Re-review at 4ca73820 (re-affirming my prior APPROVE at 941eaa3d, auto-dismissed by the new commit). Clean, purely-additive follow-up: e2e test coverage + the PR-title lint fix. Linear advance (ahead 2, behind 0 — no rebase bloat). Byte-verified: none of the shipped logic/styling/i18n changed.
Delta since 941eaa3d (git diff 941eaa3d..4ca73820, 3 files):
apps/web/e2e-kit/msw-handlers/mcp-official.ts(new) — MSW fixture serving one official (visibility: "system") and one community (visibility: "public") MCP.apps/web/e2e-kit/tests/C37-mcp-official-publisher.spec.ts(new) — Playwright scenario for list + detail, light/dark.apps/web/src/mocks/handlers.ts— registersmcpOfficialHandlers.
✅ Highlights
- No regression on the official signal:
isOfficialMcp()inpackages/dmworkmcp/src/utils/publisher.tsis byte-identical to the approved head — stillvisibility === "system"(server enum, not client-settable; missing/unknown fails closed). Badge remains cosmetic, no authz gating. McpCard.tsx,McpDetailModal.tsx, andpackages/dmworkbase/src/theme/semantic.cssare all byte-identical to941eaa3d— no change to XSS surface (still i18n text node + inline SVG), CSS accent tokens (light+dark), or i18n keys.- New MSW handler is gated behind
sessionStorage.__e2e_scenario === "mcp-official"and returnsundefined(passthrough) when off, so it cannot bleed into non-e2e runs. - Good privacy assertion: the fixture uses a redacted creator (
[redacted-admin]) and the spec asserts the official card/detail shows the official label but explicitly NOT the creator string, while the community card still shows its creator. This locks in the "official signal without leaking creator attribution" behavior. - Also covers dark-mode rendering and checks for console/page errors — solid coverage.
💬 Non-blocking
mcpOfficialHandlersis spread first inhandlers.ts, so its/mcpsroute shadows any later handler for the same path when the flag is on. Fine for the gated e2e scenario; just keep new same-path handlers flag-guarded the same way to avoid ordering surprises.
Gate: pr-title-lint now green; all CI checks pass; MERGEABLE. No blocking items.
mochashanyao
left a comment
There was a problem hiding this comment.
[Octo-Q · automated review]
Verdict: Approve — no blocking findings; notes below (data-flow traced).
Code Review — PR #1074 (octo-web)
Summary
This PR introduces official publisher styling for MCP server entries: when an MCP has visibility: "system", the card and detail modal show a ShieldCheck icon with "Official publisher" / "官方发布" label instead of the regular creator/bot owner info. The creator identity is suppressed from both the owner badge and the match-reasons chips. The feature includes a clean utility function (isOfficialMcp), type refinements (McpSource, extended McpVisibility), i18n for both locales, CSS using existing design tokens, and comprehensive test coverage at unit, component, E2E, and Storybook levels. Overall a well-structured, focused feature PR with no correctness or security concerns.
Verification
- ✅ Data flow —
isOfficialMcpgate —visibilityflows from API response throughmapListItem(mcpService.ts:569) unchanged → consumed byisOfficialMcp()in bothMcpCard.tsxandMcpDetailModal.tsx. No intermediate transformation or early return can drop the value. - ✅ Creator identity suppression — In both card and detail modal,
isOfficial = truesetsowner = null, preventingresolveOwner()output from rendering.MatchReasonsreceiveshideCreator={isOfficial}, filteringcreator:*entries from the revealed match reasons. Confirmed by unit tests (McpOfficialPublisher.test.tsx:83-90). - ✅ CSS design tokens — All new CSS variables (
--wk-ai-border,--wk-ai-surface,--wk-text-accent,--wk-color-accent) are defined inpackages/dmworkbase/src/theme/semantic.csswith both light and dark mode values. No custom unthemed values introduced. - ✅ Type system consistency —
McpSourceextracted to a named type,McpVisibilityextended with"system". All consumers (McpListItem.source,ListMcpParams.sources) updated. Wire-to-client mapping (mapListItem) passesvisibilityandsourcethrough directly. - ✅ i18n parity — Both
en-USandzh-CNhave the newcard.officialPublisherkey. - ✅ Card/detail parity (C1) — Both
McpCard.tsxandMcpDetailModal.tsximplement the sameisOfficial → null owner → ShieldCheck badgepattern. ThehideCreatorprop is correctly scoped to the card'sMatchReasons(the detail modal does not renderMatchReasons). - ✅ Keyboard accessibility preserved — Official MCP cards retain
role="button",tabIndex={0}, and keyboard activation. Verified by component test (McpOfficialPublisher.test.tsx:103-115). - ✅ MSW handler gating — E2E handlers are gated on
sessionStorage.getItem("__e2e_scenario") === "mcp-official", preventing interference with other test scenarios.
Findings
No P0/P1 issues. Two non-blocking items below.
P2 — Detail modal reuses card-scope CSS class names (packages/dmworkmcp/src/components/McpDetailModal.tsx:275)
The official publisher badge in the detail modal uses wk-mcp-card__owner-official-icon for the ShieldCheck icon and wk-mcp-card__owner-name for the name span — both BEM classes scoped to the card component. While wk-mcp-card__owner-name is already shared with the detail modal for bot/human owners (pre-existing pattern), the icon class is new and card-specific. If the card's official icon styling ever diverges from the detail view's needs, the shared class becomes a coupling point. Consider adding a detail-scoped class (e.g. wk-mcp-detail__owner-official-icon) for the new icon. Not a blocker — functionally correct.
Nit — Unrelated whitespace-only CSS formatting (packages/dmworkmcp/src/index.css:563,861)
Two pre-existing CSS declarations received whitespace-only reformatting (font shorthand slash spacing at :563, box-automated review line break at :861-862). These don't affect behavior but add noise to the diff. Consider keeping formatting fixes in a separate commit.
Things I checked that are fine
isOfficialMcp()unit test covers all fourMcpVisibilityvalues plusundefined.- Component test verifies official badge renders, creator identity is hidden, and keyboard activation works for official MCPs; also verifies normal MCPs still show regular owner info.
- The
hideCreatorfilter inMatchReasonscorrectly prevents creator-identity leakage through match-reason chips (acreator:Internal Adminreason would otherwise reveal the suppressed identity). - E2E test (C37) validates API response shape, visibility assertion, and absence of console/page errors.
- MSW mock uses
[redacted-admin]ascreator_namefor the official item — models the expected server-side redaction contract. McpSourceextraction andMcpVisibilityextension are type-safe; all consumers updated.
Human-verify
- Server-side
visibility: "system"contract — The client checksvisibility === "system"to determine official status. Confirm the backend returns this value for the intended MCP entries and thatvisibilityis not client-settable in create/update flows (which could allow users to self-designate as official). Not verifiable from this repo alone. This is not a merge blocker for this PR.
Verdict: APPROVED
Well-scoped feature with clean implementation, proper creator-identity suppression across both card and detail views, and thorough test coverage. No correctness, security, or build concerns. The P2 and nit are non-blocking.
yujiawei
left a comment
There was a problem hiding this comment.
Code Review — PR #1074 (octo-web)
Reviewed at head SHA 4ca73820d5fe688e64a4f33fa8f722df951147ac against main. This is a security-sensitive review (official-publisher identity handling).
1. Spec compliance
Checked against the stated goals (LSC-24): identify official MCPs by visibility === "system", replace creator identity with a shield + localized label, hide creator match-reason chips for official MCPs, preserve normal human/bot/import rendering, and fail closed for missing/unknown visibility.
- Not implemented / missing: none. All listed goals are present.
- Over-build: none. There is no user-facing visibility selector (
McpCreateModalhas no visibility input;toWireParamsnever sendsvisibility), so wideningMcpVisibilityto include"system"does not create a way for a normal user to self-assign the official badge. - Divergence: none.
isOfficialMcp(packages/dmworkmcp/src/utils/publisher.ts:3) gates strictly onvisibility === "system"and returnsfalseforpublic/private/undefined— the fail-closed behavior asked for, and covered bypublisher.test.ts.
Spec: ✅
2. Code quality
Solid, well-scoped change with good test coverage. No correctness/security blockers found.
- Card (
McpCard.tsx:94-96,139-145,195-197): for official itemsowneris forced tonullandMatchReasonsis passedhideCreator, which filters outcreator:chips (McpCard.tsx:42-47). Non-official rendering is untouched. - Detail modal (
McpDetailModal.tsx:270-287): official path nullsowner, so neither the bot/human name branches nor acreator:chip can render (the detail modal renders noMatchReasons). Consistent with the card. - MSW additions are correctly gated:
src/mocks/browser.tsandhandlers.tsare only imported whenVITE_E2E_MOCK === "1"(apps/web/src/index.tsx:91-93) and tree-shaken from dev/prod. No production side effects. - The new
"system"visibility variant does not break any exhaustive switch/label mapping — there is no visibility label lookup that would now fall through. - Tests are meaningful: the unit test asserts a real creator name (
"Internal Admin") is not rendered on official cards/details while still rendering for non-official items, and keyboard activation is preserved. Integration test exercises list + detail, light/dark, and mobile viewport with zero console/network errors.
Please verify before merge (security-sensitive)
- Client-side redaction is not a security boundary. Hiding the creator name and
creator:match reason happens in the frontend, but the API response still carriescreator_nameandmatch_reasons: ["creator:<admin>"]on the wire for system MCPs (see the wire shape inmcpService.ts:511-521andmapListItemat:557-579). The e2e fixture sidesteps this by pre-redacting to[redacted-admin], so it does not prove production behavior. Please confirm the backend redactscreator_nameand anycreator:match reasons forvisibility === "system"MCPs; otherwise the admin identity is still observable via network inspection despite the UI hiding it. The frontend change is correct as defense-in-depth, but the actual guarantee must live server-side.
Quality: Approved (the item above is a verification request / P2 note, not a frontend blocker — the frontend cannot control what the backend emits).
3. Overall verdict
APPROVED — Spec ✅ and Quality Approved. No P0/P1 issues. Merge is gated only on the human confirming backend-side redaction of creator identity for system MCPs.
4. Suggestions (non-blocking)
- Consider a short code comment near
isOfficialMcpnoting that server-side redaction ofcreator_name/match_reasonsis the authoritative privacy control and the UI hiding is defense-in-depth, so a future refactor doesn't mistake the client filter for the guarantee.
Summary
visibility === "system"Verification
pnpm --filter @dmwork/mcp test— 12 files, 134 tests passedpnpm i18n:check— passedpnpm --filter @octo/web build— passedE2E_TARGET=local pnpm --filter @octo/web exec playwright test --config=e2e-kit/playwright.config.ts e2e-kit/tests/C37-mcp-official-publisher.spec.ts --project=chromium— 1 passedFull-app Integration Evidence
Fixture type: application-level API fixture (repository MSW service worker), not real backend data.
45cc17b2pnpm devhttp://localhost:3000/mcp-market/mcp?sid=e2etestGET /market/api/v1/mcps?category=all&sort=updated&page_size=20&page=1GET /market/api/v1/mcp_categoriesGET /market/api/v1/mcps/official-searchGET /market/api/v1/mcps/community-searchvisibility: "system";creator_nameis redacted in fixture evidence.mcp-api-evidence.jsonare attached by Playwright and mirrored to the Octo issue comment.Base:
upstream/main@8f8a19c2Head:
feat/LSC-24-mcp-official-publisher-v2@45cc17b2