Project Configuration with Source Files

Introduction: Beyond Runtime Prompts

In the previous lesson, you learned how to use hooks to intercept and control your agent's behavior at runtime. But there's another dimension to building production-ready agents: giving them persistent knowledge about your project, domain, and conventions. Instead of repeating the same instructions in every prompt, you can store them in configuration files that the SDK can automatically load. In this lesson, you'll build a Travel Planner agent that gets its entire personality and guidelines from a CLAUDE.md file, making your agents smarter and more consistent across your entire team.

Understanding Project Configuration Files

Before we dive into how to load configuration, let's understand what files the SDK can work with and where they live. The Claude Agent SDK supports a filesystem-based configuration system with three types of files:

CLAUDE.md: This is a Markdown file that lives in your project root directory. It contains natural language instructions that define your agent's personality, domain knowledge, and approach to problems. Think of it as your agent's training manual.

your-project/
├── CLAUDE.md              # Main instructions (project root)
├── main.py
└── requirements.txt

.claude/ Directory: For more structured configuration, you can create a .claude/ folder in your project root. This directory can contain JSON files with additional settings like tool configurations, environment variables, or custom prompts.

your-project/
├── .claude/
│   ├── settings.json       # Team-shared settings
│   └── settings.local.json # Developer-specific overrides (gitignored)
├── CLAUDE.md
├── main.py
└── requirements.txt

User Settings: The SDK also supports user-level configuration stored in ~/.claude/settings.json in your home directory. These are personal preferences that apply to all your projects.

The key insight is that these files exist at different scopes:

  • User files (~/.claude/) apply to all your projects
  • Project files (CLAUDE.md, .claude/settings.json) apply to everyone on your team
  • Local files (.claude/settings.local.json) apply only to you in this project

By default, the SDK ignores all these files unless you explicitly tell it which ones to load. Let's start with the most powerful one: CLAUDE.md.

CLAUDE.md: Your Project's Memory

The most important file in your project configuration is CLAUDE.md. This is a Markdown file that acts as persistent memory for Claude, providing project-specific instructions that the agent automatically follows without you having to include them in every prompt.

What makes CLAUDE.md special is that it becomes part of Claude's system prompt automatically. Everything you write in this file is loaded before the agent processes any user queries, giving Claude context about your project, domain, and expectations. The content typically includes your agent's role and purpose, guidelines for how it should approach tasks, formatting preferences for outputs, domain-specific terminology, and project conventions.

The real power of CLAUDE.md comes from its shareability. When you commit this file to your repository, everyone on your team gets the same agent behavior without needing to pass around prompt templates or remember special instructions. A new developer can clone your project, run the agent, and immediately get the same thoughtful, domain-aware responses that you get. The same applies to open-source projects — users can download your agent and instantly have access to all the knowledge and conventions you've encoded in CLAUDE.md.

Unlike hooks, which control what the agent can do, CLAUDE.md shapes what the agent knows and how it thinks about problems. Let's see what a real CLAUDE.md file looks like by building one for our Travel Planner agent.

Creating the CLAUDE.md File

In this lesson we will build a Travel Planner agent by creating the CLAUDE.md file that contains all the instructions defining how our agent should help users plan trips. Create a file named CLAUDE.md in your project root with the following content:

# Travel Planner Agent

You help users plan trips by researching destinations, finding activities, and creating itineraries.

## Your Approach

- Work with the information provided—make reasonable assumptions if details are missing
- Research essential facts: safety, weather, local events, visa requirements
- Balance tourist highlights with local experiences
- Be concise and actionable

## Itinerary Format

When creating itineraries, organize by day:
- Morning, afternoon, evening activities
- Include travel time between locations
- Note reservation requirements

## Budget Categories

- Budget: hostels, street food, public transport
- Mid-range: 3-star hotels, casual restaurants, mix of transport
- Luxury: 4–5 star hotels, fine dining, private transfers

## Research Priority

1. Safety advisories for the destination
2. Best time to visit
3. Must-see attractions
4. Local customs and etiquette
5. Transportation options

## Files

Save itineraries to `./trips/{destination}-itinerary.md`

This CLAUDE.md file defines our agent's entire personality and approach. The first section establishes the agent's role as a travel planning assistant. The "Your Approach" section tells Claude to work with whatever information is provided and make reasonable assumptions rather than requesting more details upfront. This creates a more action-oriented agent that focuses on being concise and delivering results quickly. The "Itinerary Format" section specifies how to structure trip plans, while "Budget Categories" defines what each budget level means in concrete terms. The "Research Priority" section tells Claude what information to gather first, and the "Files" section specifies where to save completed itineraries.

