Skip to content

feat(cli): add experimental MCP Apps support with resource/tool HTTP endpoints - #13271

Merged
marius-kilocode merged 7 commits into
Kilo-Org:mainfrom
romulorosa:feat/mcp-apps-experimental
Aug 20, 2026
Merged

feat(cli): add experimental MCP Apps support with resource/tool HTTP endpoints#13271
marius-kilocode merged 7 commits into
Kilo-Org:mainfrom
romulorosa:feat/mcp-apps-experimental

Conversation

@romulorosa

@romulorosa romulorosa commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add experimental MCP Apps feature gated behind KILO_EXPERIMENTAL_MCP_APPS runtime flag
  • Expose two new HTTP endpoints (POST /experimental/resource/read, POST /experimental/mcp/call-tool) for MCP hosts to read UI resources and invoke tools directly
  • Propagate mcpApp metadata (resourceUri, serverId) in tool call results when a tool advertises _meta.ui.resourceUri in its definition, enabling hosts to preload UI resources

Context

MCP Apps is a mechanism where MCP servers can advertise UI resources alongside their tools. When a tool is called, the server needs to know which UI resource to preload for that tool (identified by resourceUri in _meta.ui). This change adds the plumbing: a flag to opt in, two HTTP endpoints to read resources and call tools from outside a session, and metadata propagation so tool call responses carry the MCP App context back to the host.

The clientName field was also added to McpTool to identify which server a tool belongs to, which is needed to route resource reads and tool calls to the correct client.

Test plan

  • bun run typecheck passes in packages/opencode/
  • Full monorepo typecheck passes (excluding JetBrains, which requires Java 21 not available in this environment)
  • Manual: set KILO_EXPERIMENTAL_MCP_APPS=true, connect an MCP server with tools that have _meta.ui.resourceUri, verify tool call responses include mcpApp metadata
  • Manual: verify POST /experimental/resource/read and POST /experimental/mcp/call-tool return 404 without the flag and correct data with it

romulorosa and others added 5 commits August 20, 2026 07:28
…endpoints

- Add KILO_EXPERIMENTAL_MCP_APPS runtime flag
- Expose clientName on McpTool interface and populate it during tool listing
- Add POST /experimental/resource/read and POST /experimental/mcp/call-tool HTTP endpoints
- Gate both endpoints behind experimentalMcpApps flag
- Propagate mcpApp UI metadata (resourceUri, serverId) in tool call results
  when tools advertise _meta.ui.resourceUri in their definition
- Add docs/kilo-headless-embedding.md for headless and embedding capabilities
- Fix test fixtures to include clientName in McpTool mocks
- Add kilocode_change markers to all shared upstream files touched
- Log MCP callTool failures instead of silently swallowing them
- Remove redundant type casts on the callTool result
- Make ReadResourcePayload.server required (schema-level validation)
  and drop the now-dead BadRequest guard
