Skip to content

feat(tui): mcp channel tui render - #2432

Open
godlzr wants to merge 13 commits into
MoonshotAI:mainfrom
godlzr:feat/mcp-channel-tui-render
Open

feat(tui): mcp channel tui render#2432
godlzr wants to merge 13 commits into
MoonshotAI:mainfrom
godlzr:feat/mcp-channel-tui-render

Conversation

@godlzr

@godlzr godlzr commented Jul 30, 2026

Copy link
Copy Markdown

Related Issue

Resolves #2431

Problem

See linked issue.

What changed

agent-core-v2 already had an MCP "channel push" mechanism (notifications/kimi/channel) so a plugin like a Discord bridge can wake a running session instead of relying on polling, but two gaps made it unusable in practice:

  1. The pushed domain event (mcp.channel.received) never carried the message text — only server / chatId / receivedAt — so there was nothing to render even if something tried.
  2. Nothing between the engine and the CLI actually rendered it. The v1-shaped Event / PromptOrigin unions that the SDK and TUI are built on (used by both engines — the v2 harness casts its own origins/events into these types) had no mcp_channel member, so the pushed message was invisible except indirectly, through the model's own paraphrase of what it received in its next turn.

This PR closes both gaps, mirroring the existing cron.fired path end to end rather than inventing a new pattern:

  • packages/protocol: add McpChannelReceivedEvent to the Event union and McpChannelOrigin to PromptOrigin, with matching zod schemas.
  • packages/agent-core-v2: include the message text in the published mcp.channel.received domain event.
  • packages/agent-core: add McpChannelOrigin to the v1-shaped PromptOrigin union, and handle the new kind in the exhaustive origin switches it already has (compaction handoff, replay turn-boundary detection, session-store visibility) — treated the same as cron_job: dropped on compaction, doesn't anchor a turn boundary for replay/undo - packages/node-sdk: re-export McpChannelReceivedEvent;translator already passes through any type it doesn't explicitly drop or rename, so no translation logic changed.
  • apps/kimi-code: new 'mcp_channel' transcript entry kind and McpChannelMessageComponent (mirrors CronMessageComponent), wired into the live session-event handler, session replay (so a resumed seo), the TUI's render dispatch, and /undo's context-entryclassification.
    Tested end-to-end against a real Discord MCP bridge plugin with the experimental v2 engine enabled: a paired DM now wakes the session and renders as a distinct "Message received via discord" block with thenly showing up through the model's own summary. No changeset: every changed code path is either internal a or only reachable when the CLI is switched onto the experimental v2 engine (KIMI_CODE_EXPERIMENTAL_FLAG`), whied engine yet — no user on the default CLI can perceive this change. Same reasoning applies to docs: nothing user-facinghe default engine.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the probl
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no chang
  • Ran gen-docs skill, or this PR needs no doc update.

godlzr added 9 commits July 29, 2026 13:45
…cation factory

Extend MCPClient with onChannelMessage and switch StdioMcpClient,
HttpMcpClient, and SseMcpClient to build their SDK Client via
createMcpSdkClient so all three transports gain the push-channel
capability and notification handler. Updates existing MCP test fakes
to satisfy the extended interface.
The mcp-channel push feature (agent-core-v2) injected pushed messages
into the agent's context but never gave the SDK/TUI a discrete signal
to render — the domain event carried no message text, and neither
protocol's Event/PromptOrigin unions, agent-core's v1-shaped
ContextMessage/Event types, nor the TUI's live/replay renderers knew
about the mcp_channel origin at all. Only the model's own paraphrase
of the pushed content was ever visible.

Wires the full chain, mirroring the existing cron.fired path:
- protocol: add McpChannelReceivedEvent to the Event union and
  McpChannelOrigin to PromptOrigin, with matching zod schemas.
- agent-core-v2: include the message text in the published
  mcp.channel.received domain event (previously only server/chatId/
  receivedAt).
- agent-core: add McpChannelOrigin to the v1-shaped PromptOrigin union
  (the v2 harness casts its own origins into these types) and handle
  the new kind in the exhaustive origin switches (compaction handoff,
  replay turn-boundary detection, session-store visibility checks) —
  treated like cron: dropped on compaction, doesn't anchor a
  replay/undo turn boundary.
- node-sdk: re-export McpChannelReceivedEvent; the v2->v1 event
  translator already passes unlisted types through unchanged.
- apps/kimi-code: new 'mcp_channel' transcript entry kind and
  McpChannelMessageComponent (mirrors CronMessageComponent), wired
  into the live event handler, session replay, kimi-tui's dispatch,
  and undo's context-entry classification.
@changeset-bot

changeset-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: bf48fcd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fbeddbf54e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/tui/controllers/session-replay.ts Outdated
Comment thread packages/agent-core-v2/src/mcpCore/client-shared.ts Outdated
…render

# Conflicts:
#	packages/agent-core-v2/docs/state-manifest.d.ts
#	packages/agent-core-v2/src/index.ts
#	packages/agent-core-v2/test/mcpCore/connection-manager.test.ts
#	packages/agent-core-v2/test/mcpCore/fixtures/channel-stdio-server.mjs
@godlzr godlzr changed the title Feat/mcp channel tui render feat(tui): mcp channel tui render Jul 30, 2026
godlzr added 2 commits July 30, 2026 15:42
origin/main's Workspace-domain refactor replaced session-scoped
ISessionMcpService with a workspace-seeded ISessionMcpHandle (plain
connectionManager property instead of a method, no ensureMcpReady).
Move channel-notification.ts to mcpCore/ alongside the rest of the
renamed MCP transport layer, and regenerate the state/wire manifests.
- Project mcp.channel.received into the transcript/web surface too:
  kap-server's coreEventMap gets a marker case mirroring cron.fired,
  and kimi-web gets the matching live-event synthesis, turn-building,
  and a McpChannelNotice.vue renderer (mirrors CronNotice.vue) so a
  push shows up for web sessions, not just the TUI.
- Fix a live/replay text mismatch: replay only stripped the
  <mcp-channel> envelope without unescaping the <>-escaped body, so
  restarting a session would show "a &lt; b" where the live render
  showed "a < b". Unescape mirrors the plugin's escapeXmlTags exactly
  (only <>, not &/" — matching what the envelope actually encodes) in
  both the TUI and kimi-web.
- Fold two inline JSDoc blocks in client-shared.ts into the file
  header per the package's comment convention (header-only, external
  role only).

Adds a second changeset for the web-facing half.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make MCP channel push (Discord-style bridges) usable outside the experimental v2 engine

2 participants