Claude Code in Action: Takeaways

Coding Assistants

When you give a coding assistant a task, like fixing a bug based on an error message, it follows a process similar to how a human developer would approach the problem:

  • Gather context
  • Formulate a plan
  • Take action

Language models by themselves can only process text and return text - they can’t actually read files or run commands. If you ask a standalone language model to read a file, it will tell you it doesn’t have that capability.

So how do coding assistants solve this problem? They use a clever system called “tool use.”

Understanding coding assistants comes down to a few essential points:

  • Coding assistants use language models to complete different tasks
  • Language models need tools to handle most real-world programming tasks
  • Not all language models use tools with the same skill level
  • Claude’s strong tool use enables better security, customization, and longevity in Claude Code

Context

The CLAUDE.md file

The /init command will generate a CLAUDE.md file which tells Claude to analyze your entire codebase and understand:

  • The project’s purpose and architecture
  • Important commands and critical files
  • Coding patterns and structure

This file gets included in every request you make to Claude, so it’s like having a persistent system prompt for your project.

CLAUDE.md file location:

  • CLAUDE.md - Generated with /init, committed to source control, shared with other engineers
  • CLAUDE.local.md - Not shared with other engineers, contains personal instructions and customizations for Claude
  • ~/.claude/CLAUDE.md - Used with all projects on your machine, contains instructions that you want Claude to follow on all projects

Use the # command to enter “memory mode” - this lets you edit your CLAUDE.md files intelligently. Just type something like:

# Use comments sparingly. Only comment complex code.

Claude will merge this instruction into your CLAUDE.md file automatically.

When you need Claude to look at specific files, use the @ symbol followed by the file path. This automatically includes that file’s contents in your request to Claude.

You can also mention files directly in your CLAUDE.md file using the same @ syntax. For example:

The database schema is defined in the @prisma/schema.prisma file. Reference it anytime you need to understand the structure of data stored in the database.

When you mention a file this way, its contents are automatically included in every request, so Claude can answer questions about your data structure immediately without having to search for and read the schema file each time.

One of the most effective ways to communicate with Claude is through screenshots. To paste a screenshot into Claude, use Ctrl+V (not Cmd+V on macOS).

Control Context

  • Interrupt with Escape: This is particularly useful when you want Claude to focus on one specific task instead of trying to handle multiple things simultaneously.
  • Combine Escape with memories: One of the most powerful applications of the escape technique is fixing repetitive errors.
    • Press Escape to stop the current response
    • Use the # shortcut to add a memory about the correct approach
    • Continue the conversation with the corrected information
  • Rewinding Conversations: Press Escape twice allows you to jump back to an earlier point and continue from there. This helps:
    • Maintain valuable context (like Claude’s understanding of your codebase)
    • Remove distracting or irrelevant conversation history
    • Keep Claude focused on the current task
  • /compact command: The /compact command summarizes your entire conversation history while preserving the key information Claude has learned. Use compact when Claude has learned a lot about the current task and you want to maintain that knowledge as it moves to the next related task. This is ideal when:
    • Claude has gained valuable knowledge about your project
    • You want to continue with related tasks
    • The conversation has become long but contains important context
  • /clear command: This command completely removes the conversation history, giving you a fresh start. This is most useful when:
    • You’re switching to a completely different, unrelated task
    • The current conversation context might confuse Claude for the new task
    • You want to start over without any previous context

These conversation control techniques are particularly valuable during:

  • Long-running conversations where context can become cluttered
  • Task transitions where previous context might be distracting
  • Situations where Claude repeatedly makes the same mistakes
  • Complex projects where you need to maintain focus on specific components

Planning vs Thinking

Planning mode: For more complex tasks that require extensive research across your codebase, you can enable Planning Mode. This feature makes Claude do thorough exploration of your project before implementing changes. This gives you the opportunity to review the plan and redirect Claude if it missed something important or didn’t consider a particular scenario.

Planning Mode is best for:

  • Tasks requiring broad understanding of your codebase
  • Multi-step implementations
  • Changes that affect multiple files or components

Thinking mode: Claude offers different levels of reasoning through “thinking” modes. These allow Claude to spend more time reasoning about complex problems before providing solutions.

  • “Think” - Basic reasoning
  • “Think more” - Extended reasoning
  • “Think a lot” - Comprehensive reasoning
  • “Think longer” - Extended time reasoning
  • “Ultrathink” - Maximum reasoning capability

Thinking Mode is best for:

  • Complex logic problems
  • Debugging difficult issues
  • Algorithmic challenges

Custom Commands

To create a custom command, you need to set up a specific folder structure in your project:

  • Find the .claude folder in your project directory
  • Create a new directory called commands inside it
  • Create a new markdown file with your desired command name (like audit.md)

The filename becomes your command name - so audit.md creates the /audit command.

Custom commands can accept arguments using the $ARGUMENTS placeholder. This makes them much more flexible and reusable.

For example, a write_tests.md command might contain:

Write comprehensive tests for: $ARGUMENTS Testing conventions: * Use Vitests with React Testing Library * Place test files in a __tests__ directory in the same folder as the source file * Name test files as [filename].test.ts(x) * Use @/ prefix for imports Coverage: * Test happy paths * Test edge cases * Test error states

You can then run this command with a file path:

/write_tests the use-auth.ts file in the hooks directory

The arguments don’t have to be file paths - they can be any string you want to pass to give Claude context and direction for the task.

