Skip to content

docs: day-to-day Claude Code setup (closes #9) - #18

Merged
tylervick merged 2 commits into
mainfrom
tylervick/claude-code-docs
Jul 29, 2026
Merged

tylervick merged 2 commits into
mainfrom
tylervick/claude-code-docs

Conversation

@tylervick

Copy link
Copy Markdown
Owner

Summary

Documents the Claude Code connection flow exactly as validated today against real hardware (v0.1.0 release binary, read-only mode): SSH master socket + tunnel with one auth, the dropbear agent-flood workaround discovered during setup, tunnel liveness check, bearer token pulled to a file and used by reference everywhere, claude mcp add with unexpanded ${VAR}, and fresh-session pickup.

Scoped to Claude Code per discussion — durable access is #16, Claude Desktop and other clients are #17.

Closes #9.

🤖 Generated with Claude Code

Replaces the generic SSH-tunnel section with the exact flow proven
end-to-end against a real device: master socket carrying the tunnel
(one auth), the dropbear agent-flood gotcha, tunnel liveness check,
token-to-file with by-reference usage everywhere, and fresh-session
pickup. Durable access is #16; other MCP clients are #17.

Closes #9.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@tylervick, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 51 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cca64370-909b-4dae-a7ba-067e03822766

📥 Commits

Reviewing files that changed from the base of the PR and between e09679d and 5f6613c.

📒 Files selected for processing (1)
  • README.md
📝 Walkthrough

Walkthrough

The README replaces one-off SSH forwarding instructions with a tested workflow using a persistent SSH master connection, protected MCP token retrieval, Claude Code registration, session guidance, and MCP Inspector verification.

Changes

Claude Code SSH setup

Layer / File(s) Summary
Persistent tunnel and endpoint verification
README.md
Documents SSH ControlMaster/ControlPersist forwarding, tunnel health checks, protected token extraction, shell-safe Claude Code registration, read-only and mutating session guidance, and MCP Inspector verification.

Estimated code review effort: 1 (Trivial) | ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR covers the Claude Code flow, but issue #9 also asks for Claude Desktop and day-to-day access guidance that isn't documented. Add the missing day-to-day guidance for Claude Desktop, tunnel keepalive or Tailscale, and read-only versus full-mode recommendations.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: documenting the day-to-day Claude Code setup.
Description check ✅ Passed The description is clearly related and summarizes the documented Claude Code SSH tunnel flow.
Out of Scope Changes check ✅ Passed The changes stay within documentation updates for the Claude Code setup and don't add unrelated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tylervick/claude-code-docs

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Around line 211-218: Update the README token retrieval command to handle an
unset NANOKVM_MCP_TOKEN by extracting the auto-generated token from daemon.log
or reporting a clear error, rather than creating an empty token file. Write the
result to a temporary file with 0600 permissions, validate that a non-empty
token was obtained, then atomically rename it to ~/.nanokvm-token.
- Around line 185-191: Update the SSH tunnel documentation around the “Claude
Code over an SSH tunnel” section to describe ControlPersist=3600 as an idle
timeout: the master connection remains active beyond one hour when reused, and
exits only after 3600 seconds without connections. Apply the same clarification
to the related text in the setup flow.
- Around line 196-199: Update the SSH command in the README to include the
ExitOnForwardFailure=yes option alongside the existing SSH options, ensuring ssh
-f only backgrounds after the local port forward is successfully established.
- Around line 237-242: Update the MCP Inspector example near the tools/list
invocation to avoid interpolating NANOKVM_MCP_TOKEN into command-line arguments.
Use a supported file/config-based header mechanism, or replace the command with
a documented non-CLI validation method that does not expose the bearer token
through process arguments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9fda99b5-140c-4956-ba0f-6d97031c4bd4

📥 Commits

Reviewing files that changed from the base of the PR and between fc2a7ae and e09679d.

📒 Files selected for processing (1)
  • README.md

Comment thread README.md Outdated
Comment thread README.md
Comment thread README.md
Comment thread README.md
Comment on lines +237 to +242
To sanity-check the endpoint without Claude, use MCP Inspector:

```sh
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8080/ \
--transport http --header "Authorization: Bearer ${NANOKVM_MCP_TOKEN}" --method tools/list
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant README section with line numbers
sed -n '220,255p' README.md

# Find other Inspector references in the repo
rg -n "modelcontextprotocol/inspector|MCP Inspector|NANOKVM_MCP_TOKEN|Authorization: Bearer" -S .

Repository: tylervick/nanokvm-mcp

Length of output: 5632


🌐 Web query:

@modelcontextprotocol/inspector CLI --header file stdin environment variable bearer token documentation

💡 Result:

The @modelcontextprotocol/inspector CLI supports custom HTTP headers, including bearer tokens, through the --header flag [1][2]. When using the CLI mode, you can pass authentication credentials by providing the header directly in the command [3][4]. The format requires the header name and value, typically structured as an Authorization header for bearer tokens [2][3]. Usage example: npx @modelcontextprotocol/inspector --cli https://example.com/mcp --transport http --method tools/list --header "Authorization: Bearer YOUR_TOKEN" Key details regarding this functionality: - Multiple --header flags: You can pass multiple --header flags in a single command if needed [2]. - Format: The argument must follow the "HeaderName: Value" format [1][2]. - Transport Compatibility: The headers are passed to both HTTP and SSE transports [2]. - Environment Variables: While the CLI supports the --header flag for ad-hoc requests, environment variables are not a native, direct configuration mechanism for header injection in the Inspector CLI itself; you should inject the variable into the command string (e.g., --header "Authorization: Bearer ${MY_TOKEN}") [2][4]. - Limitations: There have been reports that in some scenarios, specifically involving the Inspector's own proxy mechanisms, custom headers might be misinterpreted or overwritten if they conflict with internal authentication headers [5][6]. Ensure your header names do not conflict with reserved proxy headers if you are experiencing connectivity issues [6]. For standard testing, using the --header flag as shown above is the official and recommended method for providing bearer tokens to remote MCP servers via the Inspector CLI [2][3].

Citations:


🌐 Web query:

@modelcontextprotocol/inspector README --header stdin file environment variable inspector cli auth bearer token

💡 Result:

The @modelcontextprotocol/inspector is a developer tool used for testing and debugging MCP servers [1][2]. It provides a CLI mode, a web-based UI, and a Terminal UI (TUI), all executable via npx [3][4]. Regarding your specific areas of interest: Environment Variables and Auth For authentication, particularly when running in containerized environments, you can manage tokens using environment variables [5]: - MCP_INSPECTOR_API_TOKEN: Use this to set a known bearer token for the inspector [5]. If not set, one is automatically generated and displayed in the logs [5]. - DANGEROUSLY_OMIT_AUTH: Set this to true to disable authentication entirely [5][6]. - DANGEROUSLY_BIND_ALL_INTERFACES: Set this to true if you need to bind the inspector to 0.0.0.0, which is otherwise refused by default for security reasons [5]. CLI and Bearer Tokens - CLI Mode: The CLI allows for programmatic interaction with MCP servers (e.g., npx @modelcontextprotocol/inspector --cli ) [3][7]. - Bearer Tokens in UI: When using the web UI to connect to remote servers (e.g., SSE transport), you can provide a bearer token in the sidebar [7]. The inspector includes this in the Authorization header [7]. Note that there have been reports of the proxy session token potentially overwriting the Authorization header if they share the same name [6]; users are advised to use a different header name or set DANGEROUSLY_OMIT_AUTH if conflicts arise [6]. Stdin/File Configuration - The inspector supports configuring servers via command-line arguments or configuration files [1][3]. You can use --config to point to a configuration file that defines server launch commands, environment variables, and other parameters [1][7]. - When inspecting locally developed servers, the tool can be invoked with the server's command directly in the CLI, or by using a config file to manage multiple server definitions [1][7]. Detailed documentation on server configuration (including catalog vs. config files and per-server fields) is available in the project's docs/ directory [3].

Citations:


🌐 Web query:

@modelcontextprotocol/inspector config headers authorization bearer token --config

💡 Result:

To configure an authorization bearer token in the Model Context Protocol (MCP) Inspector, you can use the web interface or command-line arguments depending on your setup. Web Interface Configuration The Inspector UI allows you to add custom headers to your connection settings to support bearer token authentication [1][2][3]. 1. Open the MCP Inspector interface [4][5]. 2. Click the Configuration button (or "Add Header" in the connection setup area) [6][7][2]. 3. Add a new header entry [2]. 4. Set the Header field to Authorization and the Value field to Bearer YOUR_TOKEN [2][3]. Recent updates have enhanced header management, allowing for multiple custom headers and flexible configurations [1]. The UI now supports both form-based and JSON editor modes for these headers [1]. These settings are stored in your browser's local storage for persistence between sessions [8][3]. Command-Line Configuration When starting the Inspector from the command line, you can pass custom headers directly using the --header argument [6][9]. Example command: npx @modelcontextprotocol/inspector --cli https://my-mcp-server.example.com --transport http --header "Authorization: Bearer your-api-key" Proxy Authentication If you are running the MCP Inspector proxy, note that it requires its own authentication by default [6][10]. A session token is generated when the proxy starts and is printed to the console [6][4]. This token must be included as a Bearer token in the Authorization header for all requests to the proxy server [6][10]. You can also specify this token using the MCP_PROXY_AUTH_TOKEN environment variable when starting the server [6][4][10]. Top Results: [6], [1], [2], [3], [5]

Citations:


Avoid interpolating the token in the Inspector CLI example. Shell expansion puts ${NANOKVM_MCP_TOKEN} into the spawned process’s argv, so the bearer token is exposed to ps/local users. Use a file/config-based header path if this Inspector release supports one, or document a non-CLI check instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 237 - 242, Update the MCP Inspector example near the
tools/list invocation to avoid interpolating NANOKVM_MCP_TOKEN into command-line
arguments. Use a supported file/config-based header mechanism, or replace the
command with a documented non-CLI validation method that does not expose the
bearer token through process arguments.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Caveat added in 5f6613c rather than restructuring: per your own research above, Inspector has no file/config-based header mechanism — --header interpolation is its official method — and the primary flow (claude mcp add) already keeps the secret out of argv via the unexpanded ${VAR}. The note flags the ps exposure and points shared-host users at curl's @file header form.

…ken-file hardening

- ControlPersist=3600 described as an idle timeout, not a 1-hour cap
- ExitOnForwardFailure=yes so a failed -L bind fails loudly instead of
  backgrounding a broken master
- token pull: umask 077 subshell (no permissive window) + test -s guard
  for the unset-token path
- note that the Inspector CLI example exposes the token to ps (no
  file-based header exists in Inspector); curl @file suggested for
  shared hosts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@tylervick
tylervick merged commit ec4ca0a into main Jul 29, 2026
3 checks passed
@tylervick
tylervick deleted the tylervick/claude-code-docs branch July 29, 2026 18:58
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.

Document day-to-day Claude Desktop/Code setup

1 participant