nextlevelbuilder / nextlevelbuilder/goclaw
MCP bridge drops SenderID → cron / write_file unusable in Telegram groups (Claude CLI provider)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 3.6k
- Forks
- 1.1k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 24
Description
Symptom
In a Telegram group, every mcp__goclaw-bridge__* tool call from a Claude-CLI-backed agent is rejected with:
permission denied: only users with cron or file_writer permission can manage cron jobs in group chats
permission denied: system context cannot write files in group chats. If this is a legitimate user action, ensure the acting sender is preserved through the tool chain
…even when the calling user has all the right grants:
- File Writer · All Groups · allow
- Config Permissions:
*(Global),cron· All Groups,context_files· All Groups,heartbeat· All Groups · allow
Repro
- Agent uses provider
claude_cli. - From a Telegram group, ask the agent to add/edit a cron job, or to write a file.
- Tool call returns the error above. DB grants are never consulted.
Root cause
The MCP bridge does not propagate the acting sender:
internal/providers/claude_cli_mcp.go:86-95—BridgeContextcarriesAgentID,UserID,Channel,ChatID,PeerKind,Workspace,TenantID,LocalKey— noSenderID.internal/providers/claude_cli_mcp.go:128-164—writeMCPConfigInternalwritesX-Agent-ID,X-User-ID, … — noX-Sender-IDheader, no sender in the HMAC payload (SignBridgeContextat line 267).internal/gateway/server.go:215-303—bridgeContextMiddlewarereads the headers above and callsstore.WithAgentID/store.WithUserID/store.WithTenantID— neverstore.WithSenderID.
Result: tools land with SenderID=="" and trip the empty-sender deny at internal/store/config_permission_store.go:84 (CheckFileWriterPermission) and :142 (CheckCronPermission) before any DB grant lookup runs.
Native providers (Anthropic, OpenAI-compat, DashScope, Codex, ACP) are unaffected: they invoke tools in-process with the agent-loop ctx where store.WithSenderID(ctx, req.SenderID) is already set (internal/agent/loop_context.go:63-64).
Expected
SenderID should flow through the bridge so per-user grants (file_writer, cron) are evaluated against the real Telegram sender.
Suggested fix (~4 files)
- Add
SenderIDtoBridgeContext; emitX-Sender-IDheader; include sender inSignBridgeContextpayload. - In
bridgeContextMiddleware, readX-Sender-ID, verify HMAC, callstore.WithSenderID(ctx, …). - Extend
VerifyBridgeContextwith a sender-aware level; keep existing levels as fallback for in-flight sessions. - At the bridge-context construction site (
claude_cli_session.go:171 bridgeContextFromOpts), populate fromstore.SenderIDFromContext(ctx)/ the corresponding option.
Workaround
Switch the agent's provider away from claude_cli (e.g. Anthropic native with the same Claude model). Tool calls then run in-process with sender preserved, and the existing grants work.
Related
CronJob row also has no SenderID field (internal/store/cron_store.go:20-38) and cmd/gateway_cron.go:98-111 re-fires jobs with an empty RunRequest.SenderID — same gate trips on every scheduled execution. Likely a separate follow-up.
Drafted by Claude (Claude Code) after end-to-end verification against the codebase at dev branch. File:line citations are from this commit. Reproduced and traced before filing.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with internal/providers/claude_cli_mcp.go and bridgeContextFromOpts in internal/providers/claude_cli_session.go, then trace bridgeContextMiddleware in internal/gateway/server.go and the permission checks in internal/store/config_permission_store.go. Verify the existing HMAC context tests or add focused coverage for a Telegram sender; done means SenderID reaches the bridge and cron and file-writer grants are evaluated for that sender.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100