Claude Code Onboarding Guide
Read this first. It walks you through setting up Claude Code for SecurityV0 development, from a fresh clone to a fully working environment with skills, agents, hooks, and MCP integrations.
Related docs:
- Extensions Registry -- canonical list of plugins, skills, agents, MCP servers, and hooks
- Best Practices -- team-shareable lessons learned
What You Get
SecurityV0 ships four types of Claude Code extensions, all committed to the repos:
| Type | What it is | How you use it |
|---|---|---|
| Skills | Slash commands you type in Claude Code | /track, /review-pr, /deploy, /sync-notion |
| Agents | Specialist reviewers Claude can delegate to | ciso-reviewer, security-auditor, doc-reviewer |
| Hooks | Scripts that run automatically on certain events | GitHub issue injection on prompt, Slack summary on stop |
| MCP Servers | Direct API connections to external services | GitHub (issues, PRs), Notion (pages, databases) |
You don't need to install or configure most of these -- they come with the repos. For the full inventory of every extension, see the Extensions Registry.
Prerequisites
Before starting:
- Claude Code CLI installed (
claudecommand available in terminal) -
ghCLI installed and authenticated (gh auth statusshould show a logged-in account with access to the SecurityV0 org) - Git access to all five repos:
sv0-platform,sv0-documentation,sv0-connectors,sv0-website,sv0-skills - uv installed --
uv --versionshould work. Install:brew install uv(macOS). Required for sv0-skills render dependencies. - Docker via Colima installed (see Docker Setup section below)
- Node.js 20+ and Python 3.11+ (for running platform and connectors locally)
Docker Setup (Colima)
We use Colima as the Docker runtime on macOS. Two separate profiles keep long-running bots isolated from bursty dev work.
Install
brew install colima docker docker-compose
Create profiles
# "default" — long-running services (n8n, openclaw bots)
colima start --memory 2 --cpu 2 --disk 60
# "sv0-dev" — sv0-platform local development and PR testing
colima start --profile sv0-dev --memory 2 --cpu 2 --disk 30
This creates two lightweight VMs (2 GB RAM each). Stop sv0-dev when not doing dev work to free memory.
Switch between profiles
Each Colima profile gets its own Docker context. Switch before running docker compose:
# Platform dev work
docker context use colima-sv0-dev
cd ~/dev/securityv0/sv0-platform
docker compose up --build -d
# Bot management
docker context use colima
# Check which context is active
docker context ls
Lifecycle
# Stop the dev VM when done (frees 2 GB RAM)
colima stop sv0-dev
# Start it back up when needed
colima start --profile sv0-dev
# Check both profiles
colima list
Resource guidance
| Profile | Memory | CPU | Disk | Always-on? |
|---|---|---|---|---|
default | 2 GB | 2 | 60 GB | Yes — bots and n8n |
sv0-dev | 2 GB | 2 | 30 GB | No — start for platform work |
The sv0-platform stack (MongoDB + API + UI) uses under 1 GB. 2 GB per VM is sufficient.
Step-by-Step Setup
1. Clone all repos into a shared parent folder
mkdir -p ~/dev/securityv0 && cd ~/dev/securityv0
git clone git@github.com:SecurityV0/sv0-platform.git
git clone git@github.com:SecurityV0/sv0-documentation.git
git clone git@github.com:SecurityV0/sv0-connectors.git
git clone git@github.com:SecurityV0/sv0-website.git
git clone git@github.com:SecurityV0/sv0-skills.git
Your directory should look like:
securityv0/
├── sv0-platform/
├── sv0-documentation/
├── sv0-connectors/
├── sv0-website/
└── sv0-skills/ ← shared Claude Code skills
2. Shared skills -- zero setup
Shared skills in sv0-skills/ are auto-discovered by every SV0 repo. No symlinks or manual setup needed -- just having the repo cloned as a sibling is enough.
How it works: every repo's .claude/settings.json includes "../sv0-skills" in additionalDirectories. Claude Code scans .claude/skills/ inside additional directories on startup and finds the symlinks pointing to each skill.
# Optional: install render dependencies for excalidraw-diagram
cd ~/dev/securityv0/sv0-skills/excalidraw-diagram/references
uv sync
PLAYWRIGHT_BROWSERS_PATH=.playwright-browsers uv run playwright install chromium
Verify: open any repo in Claude Code and type /sprint-review -- it should appear in autocomplete.
3. Open the repo you're working in
Start each Claude Code session from inside the specific repo you want to work on:
cd ~/dev/securityv0/sv0-platform # or sv0-connectors, sv0-documentation, etc.
claude
One terminal per repo. If you need two Claude Code sessions working on the same repo at once, use worktrees -- see Git Workflow, Branching, and Worktrees.
You can also start from the parent securityv0/ folder -- it has its own CLAUDE.md and .claude/settings.json with all repos in additionalDirectories. Both approaches work.
4. Cross-repo access -- automatic
Each repo's .claude/settings.json already includes all sibling repos in additionalDirectories. No manual /add-dir commands needed. Claude Code can read/write files across all SV0 repos, and shared skills from sv0-skills are auto-discovered.
Claude also walks up the directory tree to load parent
CLAUDE.mdfiles, so the workspace-levelsecurityv0/CLAUDE.mdis always available regardless of which repo you start from.
5. MCP Servers -- GitHub and Notion
Install the GitHub and Notion MCP servers using the Claude Code CLI:
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
claude mcp add --transport http notion https://mcp.notion.com/mcp
These are stored in your user-level config (~/.claude/) and persist across sessions. Verify with /mcp -- both should appear as connected after OAuth (see Step 6).
Note: Earlier versions of this guide referenced a committed
sv0-documentation/.mcp.jsonfile. That approach was replaced with user-levelclaude mcp addcommands, which are simpler and avoid committing auth-adjacent config to the repo.
6. First-use OAuth
On first use, each MCP server will prompt you to authenticate:
- GitHub MCP: Opens a browser for GitHub OAuth. Authorize the "GitHub Copilot" app. This gives Claude Code read/write access to issues, PRs, and repos you have access to.
- Notion MCP: Opens a browser for Notion OAuth. Authorize access to the SecurityV0 workspace. This gives Claude Code read/write access to pages and databases.
These are one-time authorizations. Tokens are cached locally.
7. Install recommended plugins
Plugins extend Claude Code with LSP diagnostics, workflow skills, and memory management. Install from the official marketplace:
# TypeScript LSP — real-time type diagnostics after every edit (strongly recommended)
claude plugin install typescript-lsp
# Superpowers — 15 battle-tested skills for TDD, debugging, planning, worktrees, code review
claude plugin install superpowers
# Claude-mem — cross-session memory capture and intelligent retrieval
claude plugin marketplace add thedotmack/claude-mem
claude plugin install claude-mem@thedotmack
Verify: restart Claude Code, then run /plugin to confirm all plugins show as enabled.
For the full list of evaluated plugins and skills, see the Extensions Registry.
8. (Optional) Set up Slack notifications
If you want Claude Code session summaries posted to #sv0-dev:
- Get the Slack webhook URL from a team member
- Create
.claude/settings.local.jsoninsv0-platform(this file is gitignored):
{
"env": {
"SLACK_WEBHOOK_URL": "https://hooks.slack.com/services/T.../B.../..."
}
}
Without this, the Slack hook runs silently and does nothing -- it won't error.
Understanding settings.local.json (used by Step 8)
The settings.local.json file is the local-only counterpart to the committed settings.json. It's gitignored in every repo and is used for:
- Environment variables -- secrets like
SLACK_WEBHOOK_URLthat shouldn't be committed - Experimental flags -- feature flags like
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS - Personal permission overrides -- additional bash commands you want to allow without prompting
The file goes in <repo>/.claude/settings.local.json. Claude Code merges it with the committed settings.json at runtime. If you need workspace-wide settings (shared across all repos), place the file at the workspace root level instead.
9. Verify everything works
Run these checks to confirm your setup:
/track status
Should list open GitHub Issues assigned to you across SecurityV0 repos (or show "no issues" if you have none).
/mcp
Should show github and notion servers as connected.
Try invoking an agent:
Ask the doc-reviewer agent to check the runbooks index page
Claude should spawn the doc-reviewer agent and return a report.
Architecture Decisions
When to use skills vs agents vs MCP
| Mechanism | What it is | When to use |
|---|---|---|
Skills (.claude/skills/) | Reusable instruction sets with optional tool restrictions | Repeatable workflows: /deploy, /review-pr, /sync-notion |
Agents (.claude/agents/) | Autonomous specialists with own context, memory, and tool access | Personas that think differently: security auditor, CISO analyst |
| MCP Servers | External service connectors (GitHub, Notion, Slack, Jira) | API access to SaaS tools without scripting |
These compose: an agent can preload skills and use MCP servers.
Skill placement rules
Goes in sv0-skills (shared) | Stays in repo .claude/skills/ |
|---|---|
| Useful across all SV0 repos | Only makes sense in one repo |
| No hardcoded paths or server IPs | References deployment targets, config file paths, Notion IDs |
| Pure capability (diagram, review, track) | Repo-specific workflow (deploy, sync-notion) |
Composition scenarios
Developer starts a new feature:
- Developer describes the task to Claude Code
UserPromptSubmithook injects open GitHub Issues (existing)- Claude reads AGENTS.md -- runs
/track createto create an issue - Claude implements the feature
- Claude runs
/review-pron the PR ciso-revieweragent is spawned to validate UX copy and finding descriptions- Claude runs
/track closewith completion summary Stophook posts session summary to Slack
Notion spec is updated:
- Developer runs
/sync-notion <url> - Skill fetches page via Notion MCP, converts to markdown, writes to repo
- Claude auto-invokes
doc-revieweragent to check if the sync changed anything that contradicts the codebase - Developer reviews the diff and commits
Deployment:
- Developer runs
/deploy production - Skill runs pre-flight checks (tests, lint, clean tree)
- Skill asks for confirmation
- Deploys via SSH + Docker
- Runs smoke test
- Posts to Slack via webhook
File Map
What's committed vs. local-only, and which repo owns what:
sv0-platform/ # Primary workspace
├── .claude/
│ ├── settings.json # [committed] Hook configuration
│ ├── settings.local.json # [local-only] SLACK_WEBHOOK_URL
│ ├── hooks/
│ │ ├── check-github-issues.sh # [committed] UserPromptSubmit hook
│ │ └── session-summary-to-slack.sh # [committed] Stop hook
│ ├── skills/
│ │ └── deploy/SKILL.md # [committed] /deploy skill
│ └── agents/
│ ├── ciso-reviewer.md # [committed] CISO perspective agent
│ └── security-auditor.md # [committed] Security audit agent
sv0-documentation/ # Shared skills + agents
├── .claude/
│ ├── skills/
│ │ ├── track/SKILL.md # [committed] /track skill
│ │ ├── review-pr/SKILL.md # [committed] /review-pr skill
│ │ └── notion/SKILL.md # [committed] /notion skill (sync, diff)
│ └── agents/
│ └── doc-reviewer.md # [committed] Doc accuracy agent
sv0-connectors/ # No Claude Code extensions yet
└── (no .claude/ directory)
sv0-website/ # Static marketing site
├── .claude/
│ └── settings.json # [committed] Git safety deny rules
└── AGENTS.md # [pending — see PR sv0-website#4]
sv0-skills/ # Shared skills (auto-discovered)
├── .claude/
│ └── skills/ # [committed] Symlinks for auto-discovery
│ ├── sprint-review -> ../../sprint-review
│ ├── excalidraw-diagram -> ../../excalidraw-diagram
│ ├── review-pr -> ../../review-pr
│ ├── track -> ../../track
│ ├── stakeholder-review -> ../../stakeholder-review
│ └── platform-visual-capture -> ../../platform-visual-capture
├── sprint-review/
│ └── SKILL.md # [committed] Sprint review skill + config
├── excalidraw-diagram/
│ └── SKILL.md # [committed] Excalidraw diagram skill
├── CLAUDE.md # [committed]
└── AGENTS.md # [committed]
securityv0/ # Workspace root (not a git repo)
├── CLAUDE.md # [local] Workspace-level context
└── .claude/
└── settings.json # [local] additionalDirectories for all repos
Everything marked [committed] comes with the repo -- no manual setup needed. The only local-only file is settings.local.json for the optional Slack webhook.
VS Code Workspace Setup
Create a single multi-root workspace file at ~/dev/securityv0/securityv0.code-workspace:
{
"folders": [
{ "name": "platform", "path": "sv0-platform" },
{ "name": "connectors", "path": "sv0-connectors" },
{ "name": "documentation", "path": "sv0-documentation" },
{ "name": "website", "path": "sv0-website" },
{ "name": "skills", "path": "sv0-skills" }
]
}
Open it with code securityv0.code-workspace from ~/dev/securityv0/. This gives you cross-repo navigation, search, and the git panel for all repos in one VS Code window.
For Claude Code terminals inside VS Code: open one integrated terminal tab per repo, cd into the specific repo, then run claude. The multi-root workspace is for navigation -- Claude Code sessions must still be started from inside the specific repo directory.
Troubleshooting
/track returns "gh: command not found"
Install the GitHub CLI: brew install gh (macOS) or see cli.github.com. Then authenticate: gh auth login.
MCP servers don't appear in /mcp
- Check that
sv0-documentationis added as an additional directory (/add-dir ../sv0-documentation) - If still missing, install manually:
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
claude mcp add --transport http notion https://mcp.notion.com/mcp
GitHub OAuth prompt keeps appearing
Your GitHub token may have expired. Re-authenticate: gh auth login for the CLI, or revoke and re-authorize the "GitHub Copilot" app in GitHub Settings > Applications for the MCP server.
Slack hook doesn't post anything
- Confirm
SLACK_WEBHOOK_URLis set insv0-platform/.claude/settings.local.json - Confirm the webhook URL is valid (test with
curl -X POST -d '{"text":"test"}' $SLACK_WEBHOOK_URL) - The hook only posts when commits exist in the last 10 minutes -- research/chat sessions produce no output
Agent invocation fails with "agent not found"
Agents are discovered from .claude/agents/ directories. Make sure:
sv0-platformis your primary workspace (forciso-reviewer,security-auditor)sv0-documentationis added as additional directory (fordoc-reviewer)
"Permission denied" on hook scripts
chmod +x sv0-platform/.claude/hooks/*.sh
Skills don't appear in autocomplete
Shared skills (/sprint-review, /track, etc.): confirm sv0-skills is cloned as a sibling and the repo's .claude/settings.json has "../sv0-skills" in additionalDirectories. Check with ls ../sv0-skills/.claude/skills/ -- you should see symlinks for all skills.
Per-repo skills (/deploy, /notion): these only appear when working inside the repo that defines them. They live in <repo>/.claude/skills/.
Plugins (superpowers skills): confirm plugins are installed with claude plugin list. Restart Claude Code after installing new plugins.