Key Benefits:

  • Automation - Turn repetitive workflows into single commands
  • Consistency - Ensure the same steps are followed every time
  • Context - Provide Claude with specific instructions and conventions for your project
  • Flexibility - Arguments can be anything you want to pass to give Claude context and direction for the task

MCP Servers

You can extend Claude Code’s capabilities by adding MCP (Model Context Protocol) servers.

claude mcp add playwright npx @playwright/mcp@latest

Open the .claude/settings.local.json file, add allow permission for the MCP server (mcp__<server_name>):

{ "permissions": { "allow": ["mcp__playwright"], "deny": [] } }

Playwright is just one example of what’s possible with MCP servers. The ecosystem includes servers for:

Database interactions

  • API testing and monitoring
  • File system operations
  • Cloud service integrations
  • Development tool automation Consider exploring MCP servers that align with your specific development needs. They can transform Claude from a code assistant into a comprehensive development partner that can interact with your entire toolchain.

Github Integration

Claude Code offers an official GitHub integration that lets Claude run inside GitHub Actions.

To get started, run /install-github-app in Claude. This command walks you through the setup process.

The integration provides two main workflows:

  • Mention Action: You can mention Claude in any issue or pull request using @claude.
  • Pull Request Action: Whenever you create a pull request, Claude automatically
    • Reviews the proposed changes
    • Analyzes the impact of modifications
    • Posts a detailed report on the pull request

After merging the initial pull request, you can customize the workflow files to fit your project’s needs.

  • Add project setup
  • Add custom instructions
  • Add MCP servers
  • Configure tool permissions

Best Practice:

  • Start with the default workflows and customize gradually
  • Use custom instructions to provide project-specific context
  • Be explicit about tool permissions when using MCP servers
  • Test your workflows with simple tasks before complex ones
  • Consider your project’s specific needs when configuring additional steps

Hooks

Hooks allow you to run commands before or after Claude attempts to run a tool. They’re incredibly useful for implementing automated workflows like running code formatters after file edits, executing tests when files change, or blocking access to specific files.

There are two types of hooks:

  • PreToolUse hooks - Run before a tool is called
  • PostToolUse hooks - Run after a tool is called

Hooks are defined in Claude settings files. You can add them to:

  • Global - ~/.claude/settings.json (affects all projects)
  • Project - .claude/settings.json (shared with team)
  • Project (not committed) - .claude/settings.local.json (personal settings)

PreToolUse Hooks

PreToolUse hooks run before a tool is executed. They include a matcher that specifies which tool types to target:

{ "PreToolUse": [ { "matcher": "Read", "hooks": [ { "type": "command", "command": "node /home/hooks/read_hook.ts" } ] } ] }

Before the ‘Read’ tool is executed, this configuration runs the specified command. Your command receives details about the tool call Claude wants to make, and you can:

  • Allow the operation to proceed normally
  • Block the tool call and send an error message back to Claude

PostToolUse Hooks

PostToolUse hooks run after a tool has been executed. Here’s an example that triggers after write, edit, or multi-edit operations:

{ "PostToolUse": [ { "matcher": "Write|Edit|MultiEdit", "hooks": [ { "type": "command", "command": "node /home/hooks/edit_hook.ts" } ] } ] }

Since the tool call has already occurred, PostToolUse hooks can’t block the operation. However, they can:

  • Run follow-up operations (like formatting a file that was just edited)
  • Provide additional feedback to Claude about the tool use

Practical Applications

Here are some common ways to use hooks:

  • Code formatting - Automatically format files after Claude edits them
  • Testing - Run tests automatically when files are changed
  • Access control - Block Claude from reading or editing specific files
  • Code quality - Run linters or type checkers and provide feedback to Claude
  • Logging - Track what files Claude accesses or modifies
  • Validation - Check naming conventions or coding standards

The key insight is that hooks let you extend Claude Code’s capabilities by integrating your own tools and processes into the workflow. PreToolUse hooks give you control over what Claude can do, while PostToolUse hooks let you enhance what Claude has done.

Agent SDK vs Client SDK

Agent SDK

This is a high-level framework designed for building autonomous agents that can interact with their environment.

  • Runs Claude Code programmatically
  • Same Claude Code functionality as the terminal version
  • Inherits all settings from Claude Code instances in the same directory
  • Read-only permissions by default
  • Most useful as part of larger pipelines or tools
  • Only available for TypeScript and Python

Example:

import { query } from "@anthropic-ai/claude-code"; const prompt = "Look for duplicate queries in the ./src/queries dir"; for await (const message of query({ prompt, })) { console.log(JSON.stringify(message, null, 2)); }

Client SDK

Anthropic provides official client SDKs in multiple languages to make it easier to work with the Claude API. Each SDK provides idiomatic interfaces, type safety, and built-in support for features like streaming, retries, and error handling. Supports Python, TypeScript, Java, Go, C# etc.

Example:

package main import ( "context" "fmt" "github.com/anthropics/anthropic-sdk-go" "github.com/anthropics/anthropic-sdk-go/option" ) func main() { client := anthropic.NewClient( option.WithAPIKey("my-anthropic-api-key"), // defaults to os.LookupEnv("ANTHROPIC_API_KEY") ) message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{ MaxTokens: 1024, Messages: []anthropic.MessageParam{ anthropic.NewUserMessage(anthropic.NewTextBlock("What is a quaternion?")), }, Model: anthropic.ModelClaudeOpus4_6, }) if err != nil { panic(err.Error()) } fmt.Printf("%+v\n", message.Content) }
MIT 2026 © Daniel Guo.