Skip to content
Agentmart
Submit a tool

AGENTS.md · agno-agi/scout

AGENTS.md from agno-agi/scout: 249 lines covering Project Overview, Architecture, ContextProvider, One write surface and more.

Template by agno-agi

IndexedApache-2.0★ 751
Write a review

Install

Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/agno-agi/scout/main/AGENTS.md -o AGENTS.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The AGENTS.md file that agno-agi/scout (751 stars) keeps for coding agents. It has 249 lines in 15 sections: Project Overview; Architecture; ContextProvider; One write surface; Interfaces; Structure; Commands; Testing & Evals; Contexts; User Data Tables; Tools on Scout; API Endpoints; Model; Environment Variables; Conventions. Use it as a model for your own project's instructions.

Use cases: knowledge-base, code-generation

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.

For
Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
Length
249 lines
File
AGENTS.md

Sections

  1. Project Overview
  2. Architecture
  3. ContextProvider
  4. One write surface
  5. Interfaces
  6. Structure
  7. Commands
  8. Testing & Evals
  9. Contexts
  10. User Data Tables
  11. Tools on Scout
  12. API Endpoints
  13. Model
  14. Environment Variables
  15. Conventions

First lines (shown under the repo's Apache-2.0 license)

# AGENTS.md

## Project Overview

Scout is an **enterprise context agent** — a single `agno.Agent` with N `ContextProvider`s. Ships with `WebContextProvider`, `WorkspaceContextProvider` (local files via `agno.tools.Workspace`), `DatabaseContextProvider` (the CRM — user's contacts/projects/notes/follow-ups), two `WikiContextProvider`s (a writable `knowledge` wiki and a read-only `voice` wiki), `SlackContextProvider`, `GDriveContextProvider`, and `MCPContextProvider` (any MCP server → one `query_mcp_<slug>` tool on Scout). GitHub, Gmail, and Calendar land in the next release (were built and verified on the `feat/slack-interface` branch; dropped from the ship slice until we can test end-to-end with real tokens).

## Architecture

```
Scout (single Agent — one LLM hop per turn)
  tools = <query_|update_ tools from every registered ContextProvider> + list_contexts
```

Every source is a `ContextProvider`. The database is a provider too: `DatabaseContextProvider` exposes `query_crm` (reads) + `update_crm` (writes), each backed by a dedicated sub-agent so the read path never sees the write engine.

## ContextProvider

`agno.context.provider` defines the base. Every external source subclasses `ContextProvider` and implements:

- `query(question) -> Answer` / `aquery(question) -> Answer` — natural-language read
- `status() -> Status` / `astatus() -> Status` — is the source reachable?

Providers that support writes override `aupdate(instruction) -> Answer` (and optionally `update`). The base raises `NotImplementedError`; `_update_tool()` translates that into a readable "<name> is read-only" error so calling agents see a clean failure. Today only `DatabaseContextProvider` overrides it.

`mode` controls how the provider surfaces itself to the calling agent:

| Mode | Exposure |
|---|---|
| `default` | The provider's recommended exposure. Each subclass decides. |
| `agent` | One `query_<id>` tool wrapping a sub-agent. |
| `tools` | The underlying tools directly. |

`model` swaps the model used by the internal sub-agent (when one is built). `instructions()` returns mode-aware usage guidance for the calling agent.

The full type set:
- `Status(ok: bool, detail: str = "")`
- `Document(id, name, uri=None, source=None, snippet=None)` — a piece of content
- `Answer(results: list[Document] = [], text: str | None = None)` — what `query()` returns

## One write surface

| Write surface | Owner | Call |
|---|---|---|
| `scout_*` user-data tables | `DatabaseContextProvider` write sub-agent | `update_crm(instruction)` — SQL DDL + DML, scoped to the `scout` schema (`get_sql_engine()`) |

Everything else reads. The CRM read sub-agent uses `get_readonly_engine()` (PostgreSQL's `default_transaction_read_only`). The scout engine has a `before_cursor_execute` hook that rejects any DDL/DML targeting `public` or `ai` — so even if Scout is tricked into calling `update_crm` with an out-of-schema statement, the engine rejects it.

## Interfaces

Chat surfaces beyond AgentOS's built-in UI. Wired in `app/main.py` and passed to `AgentOS(interfaces=...)`.

| Interface | Trigger | Notes |
|---|---|---|
| Slack | `SLACK_BOT_TOKEN` **and** `SLACK_SIGNING_SECRET` set | Webhook at `/slack/events`; each Slack thread → a persistent session. `resolve_user_identity=True` maps Slack user IDs to names. Setup: [`docs/SLACK_CONNECT.md`](docs/SLACK_CONNECT.md). |

Both Slack env vars must be set for the interface to light up; otherwise `interfaces=[]` and Scout runs headless + on AgentOS. We explicitly pass `token=SLACK_BOT_TOKEN` because agno's default env-var read is `SLACK_TOKEN` — keeping the `_BOT_` name is intentional.

## Structure

```
scout/
├── __init__.py
├── __main__.py                     # CLI: chat | contexts
├── agent.py                        # The single `scout` Agent
├── instructions.py                 # Scout-tuned prompts: SCOUT_INSTRUCTIONS + CRM read/write
├── settings.py                     # Runtime objects: agent_db + default_model() factory
└── contexts.py                     # create/get/update/close_context_providers + list_contexts tool + status row helpers

# The ContextProvider library (base ABC + shipped providers) lives in `agno.context`
# as of agno 2.6 — see `agno.context.{database,gdrive,mcp,slack,web,wiki,workspace}`.

app/
├── main.py                         # AgentOS entry (lifespan wires contexts; Slack interface if env set)
├── router.py                       # /contexts/* endpoints
└── config.yaml

db/
├── session.py                      # get_sql_engine (guarded) / get_readonly_engine / get_postgres_db / create_knowledge
├── url.py                          # DB URL builder
└── tables.py                       # Canonical DDL: scout_contacts / projects / notes / followups

wiki/
├── knowledge/                      # Prose memory Scout files into (gitignored except README)
└── voice/                          # Code-managed style guide (committed, read-only to Scout)

evals/
├── cases.py                        # Behavioral Case dataclass + CASES tuple
├── runner.py                       # In-process transport + fixtures
├── wiring.py                       # Code-level invariants, no LLM (W1-W6)
├── judges.py                       # LLM-scored quality tier
└── __main__.py                     # CLI dispatch
```

## Commands

```bash
./scripts/venv_setup.sh && source .venv/bin/activate
./scripts/format.sh                   # Format code
./scripts/validate.sh                 # ruff + mypy

# CLI
python -m scout                       # Chat
python -m scout contexts              # List contexts + status

# Tables (also run automatically on app startup)
python -m db.tables

# Evals
python -m evals wiring                # Code-level invariants (no LLM)
python -m evals                       # Behavioral cases, in-process
python -m evals --case <id>           # Single case
python -m evals --verbose             # Response + tool previews
python -m evals judges                # LLM-scored quality tier
```

### Environment loading for CLI work

Secrets live in `.env`. Anything that hits OpenAI / Parallel from the host (`python -m evals`, etc.) needs `.env` loaded:

1. **Prefer direnv:** `direnv allow .` once per repo.
2. **Fallback:** `set -a; source .env; set +a; python -m evals`
3. **Per-invocation (Bash tool):** `set -a && source .env && set +a && ...`

Docker picks up `.env` automatically via `docker compose`, so code inside `scout-api` has everything. Only direct host-shell invocations need the explicit source.

## Testing & Evals

**Static checks** — `./scripts/validate.sh` runs ruff + mypy. Both run even if one fails; the script exits non-zero if either reports problems, warns if no virtualenv is active.

**Three eval tiers** under `python -m evals`:

| Tier | Command | Speed | LLM? | What it catches |
|---|---|---|---|---|
| Wiring | `python -m evals wiring` | <1s | No | Scout's tool shape drifts (bare SQL on Scout, CRM provider loses `update_crm`, schema guard removed, default `user_id` sentinel regresses, GDrive backend drops shared-drive coverage, MCP lifecycle breaks, voice gains a write tool, `scout_followups` falls out of canonical DDL) |
| Behavioral | `python -m evals` | ~3min | Yes (gpt-5.6-sol) | Scout picks the wrong tool, over-tools, responses miss expected substrings |
| Judges | `python -m evals judges` | ~1min/case | Yes | Answer quality a regex can't express |

Flags: `--case <id>` narrows to one case; `--verbose` prints response + tool previews. Details: [`docs/EVALS.md`](docs/EVALS.md).

**Fixing a failing case** — paste [`docs/EVAL_AND_IMPROVE.md`](docs/EVAL_AND_IMPROVE.md) into a fresh agent session. It runs the suite, diagnoses each failure (agent bug vs. stale assertion vs. runner bug), fixes what's in scope, and flags what isn't.

## Contexts

`scout/contexts.py::create_context_providers()` is the env-driven factory. The app lifespan calls it at startup to warm a module-level cache; `get_context_providers()` lazy-builds on first access. `update_context_providers()` swaps the cached list in place (used by eval fixtures). The web provider is always on; others opt-in via env.

Registered provider set (in order):

| Provider | Trigger | Notes |
|---|---|---|
| `WebContextProvider` | always | Backend picked below |
| `WorkspaceContextProvider` | always | Read-only; `Workspace` scoped to `SCOUT_FS_ROOT` in `scout/contexts.py` (the scout repo — Scout answers questions about itself). One `query_workspace` tool that routes through a tuned sub-agent. |
| `DatabaseContextProvider` | always | CRM — the user's contacts/projects/notes/follow-ups. Exposes `query_crm` + `update_crm`; read path uses `get_readonly_engine()`, write path uses `get_sql_engine()` (scout-schema-guarded). |
| `WikiContextProvider` (knowledge) | always | Prose memory — runbooks, design notes, learnings. `FileSystemBackend` on `wiki/knowledge/` by default; swap to `GitBackend` for durability + audit trail (see [`docs/WIKI_GIT.md`](docs/WIKI_GIT.md)). Tools: `query_knowledge` + `update_knowledge`. |
| `WikiContextProvider` (voice) | always | Read-only (`write=False`) style guide for external content. Filesystem-backed on `wiki/voice/`; rules are code-managed (PR, not agent edits). Tool: `query_voice` only — no `update_voice`. |
| `SlackContextProvider` | `SLACK_BOT_TOKEN` | Read-only; search + channel history + threads. Sending is disabled (Slack interface handles posting). Setup: [`docs/SLACK_CONNECT.md`](docs/SLACK_CONNECT.md) |
| `GDriveContextProvider` | `GOOGLE_SERVICE_ACCOUNT_FILE` | Read-only; Scout authenticates as its own service account (no user impersonation). Setup: [`docs/GDRIVE_CONNECT.md`](docs/GDRIVE_CONNECT.md) or `./scripts/google_setup.sh` |
| `MCPContextProvider` | wired in `scout/contexts.py` | One per server; transports `stdio`/`sse`/`streamable-http`. Sub-agent instructions rebuilt from `list_tools()` at connect. `aclose()` closes the session on shutdown. Setup: [`docs/MCP_CONNECT.md`](docs/MCP_CONNECT.md) |

`create_context_providers()` dedupes by `id` globally (first wins, warns on collision) so Scout never ends up with two `query_<id>` tools sharing a name.

Signals

Stars
751
Forks
74
Open issues
1
Last commit (this folder)
Jul 10, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from agno-agi

Cite this page

AGENTS.md · agno-agi/scout. Agent Mart. https://agentmart.dev/templates/agno-agi-scout-agents-md (last updated 2026-10-24)