Notice that we're writing in natural language with clear, specific instructions rather than vague guidance. This makes the file easy for humans to read and maintain, while still giving Claude precise directions. Now that we have our CLAUDE.md file ready, let's learn how to tell the SDK to load it.

The setting_sources Parameter

Now that we've created our CLAUDE.md file, we need to tell the SDK to load it. The setting_sources parameter in ClaudeAgentOptions is what controls which configuration files get loaded from your filesystem. This is an opt-in feature, meaning that by default, the SDK doesn't load any configuration files unless you explicitly tell it to.

from claude_agent_sdk import ClaudeAgentOptions

options = ClaudeAgentOptions(
    setting_sources=["project"]  # Load project-level settings
)

The setting_sources parameter accepts a list of strings, and the SDK supports three types of configuration sources:

  • "user": Loads settings from ~/.claude/settings.json in your home directory for personal preferences.
  • "project": Loads settings from .claude/settings.json and CLAUDE.md files relative to your working directory for team-shared conventions.
  • "local": Loads settings from .claude/settings.local.json for developer-specific overrides that are typically gitignored.

You can specify multiple sources in the list, and they'll be loaded in order, with later sources overriding earlier ones. For this lesson, we'll focus on the "project" source because it's the most commonly used for building team-friendly agents. When you specify setting_sources=["project"], the SDK will look for our CLAUDE.md file and load its contents into Claude's system prompt automatically.

The cwd Parameter Connection

When you use setting_sources=["project"] or setting_sources=["local"], the SDK needs to know where to look for your configuration files. This is where the cwd (current working directory) parameter comes in. The cwd parameter tells the SDK which directory contains your CLAUDE.md file and .claude/ folder.

from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions

# RECOMMENDED: Set the project root directory explicitly
project_root = Path(__file__).parent.absolute()

options = ClaudeAgentOptions(
    setting_sources=["project"],
    # This tells the SDK where to find the project directory
    cwd=project_root
)

Here's the important part: the cwd parameter has a default value. If you don't set it explicitly, it defaults to the directory from which you launched your Python script. Using Path(__file__).parent.absolute() gives you the directory containing your Python script, which is usually your project root. This approach works reliably regardless of where you run the script from. Without an explicit cwd, the SDK might look in unexpected locations depending on where you launched your script.

There's one exception: if you're only using setting_sources=["user"], you don't need to set cwd at all because user settings always live in ~/.claude/settings.json in your home directory. For our Travel Planner agent, we'll use the recommended pattern with an explicit cwd.

Building the Python Code

Now let's create the Python code that loads our CLAUDE.md configuration and uses it to help plan a trip. We'll configure the agent to automatically load project-level settings and enable the tools needed for travel research.

import anyio
from pathlib import Path
from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
)
from utils import display_response


async def main():
    # Set the project root directory explicitly
    project_root = Path(__file__).parent.absolute()

    # Configure the agent to load project-level settings from CLAUDE.md
    options = ClaudeAgentOptions(
        model="haiku",
        max_turns=10,
        setting_sources=["project"],
        cwd=project_root,
        allowed_tools=["WebSearch", "WebFetch", "Write", "Read"]
    )

    async with ClaudeSDKClient(options=options) as client:
        # The agent will automatically follow the Travel Planner instructions in CLAUDE.md
        await client.query(
            "I want to plan a 5-day trip to Tokyo. "
            "My budget is mid-range and I'm interested in food, history, and anime culture. "
            "I'm traveling in April."
        )

        await display_response(client)


if __name__ == "__main__":
    anyio.run(main)

The key lines here are setting_sources=["project"], which tells the SDK to load our CLAUDE.md file, and cwd=project_root, which tells it exactly where to find that file. We set project_root at the beginning of our function using Path(__file__).parent.absolute() to ensure the SDK always looks in the correct directory, regardless of where we run the script from. Notice that our user query provides specific details about the trip (destination, budget, interests, timing), but doesn't include any instructions about how to plan the trip or what format to use — we're just stating what we want. All the guidance about how to approach this task comes from CLAUDE.md, which the SDK loaded automatically. Let's see what happens when we run this code.

Observing the Agent Taking Action