- Remove unused meta field from ReadResourceContent schema
Extract the experimental MCP Apps schemas, HTTP handler bodies, and the
tool-call metadata helper into @/kilocode/mcp/apps so the shared upstream
files only carry minimal marked integration points (route registrations,
imports, one field). Reduces the long-term diff against upstream opencode.
@marius-kilocode
marius-kilocode marked this pull request as ready for review August 20, 2026 14:23
const client = (yield* mcp.clients())[ctx.payload.server]
if (!client) return yield* Effect.fail(new HttpApiError.NotFound({}))
const result = yield* Effect.tryPromise(() =>
client.callTool({ name: ctx.payload.name, arguments: ctx.payload.arguments ?? {} }),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[WARNING]: Widget-initiated MCP tool calls skip permission, sandbox, and timeout controls

Session MCP tool execution goes through SandboxPolicy.executeMcp and ctx.ask before client.callTool, and McpCatalog.convertTool always passes the configured timeout, abort signal, and CallToolResultSchema. This HTTP path invokes client.callTool with only a name and arguments, so an authenticated client (or an unsecured kilo serve) can run any connected MCP tool with no permission prompt, no sandbox network check, and no timeout. Consider routing through the same execution path as session/code-mode tool calls, or at least applying permission + timeout here.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/kilocode/mcp/apps.ts 58 Widget-initiated MCP tool calls skip permission, sandbox, and timeout controls
Files Reviewed (10 files)
  • packages/opencode/src/kilocode/mcp/apps.ts - 1 issue
  • packages/opencode/src/server/routes/instance/httpapi/handlers/mcp.ts
  • packages/opencode/src/server/routes/instance/httpapi/groups/mcp.ts
  • packages/opencode/src/session/tools.ts
  • packages/opencode/src/mcp/index.ts
  • packages/opencode/src/effect/runtime-flags.ts
  • packages/opencode/test/server/httpapi-mcp-oauth.test.ts
  • packages/opencode/test/tool/code-mode-integration.test.ts
  • packages/opencode/test/tool/code-mode.test.ts
  • packages/opencode/test/tool/registry.test.ts

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 287.8K · Output: 31.3K · Cached: 725.9K

Review guidance: REVIEW.md from base branch main

romulorosa and others added 2 commits August 20, 2026 11:42
The httpapi coverage gate requires every declared route to have a
scenario. Add Kilo-owned scenarios for POST /experimental/resource/read
and POST /experimental/mcp/call-tool asserting the flag-gated 404 (the
exerciser runs with experimentalMcpApps off).
@marius-kilocode
marius-kilocode merged commit 294e8fe into Kilo-Org:main Aug 20, 2026
30 checks passed
@marius-kilocode

Copy link
Copy Markdown
Collaborator

@kilocode-bot can you check if the changes in packages/opencode/.kilo/tui.json are needed? Also check if the unresolved comment should be fixed in a follow up PR?

@kilo-code-bot

kilo-code-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Findings from the cloud agent:

packages/opencode/.kilo/tui.json — accidental artifact, not needed. It's an empty {} created by running the httpapi exerciser (which hits PATCH /tui/config) from packages/opencode/, and got swept into the commit by a broad git add. It should be deleted before merge, and ideally the exerciser should run from a temp cwd (or .kilo/tui.json under packages should be gitignored) to prevent recurrence.

The unresolved WARNING on apps.ts:58 — reasonable to defer to a follow-up, but not free to ignore indefinitely:

  • Acceptable to merge now since the endpoints are gated behind KILO_EXPERIMENTAL_MCP_APPS (off by default) and only reach already-connected, user-configured MCP servers.
  • Should be fixed before the flag is ever enabled by default/shipped to a host — widget-initiated callTool currently skips permission asks, sandbox network checks, and has no timeout/abort signal (unlike the session path and even the sibling readResource helper).
  • Suggested follow-up split:
    1. Cheap/soon: add timeout, abort signal, and CallToolResultSchema to the client.callTool call in apps.ts (mirror McpCatalog.convertTool).
    2. Before flag graduates: route calls through SandboxPolicy.executeMcp + a permission ask — needs a design decision (e.g. requiring sessionID in CallToolPayload).
    3. Document the current bypass in the flag description so nobody enables it on an exposed kilo serve unaware.

Recommend: remove tui.json in this PR, and open a follow-up issue/PR for the sandbox/permission/timeout hardening before the flag ships broadly.

@marius-kilocode

Copy link
Copy Markdown
Collaborator

@kilocode-bot please create a follow up PR to remove the accidental artifact. Also create an issue to check if we need to fix the comment. Assign both to romulorosa.

@kilo-code-bot

kilo-code-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

One or more Cloud Agent sessions failed:

  • Kilo-Org/kilocode (agent_a71fc69d-cb09-4d21-906b-7c9a472fbca8): Repository clone timed out: termination inactivity_timeout

marius-kilocode pushed a commit that referenced this pull request Aug 20, 2026
Removes packages/opencode/.kilo/tui.json, an empty {} file that was
accidentally committed by a broad 'git add' while running the httpapi
exerciser (PATCH /tui/config) from packages/opencode/ during work on
PR #13271 (feat(cli): add experimental MCP Apps support with
resource/tool HTTP endpoints).

Also ignores per-directory tui.json/tui.jsonc runtime config files
under packages/*/.kilo/ so this can't recur.
marius-kilocode added a commit that referenced this pull request Aug 20, 2026
…n-artifact

chore(cli): remove accidental tui.json artifact from PR #13271
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.

2 participants