Notes that I wrote for work on how to get started with Claude Code, Anthropic’s agentic code tool. Anthropic’s own documentation is good, but I wanted a single page that I could share with people to help them get rapidly up to speed.
Once past this stage, their Claude code best practices page is excellent.
Installation
You’ll need to setup an API key to use it. Put this in $ANTHROPIC_API_KEY
then run the installer:
$ npm install -g @anthropic-ai/claude-code
$ cd <project directory>
$ claude
# authorisation flow runs first time
# to update manually run the below but it auto-updates
$ npm update -g @anthropic-ai/claude-code
If you get an auth failure on macOS with fetch error
it’s possibly a certificate error. Use
$ export NODE_EXTRA_CA_CERTS=/etc/ssl/cert.pem
to fix this.
Usage Patterns
Claude Code supports, and works best with, a plan/act pattern but it’s not exposed directly in the UI and until recently wasn’t really documented.
So here’s what it looks like:
- Ask Claude to read relevant files etc
- Ask it to make a plan. Include the word ’think’ or stronger words. You could also use
/model
to switch to Opus for this bit. Remember to switch back to Sonnet after! - Ask it to implement the plan
- Ask it to commit the changes and create a pull request
Alternatively you can have it work in a TDD way:
- Say you’re doing TDD, and provide input/output pairs. Ask Claude to write tests
- Tell Claude to run the tests and confirm they fail
- Commit the tests
- Ask Claude to write code that passes the tests, without modifying the tests
- Repeat this. It may take a few iterations!
Claude also understands PR based workflows based around branches. Have it create a branch for the PR etc. It uses the gh
Github cli tooling for this.
For a variant of the first workflow, see Harper Reed’s blog post or video version. It’s especially interesting for the way he goes back and forth between Claude Code and a other models like Opus 4 or ChatGPT-o3. Here’s the expanded version with prompts:
-
Start with one LLM. Describe an idea/requirement and get it to ask a series of clarifying questions with Y/N answers:
Ask me one question at a time so we can develop a thorough, step-by-step spec for this idea. Each question should build on my previous answers, and our end goal is to have a detailed specification I can hand off to a developer. Let’s do this iteratively and dig into every relevant detail. Remember, only one question at a time.
Here’s the idea:
<IDEA>
-
Use another LLM or a new session to turn that series of questions into a
spec.md
document. Put this in the project rootNow that we’ve wrapped up the brainstorming process, can you compile our findings into a comprehensive, developer-ready specification? Include all relevant requirements, architecture choices, data handling details, error handling strategies, and a testing plan so a developer can immediately begin implementation
-
Now in a reasoning model
Draft a detailed, step-by-step blueprint for building this project. Then, once you have a solid plan, break it down into small, iterative chunks that build on each other. Look at these chunks and then go another round to break it into small steps. Review the results and make sure that the steps are small enough to be implemented safely with strong testing, but big enough to move the project forward. Iterate until you feel that the steps are right sized for this project. From here you should have the foundation to provide a series of prompts for a code-generation LLM that will implement each step in a test-driven manner. Prioritize best practices, incremental progress, and early testing, ensuring no big jumps in complexity at any stage. Make sure that each prompt builds on the previous prompts, and ends with wiring things together. There should be no hanging or orphaned code that isn’t integrated into a previous step. Make sure and separate each prompt section. Use markdown. Each prompt should be tagged as text using code tags. The goal is to output prompts, but context, etc is important as well.
<SPEC>
Save this as
prompt_plan.md
in the project -
Generate a todo from the plan
Can you make a
todo.md
that I can use as a checklist? Be thorough. -
And finally (!) open Claude Code and set it to work:
- Open @prompt_plan.md and identify any prompts not marked as completed.
- For each incomplete prompt:
- Double-check if it’s truly unfinished (if uncertain, ask for clarification).
- If you confirm it’s already done, skip it.
- Otherwise, implement it as described.
- Make sure the tests pass, and the program builds/runs
- Commit the changes to your repository with a clear commit message.
- Update @prompt_plan.md to mark this prompt as completed.
- After you finish each prompt, pause and wait for user review or feedback.
- Repeat with the next unfinished prompt as directed by the user.
Using CLAUDE.md files
Following the structure above gives Claude a way to work through a plan. But, as usual with LLMs,
giving context to the model is key.
If you want it to update something, give it an example of a before and after etc. Say which test library
you use. uv
or pip
? etc. The way to do this is via CLAUDE.md
files.
These can be very complex and give a lot of details - look at samples and more samples to get some ideas.
Claude reads information and guidance from CLAUDE.md
files in order:
first from the user’s home directory, then at the top level of the project, and then per-directory.
There’s also CLAUDE.local.md
which is the local, git-ignored version for storing working info, memories etc.
Use /memory
to see all these.
Per-project and directory level CLAUDE.md
files should be committed to source control and treated as shared artifacts!
It can also be good to ask Claude to add to the file itself when something has gone wrong and been solved “Add to CLAUDE.md an instruction to avoid this in future” or ask claude.ai to read and review the file periodically.
And if team members use different software (aider, codex etc), vibe-rules can be used to store a canonical version of the rules and translate them into different formats as needed.
Random other Hints and Tips
- Run
/compact
to free up context window space - If you finish working and want to resume later ask Claude to write out a summary of the session to a file and read that back in at the start of the next session
- The same trick works for complex tasks: tell Claude to use a Markdown file to store temporary results e.g.
run lint writing results to a file
, then then work through that file - Ask Claude to undo changes and think again if needed. Don’t just accept its suggestions!
- There are keywords to use more reasoning tokens, but they are only mentioned in passing in the docs:
We recommend using the word “think” to trigger extended thinking mode, which gives Claude additional computation time to evaluate alternatives more thoroughly. These specific phrases are mapped directly to increasing levels of thinking budget in the system: “think” < “think hard” < “think harder” < “ultrathink”
- Add custom slash commands. These are great for encoding the long prompts above!
- Claude can work in parallel which can be a time saver for bigger tasks:
> give me three options for new blog posts. Run three agents in parallel to do this
⏺ I'll generate three blog post ideas for you by running three agents in parallel.
⏺ Update Todos
⎿ ☐ Generate three blog post ideas
⏺ Call(Run three agents to generate blog post ideas)…
⎿ Task(Generate AI ethics blog idea)…
⎿ Task(Generate productivity blog idea)…
⎿ Task(Generate future tech blog idea)…
⎿ Done (3 tool uses · 9.7s)
⏺ Update Todos
⎿ ☒ Generate three blog post ideas
MCP Servers
The final hint is that Claude can be extended via MCP to connect to external services.
$ claude mcp list
$ claude mcp get my-server # get details
$ claude mcp remove my-server # delete
e.g. You can use Playwright for web testing/checking etc. Run claude mcp add
, choose CLI extension with the command
$ claude mcp add "docker run -i --rm --init --pull=always http://mcr.microsoft.com/playwright/mcp"
Claude will then have access to browse websites etc which allows things like “Move the location of this div, and check that it’s worked using playwright”
MCP has really taken off as a standard and there’s loads
of servers out there now, and the fast-mcp
python library makes it easy to build custom MCPs to connect to internal tooling