SETUP GUIDE · ASYNC · COPY-PASTE READY
Claude Code: a project setup that survives you leaving
A written, async setup. No call, no video. You copy each block, run it, and verify the result before moving on. By the end you have a project Claude Code understands, MCP servers wired and verified, and guardrails that stop bad actions before they happen.
Portfolio sample
A demonstration of the method. Your delivered guide targets your stack, your repo, and your tools, with tailored configuration and step-by-step annotations.
What this guide delivers.
01
Project memory
A CLAUDE.md that encodes your stack, conventions, and hard rules, so every session starts aligned.
02
Verified MCP servers
External tools connected and confirmed working, added one at a time so failures are obvious.
03
Guardrails
Permissions and hooks that block destructive actions structurally, not by hoping nobody runs them.
Before you start.
Three things must be true. Confirm each before touching the project.
| Requirement | Why | Check |
|---|---|---|
| Node.js 18 or newer | Claude Code and most MCP servers run on Node. | node -v |
| Claude Code installed | The CLI itself. | claude --version |
| Git repository | CLAUDE.md and settings live at the repo root. | git status |
# install Claude Code globally
npm install -g @anthropic-ai/claude-code
# start it inside your project
cd my-project
claude
First run will prompt you to authenticate. Once done, the session opens in your project root.
Give the project a memory.
CLAUDE.md is the single highest-leverage file. Claude Code reads it on every session in this repo. Keep it short, specific, and imperative. Vague rules get ignored; concrete ones get followed.
Run the init command inside the session. It scans the repo and drafts a CLAUDE.md you then trim.
/initCut the boilerplate. A good CLAUDE.md has four blocks: stack, conventions, commands, and hard "do not" rules.
# Project: Acme API
## Stack
Node.js 20, Fastify, PostgreSQL, Vitest.
## Conventions
- Absolute imports only (@/...), never relative.
- Files kebab-case. Conventional commits.
- Every new function gets a test.
## Commands
- Test: npm test
- Lint: npm run lint
- Build: npm run build
Run test + lint before marking any task done.
## Do not
- Touch /migrations without asking.
- Add a dependency without a one-line reason.
- Commit secrets or .env files.anatomy: why each block exists
| Block | What it controls | Failure if missing |
|---|---|---|
| Stack | Frames every suggestion to your tools. | Claude proposes the wrong library or pattern. |
| Conventions | Import style, naming, commit format. | Inconsistent code you fix by hand later. |
| Commands | How to test, lint, build. | Tasks marked done without verification. |
| Do not | Hard boundaries. | The one mistake that costs you a day. |
Wire in external tools.
MCP servers give Claude real tools: live docs, browser control, databases. Add one, verify it, then add the next. Adding five at once hides which one failed.
# 1. up-to-date library docs (prevents stale-API hallucinations)
claude mcp add context7 -- npx -y @upstash/context7-mcp
# 2. browser automation for UI checks
claude mcp add playwright -- npx -y @playwright/mcp@latest
# verify after EACH add
claude mcp list
| Server | Use it for | Skip it if |
|---|---|---|
| context7 | Current docs for any library, so generated code matches the real API. | You only touch internal code. |
| playwright | Screenshots, clicking through a running app, console checks. | No web UI in the project. |
Verify each addition before the next. If claude mcp list shows a server as prompts instead of connected, its auth failed. Fix it before adding more, or you will not know which one broke.
Make the wrong action impossible.
settings.json controls permissions and hooks. Permissions decide what runs without asking. Hooks run your own checks at defined moments. Together they stop bad actions structurally.
{
"permissions": {
"allow": ["Bash(npm test)", "Bash(npm run lint)"],
"deny": ["Bash(rm -rf*)", "Read(.env)"]
},
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{ "type": "command",
"command": "./.claude/guard.sh" }]
}]
}
}
| Mechanism | When it fires | Example |
|---|---|---|
| permissions.allow | Auto-approves safe, repeated commands. | Run tests without a prompt every time. |
| permissions.deny | Hard block, no override in-session. | Never read .env, never rm -rf. |
| PreToolUse hook | Before a tool runs. | Reject a commit that has no story reference. |
Prove it works.
claude mcp list
# expect: context7 ✓ connected
# expect: playwright ✓ connected
When it doesn't work.
| Symptom | Likely cause | Fix |
|---|---|---|
| Server shows "(N prompts)" not "(N tools)" | Authentication did not pass to the server. | Re-check the API key or env var. Re-add the server and verify. |
| Claude ignores your conventions | CLAUDE.md too long or too vague. | Cut to one page. Make rules imperative, not aspirational. |
| A denied command still runs | Pattern in deny list does not match. | Test the matcher. Patterns are specific; broaden carefully. |
| MCP server times out | Wrong command or missing package. | Run the npx command manually to see the real error. |
Where you land.
Project memory, verified MCP servers, and guardrails, all documented so a teammate can repeat it.