strands-base-agent
AGENTS.md16 starsChanged 5 months agoApache-2.0View on GitHub
This file provides guidance for AI assistants and human contributors working with this codebase. A baseline starter repo from the Agent Foundry team, used to accelerate client delivery and team POCs. You forked or cloned it to build an agent for a specific use case in your own environment. This repo is the composition root — it wires foundry-agent-* packages into a runnable service. The shared infrastructure (DI, lifecycle, middleware, retry, OTel, tool loading) lives in those packages, not here.
- Reads credentials
- Installs packages
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,542 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository26 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- .cursor/rules/specify-rules.mdcCursor rule
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-continue-changeSkill
- openspec-exploreSkill
- openspec-ff-changeSkill
- openspec-new-changeSkill
- openspec-sync-specsSkill
- openspec-verify-changeSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-continue-changeSkill
- openspec-exploreSkill
- openspec-ff-changeSkill
- openspec-new-changeSkill
- openspec-sync-specsSkill
- openspec-verify-changeSkill
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-continue-changeSkill
- openspec-exploreSkill
- openspec-ff-changeSkill
- openspec-new-changeSkill
- openspec-sync-specsSkill
- openspec-verify-changeSkill
The file
We split this AGENTS.md into the rules it gives an agent
11 rules. About 0 are common, 3 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 39
Add tools in tools/
- Very specific: line 40
Add API routes in api/routes/
- Very specific: line 41
Add MCP servers in config.yaml
- Distinctive: line 89
When a change touches a STIG-relevant area (auth, authz, crypto, audit logging, session handling, data handling, input validation), update …
- Very specific: line 210
Create tool function with @tool decorator (from strands SDK)
- Very specific: line 211
Place in tools/ directory
- Very specific: line 215
Create router in api/routes/
- Very specific: line 221
Add MCP servers in config.yaml under mcp_servers
- Very specific: line 278
Use % interpolation in logging calls, never f-strings
- Distinctive: line 280
No mutable default arguments, no global mutable state, no staticmethod
- Distinctive: line 281
Prefer composition over inheritance
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md - Strands Base Agent (Starter Repo)
This file provides guidance for AI assistants and human contributors working with this codebase.
What this repo is
A baseline starter repo from the Agent Foundry team, used to accelerate
client delivery and team POCs. You forked or cloned it to build an agent
for a specific use case in your own environment. This repo is the
composition root — it wires foundry-agent-* packages into a runnable service. The shared infrastructure
(DI, lifecycle, middleware, retry, OTel, tool loading) lives in those
packages, not here.
What this repo provides directly:
- A composition root that wires the packages together (
server.py) - HTTP API routes for query processing and chat history
- A2A protocol server for multi-agent communication
- A
config.yamlfor YAML-first configuration - A
tools/directory for domain-specific tools
First 90 seconds after forking
just setup— installs dependencies and pre-commit hooks- Edit
config.yaml— setmodel,agent_name,system_prompt cp env.template .env— set AWS Bedrock credentialsjust demo "Tell me about Python"— verify the agent runs
Two ways to extend this baseline
You can use either or both. Adopters choose based on team practice.
Path A — Direct extension (default)
Open your coding agent, describe what you want, let it modify code. Best for small or exploratory changes.
- Add tools in
tools/ - Add API routes in
api/routes/ - Add MCP servers in
config.yaml - Customize session managers / model providers in
server.py
Path B — Spec-driven via OpenSpec (opt-in)
For larger changes where you want a written proposal before code lands.
openspec/specs/documents the baseline capabilities this repo ships with — read these to understand what already exists before proposing changes. They are useful even if you never write a new spec yourself.openspec/changes/is where new proposals live. TheopenspecCLI (or matching slash commands in your coding agent) drives the workflow.- See
openspec/config.yamlfor project orientation passed to coding agents.
Security posture & STIG tracking
This repo ships with a baseline assessment against the DISA Application Security and Development (ASD) STIG. The intent is to give adopters pursuing ATO-style requirements a head start: the controls inherited from the baseline are pre-recorded, and what remains is whatever the adopter adds on top of it.
security/stig_checklist.json— machine-readable checklist of every STIG finding, withstatus,responsibility(baseline vs. adopter),finding_details, and longer-formcommentsper control. This is the single file to update as the baseline (or your fork) evolves — evidence lives inside it, not alongside it.security/README.md— orientation for the directory, including how to refresh the checklist and what to put infinding_detailsvs.comments.
Treat the checklist as a recommended template, not a hard requirement. Adopters in regulated environments should keep it current alongside code changes. Adopters with no compliance obligation can tailor or remove it.
Keeping it current. Two patterns work; pick whichever matches your team's level of AI adoption:
- Skill-driven (what the Foundry team uses internally): coding agents
drive the assessment via
foundry-stigkit-backed skills. These are tooling not included in this repo, but the pattern (run a domain assessment, triage findings, update the JSON) is reproducible with any coding agent and the JSON schema in the file. - Manual / traditional: edit
security/stig_checklist.jsondirectly when a code change affects a control. Use theresponsibilityfield to mark whether the control is satisfied by the baseline or by an adopter overlay.
When a change touches a STIG-relevant area (auth, authz, crypto, audit logging, session handling, data handling, input validation), update the checklist in the same PR.
Architecture Overview
┌──────────────────────────────────────────────────────┐
│ Starter Repo (this repo) │
├──────────────────────────────────────────────────────┤
│ server.py - Composition root, A2A server │
│ application/ - DI container setup, lifecycle │
│ api/routes/ - Query, streaming, chat history│
│ api/dependencies.py - FastAPI DI bridge │
│ config.yaml - Default configuration │
│ tools/ - Domain-specific tools │
└──────────────────────────────────────────────────────┘
│ pip install
▼
┌──────────────────────────────────────────────────────┐
│ foundry-agent-* Packages │
├──────────────────────────────────────────────────────┤
│ foundry-agent-core - DI, protocols, types, │
│ exceptions, lifecycle │
│ foundry-agent-config - YAML loader + env overrides │
│ foundry-agent-fastapi- Middleware, models, mappers, │
│ health router │
│ foundry-strands-agent- StrandsAgentBackend, factory, │
│ orchestrator, tool_loader, │
│ chat historian, config models │
└──────────────────────────────────────────────────────┘File Structure
strands_base_agent/
├── __init__.py # Package root
├── __main__.py # CLI entry point
├── main.py # process_query() function
├── server.py # Composition root + A2A server
├── application/
│ ├── factory.py # DI container setup
│ ├── lifecycle.py # Startup/shutdown
│ └── runtime_container.py # Process-wide container singleton
├── api/
│ ├── dependencies.py # FastAPI DI bridge
│ └── routes/
│ ├── query.py # Query + streaming endpoints
│ └── chat_history.py # Chat history endpoints
└── tools/
└── __init__.py # Custom tools go hereKey Files
| File | Purpose |
server.py | Composition root. Registers AgentFactory and AgentBackend in the DI container. Adopters customize session managers and model providers here. |
application/factory.py | Creates the DI container and registers infrastructure services. Loads config from config.yaml with env var fallback. |
application/lifecycle.py | Startup/shutdown lifecycle. Signal handlers, logging init. |
api/dependencies.py | FastAPI dependency injection bridge. Resolves AgentBackend, AgentService, ChatHistoryManager from the container. |
api/routes/query.py | POST /api/v1/query (sync via AgentBackend) and POST /api/v1/query/stream (SSE via AgentService). |
api/routes/chat_history.py | CRUD endpoints for chat session history. Injects ChatHistoryManager directly. |
config.yaml | Default YAML configuration. Env vars override using double-underscore nesting (STRANDS__MODEL__PROVIDER). |
main.py | Interface-agnostic process_query() for CLI, Lambda, scripts. |
Packages
Pinned versions live in pyproject.toml; this table only describes what each
package provides. See the README install note
for the GitHub-Release vs. internal-index install paths.
| Package | What It Provides |
foundry-agent-core | AgentBackend protocol, AgentRequest/AgentResponse/TokenUsage types, DependencyContainer, exception hierarchy, lifecycle/retry |
foundry-agent-config | load_config() function. YAML primary, env var overrides with type coercion. |
foundry-agent-fastapi | CORS/error/logging middleware, QueryAPIRequest/QueryAPIResponse models, health router, mappers |
foundry-strands-agent | StrandsAgentBackend, StrandsAgentFactory, QueryOrchestrator, ChatHistorian, AgentService, tool loader, config models |
Configuration
YAML is the primary config source. Environment variables override YAML values.
# config.yaml
model:
provider: bedrock
model_id: us.anthropic.claude-haiku-4-5-20251001-v1:0
temperature: 0.3
streaming: true
agent_name: strands-base-agent
system_prompt: "You are a helpful AI assistant..."Env var overrides use double-underscore nesting:
| YAML path | Env var |
model.provider | STRANDS__MODEL__PROVIDER |
model.model_id | STRANDS__MODEL__MODEL_ID |
agent_name | STRANDS__AGENT_NAME |
See docs/foundry/configuration/index.md for the full guide including the composed config pattern for domain-specific fields.
Development Commands
just setup # Install deps + pre-commit hooks
just run # Start A2A server on :8000
just demo # Run CLI with test query
just test # All tests
just lint # Ruff linting
just dead-code # Advisory vulture scan (not part of check/ci)
just check # All quality checks (lint, format, type-check, test)Common Tasks
Add a New Tool
- Create tool function with
@tooldecorator (from strands SDK) - Place in
tools/directory - Set
STRANDS__TOOLS_MODULESorSTRANDS__TOOLS_FILESin config
Add API Endpoint
- Create router in
api/routes/ - Add to
api/routes/__init__.py - Register in
server.py
Customize Agent Behavior
- Edit
config.yamlfor model, system prompt, tools - Add MCP servers in
config.yamlundermcp_servers - Register custom session manager factories in
server.py
Extend Configuration (Domain-Specific)
See docs/foundry/configuration/index.md for the composed config pattern. Wrap StrandsAgentConfig in a custom Pydantic model with your domain fields.
Extension Points
Adopters customize by editing server.py (the composition root):
# Custom session manager
container.register_factory(
AgentFactory,
lambda: StrandsAgentFactory(
container,
session_manager_factories={
"file": _default_file_session_manager,
"s3": _default_s3_session_manager,
"dynamodb": my_dynamodb_factory,
},
),
singleton=True,
)The AgentBackend protocol enables future framework adapters (LangChain, CrewAI) without changing the starter repo's API layer.
Testing
- Unit tests in
tests/unit/test starter repo code (routes, factory, dependencies) - Integration tests in
tests/integration/test tool loading and startup - Package tests live in the
foundry-agent-packagesmonorepo
just test # Run all tests
just test-unit # Unit tests only
just test-integration # Integration tests onlyCommit Guidelines
- One logical change per commit
- Each commit should compile and pass tests
- Small, incremental, reviewable diffs
<type>: <short description>
<optional body explaining why, not what>Types: feat, fix, refactor, test, docs, chore
Python Style
- Modern PEP 585 syntax:
list[int],dict[str, Any],X | Y | None - Use
%interpolation in logging calls, never f-strings - Pydantic v2:
@field_validator,model_config = {"frozen": True} - No mutable default arguments, no global mutable state, no staticmethod
- Prefer composition over inheritance
Things to leave alone
These responsibilities live upstream in foundry-agent-* packages. If you
find yourself reaching to re-implement them in this repo, that's a signal the
work belongs in a package PR instead.
tool_loader.py— lives infoundry-strands-agent, security-critical; never re-implement in this repo- OTel instrumentation, retry logic, and shutdown handlers — provided by the packages; do not duplicate
- DI container, protocol definitions, lifecycle hooks —
foundry-agent-coreowns these - Python 3.14 is required (any 3.14.x — see
pyproject.toml)
Documentation
env.template— environment variable referenceCONTRIBUTING.md— development process, commit/PR conventionssecurity/README.md— STIG checklist and security posture- See
docs/foundry/for deeper guides (configuration, MCP setup, tool authoring, server customization). This is the same content published to the Agent Foundry docs site.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

