doc(zulip-mpc): add zulip-mcp team setup instructions #15616
doc(zulip-mpc): add zulip-mcp team setup instructions #15616
Conversation
Write-up of the macOS + Docker Desktop setup we landed on for running a companion Zulip MCP container, including Keychain-backed secret handling, Claude Code registration, write-tool allowlist, and the honest threat model so readers know the container is an isolation boundary, not a vault. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Rephrased a specific debugger tool name to a generic term to satisfy cspell without polluting the dictionary for a doc that may move out of this repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the grafana-mcp-setup.md precedent so the setup guide shows up in the rendered book under Misc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds internal documentation for setting up a Zulip MCP server alongside Claude Code using a companion Docker container on macOS, and links it into the mdBook docs index.
Changes:
- Add a new setup guide covering Keychain-backed secret injection, Claude Code registration, a write-tool denylist, troubleshooting, and a threat model.
- Link the new guide from
docs/SUMMARY.mdso it appears in the built docs.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| docs/zulip-mcp-setup.md | New end-to-end setup guide for Zulip MCP on macOS + Docker Desktop |
| docs/SUMMARY.md | Adds the new Zulip MCP doc to the mdBook table of contents |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| your API key stays isolated — it lives only in the container's process env and | ||
| your macOS Keychain, never in Claude's conversation context or reachable by | ||
| Claude's own tools (when Claude runs in a different container). |
There was a problem hiding this comment.
The intro claims the API key “lives only in the container's process env and your macOS Keychain”. With the provided start.sh, the key is also present (at least briefly) in the environment of the host-side docker compose up process that reads it, so it’s not strictly limited to container env + Keychain. Please reword the sentence (or call out the brief host-process exposure) so the threat model remains accurate.
| your API key stays isolated — it lives only in the container's process env and | |
| your macOS Keychain, never in Claude's conversation context or reachable by | |
| Claude's own tools (when Claude runs in a different container). | |
| your API key stays isolated from Claude's conversation context and from Claude's | |
| own tools (when Claude runs in a different container). In this setup, the key is | |
| stored in your macOS Keychain, passed into the companion container's process env, | |
| and may also be briefly present in the environment of the host-side `docker compose up` | |
| process that reads it. |
| ### 2. Store your API key in the macOS Keychain | ||
|
|
||
| ```bash | ||
| security add-generic-password -s zulip-mcp -a you@nearone.org -w |
There was a problem hiding this comment.
security add-generic-password will error on re-runs if the zulip-mcp item already exists (“item already exists in the keychain”). Consider making the command idempotent by using the update option (e.g. -U) or documenting how to delete/replace an existing entry.
| security add-generic-password -s zulip-mcp -a you@nearone.org -w | |
| security add-generic-password -U -s zulip-mcp -a you@nearone.org -w |
| set -euo pipefail | ||
| cd "$(dirname "$0")" | ||
|
|
||
| ZULIP_API_KEY="$(security find-generic-password -s zulip-mcp -w)" \ |
There was a problem hiding this comment.
The Keychain entry is created with an account (-a you@nearone.org) but retrieved without -a. If a user has multiple zulip-mcp entries under different accounts, find-generic-password -s zulip-mcp may return the wrong one. Please include the same -a ... (or otherwise disambiguate) on the read path.
| ZULIP_API_KEY="$(security find-generic-password -s zulip-mcp -w)" \ | |
| set -a | |
| source ./.env | |
| set +a | |
| ZULIP_API_KEY="$(security find-generic-password -s zulip-mcp -a "$ZULIP_EMAIL" -w)" \ |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #15616 +/- ##
==========================================
- Coverage 69.40% 69.39% -0.01%
==========================================
Files 940 942 +2
Lines 212756 213590 +834
Branches 212756 213590 +834
==========================================
+ Hits 147655 148225 +570
- Misses 59249 59462 +213
- Partials 5852 5903 +51
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| - Use a **dedicated bot key** so rotation is cheap and blast radius is | ||
| bounded to streams the bot is subscribed to. | ||
| - Keep the **write-tool allowlist** above to prevent accidental sends. | ||
| - On Keychain, optionally turn on **Confirm before allowing access** (see |
There was a problem hiding this comment.
Since you opted for keychain use, not enabling the fingerprint/password prompt is as safe as storing the token in a file.
There was a problem hiding this comment.
Nice catch, let me recommend that as well.
Reviewer noted that without the confirmation prompt the Keychain entry is silently readable by any user-owned process, equivalent to a chmod-600 file. Promote the ACL hardening from optional to required, add a forward pointer from the storage step, and reframe the security notes to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Write-up of the macOS + Docker Desktop setup for running a companion Zulip MCP container, including Keychain-backed secret handling, Claude Code registration, write-tool allowlist, and the honest threat model so readers know the container is an isolation boundary, not a vault.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com