Skip to content

Fix MCP named tool methods failing with apply error in GatekeeperLoopback - #491

Open
dreh23 wants to merge 1 commit into
cloudflare:mainfrom
dreh23:pr/upstream-fix-mcp-apply
Open

dreh23 wants to merge 1 commit into
cloudflare:mainfrom
dreh23:pr/upstream-fix-mcp-apply

Conversation

@dreh23

@dreh23 dreh23 commented Sep 14, 2026

Copy link
Copy Markdown

What does this change?

In GatekeeperLoopback (packages/workshop-backend/src/overseer.ts), the proxy wrapping the gatekeeper session RpcStub used Reflect.get(target, prop, target) in its get trap.

When an agent in executeCode calls a dynamically-installed MCP tool method (e.g. env.MY_MCP.myToolName({...})), that method name was attached at runtime to the session prototype by installToolMethods(), but is not in workerd's statically-known RPC surface for the base stub type.

Because the property is not in the static surface, Reflect.get(rpcStub, prop) returns an RpcProperty pipeline sub-stub. Calling that sub-stub as a function causes workerd to dispatch an RPC method named "apply" to the remote receiver (McpSessionImpl), which does not implement it, throwing:

TypeError: The RPC receiver does not implement the method "apply"

This patch changes the get trap to return a wrapper function for string property accesses:

return function(this: unknown, ...args: unknown[]) {
  return (target as Record<string, (...a: unknown[]) => unknown>)[prop as string](...args);
};

This causes workerd to dispatch target[prop](...args) as a direct named RPC method call to the remote session, where the dynamically-installed method on the prototype chain handles it. Symbols and "then" continue to pass through directly.

Why is this obviously correct and trivially verifiable?

  1. Self-contained: It changes only the get handler inside GatekeeperLoopback (17 lines changed).
  2. Preserves standard RPC behavior: Symbols (like Symbol.dispose) and "then" pass through via Reflect.get(target, prop, target), maintaining lifecycle and Promise resolution invariants.
  3. No new surface or dependencies: For statically-known methods, calling target[prop](...args) on the stub dispatches the same RPC call as before. For dynamically-installed prototype methods (which previously threw TypeError), it now dispatches the intended method call.

Checklist

Checking every item does not guarantee acceptance. Maintainers determine whether
a pull request meets the contribution policy.

  • This is a small, concrete change; it is not a feature, refactor, or low-value cleanup.
  • I understand that maintainers decide whether the change is obviously correct and trivially verifiable.
  • I have read and followed the contribution guidelines.

Devin Review

…back

GatekeeperLoopback wraps the gatekeeper session RpcStub in a Proxy whose
'get' trap returned Reflect.get(target, prop, target).

For method names that are not in workerd's statically-known RPC surface
for the stub type (such as dynamically-installed MCP tool methods added
at runtime by installToolMethods), Reflect.get(rpcStub, prop) returns a
pipeline property sub-stub. Calling that sub-stub as a function
dispatches an RPC method named 'apply' to the remote receiver. Since
McpSessionImpl does not implement 'apply', the call fails with:

  TypeError: The RPC receiver does not implement the method "apply"

Fix: return a wrapper function for string property accesses that invokes
target[prop](...args) directly on the session RpcStub. workerd treats
this direct method call as a standard RPC method dispatch, which the
remote session handles via its prototype chain where installToolMethods
attached the delegates.
@github-actions github-actions Bot added the kernel Changes to the Workshop kernel label Sep 14, 2026
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@dreh23

dreh23 commented Sep 14, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

@dreh23

dreh23 commented Sep 14, 2026

Copy link
Copy Markdown
Author

recheck

github-actions Bot added a commit that referenced this pull request Sep 14, 2026

@devin-ai-integration devin-ai-integration 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kernel Changes to the Workshop kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant