feat(mcp): add --token flag and fix .mcp.json auth for Claude Code#90
Merged
Conversation
The daemon starts both the gateway and agent runtime concurrently. Both called load_or_generate_token() at the same time, hitting a two-step race: O_EXCL creates the file atomically, but the data write is a separate syscall — leaving a brief window where AlreadyExists was returned but the file was still empty. Two layers of defence: - OnceLock in load_or_generate_token() so same-process callers never race to the filesystem after the first call - wait_for_token() replaces the hard error on AlreadyExists, spinning up to 100 ms for the winning writer to flush (handles cross-process races) Adds test_concurrent_token_generation: 8 threads race to create the token and must all receive the same value. Also suppresses pre-existing clippy::const_is_empty lint in agent_setup tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add `bubbaloop mcp --token` to print the bearer token without starting a server, enabling the BUBBALOOP_MCP_TOKEN env var pattern. Fix the project .mcp.json to include the Authorization header so Claude Code can connect to the running daemon's HTTP MCP endpoint. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
6 tasks
edgarriba
added a commit
that referenced
this pull request
May 19, 2026
Ships 10 commits worth of features and fixes since v0.0.13: Features - agent: grab_frame tool + Gemini Vision provider + image-in-chat (#96) - dashboard: Chat tab with HTTP+SSE agent gateway (#91) - agent: client-side turn cancellation via Zenoh cancel topic (#94, #95) - chat: multi-provider login status, 404 on unknown agent, Claude OAuth risk warning (#93) - mcp: 'bubbaloop mcp --token' prints bearer token for .mcp.json (#90) Fixes - agent: grab_frame reads binary JPEG payload + JSON metadata attachment from camera nodes (#99) - chat: clear Responding state after multi-camera grab_frame (#98) - mcp: eliminate token race between gateway and agent runtime (#89) Chores - dashboard: remove LibraryView component (#92, replaced by Chat tab) Docs - Comprehensive sync across README, CHANGELOG (backfilled v0.0.8 to v0.0.13), CLAUDE.md, ARCHITECTURE.md, ROADMAP.md, concept/reference/ dashboard docs to match the new feature surface (#100) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bubbaloop mcp --token: new early-exit flag that prints the MCP bearer token (generating it if missing) — no Zenoh session needed. Enablesexport BUBBALOOP_MCP_TOKEN=$(bubbaloop mcp --token)in shell profiles..mcp.jsonauth fix: adds"headers": {"Authorization": "Bearer ${BUBBALOOP_MCP_TOKEN}"}so Claude Code can connect to the running daemon's HTTP MCP endpoint. Previously the server returned401 Unauthorizedand never appeared in Claude Code.docs/troubleshooting.mdenv vars table updated.Why the server wasn't showing up
The project
.mcp.jsonusedstreamable-httptransport (connects to the running daemon on port 8088), but the HTTP endpoint requires a bearer token. Claude Code sent the MCP init request without auth →401→ server never registered. The project config was also shadowing the global~/.claude/.mcp.jsonstdio config (same server name"bubbaloop"), so neither worked.The
${BUBBALOOP_MCP_TOKEN}pattern is the standard approach used by Hugging Face, Notion, and other MCP servers with auth.Test plan
bubbaloop mcp --tokenprints the token from~/.bubbaloop/mcp-tokenexport BUBBALOOP_MCP_TOKEN=$(bubbaloop mcp --token)then start Claude Code in this project — bubbaloop server appears in the MCP tool listbubbaloop mcp --tokenon a fresh machine (no token file) generates and prints a new tokenbubbaloop --helpshows--token: Print bearer token (for BUBBALOOP_MCP_TOKEN)🤖 Generated with Claude Code