When we run this code, Claude immediately demonstrates that it has absorbed the instructions from CLAUDE.md. Instead of asking clarifying questions, the agent takes action right away by conducting research, exactly as instructed in the "Your Approach" section that says "Work with the information provided—make reasonable assumptions if details are missing."

💬 Claude Response:
I'll help you plan a fantastic 5-day trip to Tokyo! Let me research the essential information first, then create a detailed itinerary tailored to your interests.

🔧 [Tool: WebSearch]

🔧 [Tool: WebSearch]

🔧 [Tool: WebSearch]

🔧 [Tool: WebSearch]

🔧 [Tool: WebSearch]

Look at how Claude is following the instructions from CLAUDE.md without us having to include them in the prompt. The agent immediately launches into research mode, conducting multiple web searches to gather information about Tokyo. Claude doesn't ask for more details about accommodation preferences or group size — it works with the information provided (destination, budget, interests, timing) and will make reasonable assumptions where needed. This demonstrates the "be concise and actionable" directive from our configuration. After completing its research, Claude moves directly to creating the itinerary.

Analyzing the Complete Response

After conducting its research and creating the itinerary file, Claude presents a comprehensive summary that's both structured and actionable. The agent has followed all the guidelines from CLAUDE.md, including the research priorities and file-saving conventions.

💬 Claude Response:
Perfect! I have all the information I need. Now let me create a comprehensive 5-day itinerary tailored to your interests. I'll save this to a file for you.

🔧 [Tool: Write]

💬 Claude Response:
Perfect! I've created a comprehensive 5-day Tokyo itinerary tailored specifically to your interests. Here's what I've planned:

## 📋 Itinerary Highlights

**Day 1:** Classic Tokyo intro with Meiji Jingu Shrine and Harajuku anime shops
**Day 2:** Asakusa's historic Sensoji Temple (1,400+ years old) and Ueno Park
**Day 3:** Anime deep dive—Akihabara's otaku paradise + Ghibli Museum (book tickets ahead!)
**Day 4:** Food culture focus—Tsukiji Market sushi, historic temples, quality dining
**Day 5:** Flexible day for last-minute explorations and favorite neighborhood revisits

## 🌸 April Timing Benefits
- **Cherry blossoms** likely still visible early April
- **Mild weather** (17-22°C) perfect for walking
- **Low crime**—Tokyo is one of the world's safest cities

## 💰 Budget Breakdown (Mid-Range)
- **Total: ~¥95,000-120,000 (~$650-820 USD)** for 5 days including:
  - Comfortable 3-star hotels (~¥10,000/night)
  - Local restaurants and some higher-end dining
  - All major attractions and museum entries
  - Train transport via IC card

## 🎌 Key Reservations
- **Book Ghibli Museum tickets in advance** (timed entries, sells out quickly)
- Popular restaurants may need advance bookings

The itinerary balances iconic attractions with local experiences—yokocho alleyways, temple visits, anime culture, and food exploration. I've saved it to `./trips/tokyo-itinerary.md` for your reference!

Would you like me to adjust anything—add more specific restaurant recommendations, swap activities, or provide tips for any particular interest?

Claude used the Write tool to save the itinerary to ./trips/tokyo-itinerary.md, following the "Files" section of our configuration. The response is concise and actionable, organized with clear headers and emoji for visual scanning. The agent researched and presented information following the "Research Priority" list: safety ("Low crime—Tokyo is one of the world's safest cities"), best time to visit ("April Timing Benefits"), must-see attractions (day-by-day highlights), and practical details like transportation and reservations. The budget breakdown reflects the mid-range category from CLAUDE.md with specific cost estimates for 3-star hotels and restaurant options.

Most importantly, notice what we didn't have to include in our prompt — we didn't say "research safety" or "check the weather" or "save the itinerary to a file." All of that behavior came from CLAUDE.md, which means every time anyone on your team uses this agent, they'll get the same action-oriented, research-driven approach to trip planning with consistent output formatting.

Summary: Configuration as Code

You've now learned how to use setting_sources and CLAUDE.md to give your agents persistent knowledge and consistent behavior. The key concepts are that setting_sources is an opt-in parameter, with "project" being the most common choice, CLAUDE.md contains natural language instructions that become part of Claude's system prompt automatically, and you should always set cwd explicitly when using project settings. In the upcoming practice exercises, you'll create your own CLAUDE.md files for different domains and learn how to structure project settings for maximum reusability.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal