Skip to content

feat(middleware): propagate senderIsOwner security context to MCP server#60

Merged
alexey-pelykh merged 1 commit intomainfrom
feat/mcp-security-context
Feb 27, 2026
Merged

feat(middleware): propagate senderIsOwner security context to MCP server#60
alexey-pelykh merged 1 commit intomainfrom
feat/mcp-security-context

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

  • Gate owner-only MCP tools (cron scheduling, gateway admin) behind senderIsOwner flag resolved from command authorization
  • Propagate senderIsOwner and toolProfile end-to-end: dispatch site → ChannelMessage → ChannelBridge env var → MCP server context → tool registration gate
  • Non-owner channel users can no longer instruct the agent to modify cron schedules or restart the gateway via MCP tools
  • Secure defaults: senderIsOwner defaults to false at every boundary (defense-in-depth)

Changes

File Change
src/middleware/mcp-handlers/context.ts Add senderIsOwner and toolProfile fields
src/middleware/mcp-server.ts Read REMOTECLAW_SENDER_IS_OWNER and REMOTECLAW_TOOL_PROFILE env vars
src/middleware/mcp-tools.ts Gate cron/gateway tool registration on ctx.senderIsOwner
src/middleware/channel-bridge.ts Pass security context as env vars in #buildMcpConfig()
src/middleware/types.ts Add senderIsOwner and toolProfile to ChannelMessage
src/auto-reply/reply/agent-runner-execution.ts Propagate senderIsOwner from resolveCommandAuthorization()
src/commands/agent.ts Set senderIsOwner: true (CLI user is always owner)
src/cron/isolated-agent/run.ts Set senderIsOwner: false (cron agents must not self-modify)
extensions/voice-call/src/core-bridge.ts Add fields to duck-typed ChannelMessage
extensions/voice-call/src/response-generator.ts Set senderIsOwner: true (voice callers have direct access)

Test plan

  • registerAllTools with senderIsOwner: false registers only 17 tools (no cron/gateway)
  • registerAllTools with senderIsOwner: true registers all 29 tools
  • ChannelBridge.#buildMcpConfig() includes REMOTECLAW_SENDER_IS_OWNER env var
  • Default senderIsOwner is false when not set on message
  • REMOTECLAW_TOOL_PROFILE defaults to "full" when not set
  • All existing middleware tests pass (71 tests)
  • pnpm build passes
  • pnpm format and pnpm lint clean

Closes #59

🤖 Generated with Claude Code

…ver (#59)

Gate owner-only MCP tools (cron scheduling, gateway admin) behind a
senderIsOwner flag resolved from command authorization. Non-owner
channel users can no longer instruct the agent to modify cron schedules
or restart the gateway via MCP tools.

Pipeline: dispatch site → ChannelMessage.senderIsOwner →
ChannelBridge env var → MCP server context → tool registration gate.

- Add senderIsOwner and toolProfile fields to McpHandlerContext
- Read REMOTECLAW_SENDER_IS_OWNER and REMOTECLAW_TOOL_PROFILE env vars
  in MCP server createContext()
- Gate cron/gateway tool registration on ctx.senderIsOwner in
  registerAllTools() (29 tools for owner, 17 for non-owner)
- Add senderIsOwner and toolProfile to ChannelMessage type
- Pass security context as env vars in ChannelBridge.#buildMcpConfig()
- Thread senderIsOwner through all dispatch sites:
  - Auto-reply: propagated from resolveCommandAuthorization()
  - CLI command: always true (CLI user is the bot owner)
  - Cron: always false (cron agents must not self-modify)
  - Voice-call: true (callers have direct phone access)
- Secure defaults: senderIsOwner defaults to false at every boundary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh enabled auto-merge (squash) February 27, 2026 08:15
@alexey-pelykh alexey-pelykh merged commit 3c91fd9 into main Feb 27, 2026
2 checks passed
@alexey-pelykh alexey-pelykh deleted the feat/mcp-security-context branch February 27, 2026 08:24
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.

Propagate security context (senderIsOwner, toolProfile) to MCP server

1 participant