# CLI Source: https://agentharnesses.io/cli Install and use the agentharnesses CLI to scaffold and manage harnesses. # CLI The `ahar` CLI scaffolds and manages Agent Harnesses. ## Installation ```bash theme={null} pip install agentharnesses-cli ``` ## Commands ### `ahar init` Scaffold a new harness in the current directory: ```bash theme={null} ahar init ``` Optionally specify a name (defaults to the directory name): ```bash theme={null} ahar init my-harness ``` This creates: ``` my-harness/ ├── HARNESS.md # entry point and agent identity ├── README.md # human-facing description ├── .gitignore ├── .claude/settings.json # registers the harness as a Claude Code plugin ├── skills/ │ └── SKILLS.md # skill index └── references/ └── REFERENCES.md # reference index ``` When using the `claude` preset (default), `ahar init` also installs: ``` ├── .claude/skills/agent-harnesses/ # metaskill for progressive harness exploration └── skills/ └── maintenance/ ├── SKILLS.md └── modify-harness/ └── SKILL.md ``` The metaskill is cloned fresh from [agentharnesses/metaskill](https://github.com/agentharnesses/metaskill) at init time. ### `ahar validate` Validate a harness directory structure: ```bash theme={null} ahar validate ./my-harness ``` ### `ahar read` Read a property from a harness's `HARNESS.md` frontmatter: ```bash theme={null} ahar read ./my-harness name ahar read ./my-harness description ``` ### `ahar prompt` Render a harness as prompt XML for agent injection: ```bash theme={null} ahar prompt ./my-harness ``` These commands are backed by [harnesses-ref](https://pypi.org/project/harnesses-ref/), the reference implementation for the Agent Harnesses standard. # Adding Harness Support Source: https://agentharnesses.io/client-implementation/adding-harnesses-support How to implement the Agent Harnesses standard in your AI client or tool. # Adding Harness Support This guide is for developers building AI clients, IDEs, agent frameworks, or other tools who want to support the Agent Harnesses standard. ## What clients must implement A compliant client must support the four-phase loading model: 1. **Load** — at session start, inject the full `HARNESS.md` body into the agent's context 2. **Discovery** — expose tools so the agent can read routing files and content descriptions to find what is relevant to a task 3. **Activation** — expose tools so the agent can read the full content of a skill, document, or routing file when it matches the task 4. **Execution** — expose tools so the agent can run scripts bundled within skills Clients may implement additional features (caching, search, UI affordances) but these four behaviors are the baseline. *** ## Loading model in detail ### Load At session start, read `HARNESS.md` frontmatter to get `name` and `description`, then inject the full body into the agent's context: ```python theme={null} harness = parse_frontmatter_and_body("HARNESS.md") present_to_user(harness.name, harness.description) inject_into_context(harness.body) ``` `HARNESS.md` is the agent's map of the harness — it establishes the agent's role and tells it what top-level directories are available. ### Discovery When a task arrives, the agent reads routing files to decide which directories are relevant. Expose a tool so the agent can request content on demand rather than having the client inject everything upfront. ### Activation When the agent determines a directory or file is relevant, your client reads the requested content and returns it. A single path-based tool handles the full directory hierarchy: ``` load_content(path: str) -> str If path points to a grouping directory, returns its routing file. If path points to a leaf directory, returns its primary file (per .leaf-detectors) and lists available scripts. If path points to a file, returns the full file content. ``` Using a single path-based interface keeps the API uniform across flat and deeply nested harnesses and handles arbitrary directory structures without client changes. *** ## Traversal and termination A harness may contain any number of top-level subdirectories. Each uses a routing file named after the top-level directory in all-caps — `TOOLS.md` for `tools/`, `DATA.md` for `data/`, and so on. This convention propagates throughout each subtree. The agent navigates progressively: reads `HARNESS.md` to learn about top-level directories, loads a routing file to learn what is in a branch, then loads individual files only when a task requires them. Two mechanisms signal that a directory should not be traversed further: * **`.harnessleaf`** — a file that explicitly marks a directory as a leaf * **`.leaf-detectors`** — a file at the harness root declaring keyword patterns; any directory containing the named file is treated as a leaf of the declared type Your `load_content` tool should respect these boundaries: return the leaf directory's primary file or listing rather than recursing into subdirectories. *** ## Reference file types Files in a harness may be any type — markdown, images, code, data files, or anything else. Your `load_content` tool should return the raw file content and let the agent handle interpretation. When indexing files for presentation or search, only markdown files (`.md`) may carry a `description` frontmatter field. Non-markdown files have no structured metadata. *** ## Script execution When an agent invokes a script bundled inside a skill, your client is responsible for executing it. The expected interface: * Scripts receive input via command-line arguments or stdin * Scripts write results to stdout * Non-zero exit code indicates failure; stderr contains the error message Clients should sandbox script execution appropriately for their environment and expose a `run_script(path: str, script: str, args: list[str]) -> str` tool to the agent. *** ## Validation Use the `harnesses-ref` CLI to validate a harness before loading it: ```bash theme={null} pip install harnesses-ref harnesses-ref validate ./my-harness ``` The validator checks structural correctness including `HARNESS.md` frontmatter, detected skill leaf validity, and the presence of routing files in grouping subdirectories. Clients may run this check at install time and surface errors to the user. *** ## Minimal example A minimal Python implementation of harness loading: ```python theme={null} from pathlib import Path def load_harness(harness_path: Path) -> dict: harness_md = (harness_path / "HARNESS.md").read_text() frontmatter, body = parse_frontmatter_and_body(harness_md) return { "name": frontmatter["name"], "description": frontmatter["description"], "body": body, } def _load_leaf_detectors(harness_path: Path) -> dict[str, str]: detectors: dict[str, str] = {} leaf_file = harness_path / ".leaf-detectors" if leaf_file.exists(): for line in leaf_file.read_text().splitlines(): line = line.strip() if not line or line.startswith("#"): continue if "=" in line: leaf_type, rel_path = line.split("=", 1) detectors[leaf_type.strip()] = rel_path.strip() return detectors def _routing_file_name(top_level_dir: Path) -> str: return top_level_dir.name.upper() + ".md" def _leaf_type(directory: Path, detectors: dict[str, str]) -> str | None: if (directory / ".harnessleaf").exists(): return "leaf" for ltype, rel_path in detectors.items(): if (directory / rel_path).exists(): return ltype return None def load_content(harness_path: Path, rel_path: str) -> str: target = harness_path / rel_path detectors = _load_leaf_detectors(harness_path) if target.is_dir(): ltype = _leaf_type(target, detectors) if ltype is not None: primary_rel = detectors.get(ltype) if primary_rel and (target / primary_rel).exists(): result = (target / primary_rel).read_text() scripts = list((target / "scripts").glob("*")) if (target / "scripts").exists() else [] if scripts: result += "\n\nAvailable scripts: " + ", ".join(s.name for s in scripts) return result return "\n".join(f.name for f in sorted(target.iterdir())) # Find the top-level ancestor to derive the routing file name parts = Path(rel_path).parts routing_name = parts[0].upper() + ".md" if parts else "HARNESS.md" routing_file = target / routing_name if routing_file.exists(): return routing_file.read_text() # Fall back to listing the directory return "\n".join(f.name for f in sorted(target.iterdir())) return target.read_bytes().decode(errors="replace") ``` # Clients Source: https://agentharnesses.io/clients AI clients and tools that support the Agent Harnesses standard. # Clients The following AI clients and tools support the Agent Harnesses standard, allowing users to install and run harnesses directly. ## Adding Your Client If your tool supports harnesses and you'd like to be listed here, open a pull request following the [contribution guidelines](https://github.com/agentharnesses/agentharnesses/blob/main/CONTRIBUTING.md). Requirements: * Your tool must be publicly available * It must be able to discover and load harnesses today (not planned) * It must implement the [progressive disclosure loading model](/specification#loading-model) *** *This page will be updated as the ecosystem grows.* # Best Practices Source: https://agentharnesses.io/harness-creation/best-practices Recommended approaches for building maintainable, effective harnesses. # Best Practices ## Keep skills atomic Each skill should do one thing. Resist the temptation to build a large skill that handles many related tasks — prefer composing several small skills at the harness level instead. **Instead of:** ``` tools/ └── content/ # drafts posts, generates images, scans social, emails stakeholders ``` **Prefer:** ``` tools/ ├── create-blog-post/ ├── generate-images/ ├── scan-social/ └── email-stakeholders/ ``` Atomic skills are easier to test, easier to reuse across harnesses, and easier to update independently. *** ## Put shared context in a dedicated top-level directory Content that is relevant across multiple skills — style guides, environment details, organizational priorities — belongs in its own top-level directory, not inside any individual skill. This avoids duplication and keeps cross-cutting knowledge in one place. Choose a directory name that fits your domain: `context/`, `references/`, `environment/`, `brand/` — whatever reflects what the content actually is. Add a routing file named after that directory so the agent can navigate it efficiently. *** ## Keep HARNESS.md as short as possible `HARNESS.md` is loaded into the agent's context window on every activation. Write the minimum body that lets the agent understand the harness structure and navigate to the right content. A good body: * One short paragraph describing the agent's role * A bulleted list of top-level directories with one-line descriptions * Pointers to routing files for larger directories A bad body: * Repeats information already in routing files or skill documents * Explains how skills work internally * Contains lengthy prose that could live in a dedicated document *** ## Structure directories around the agent's domain, not the spec The spec constrains almost nothing about top-level directory names. Choose names and structure based on how the agent thinks about its work — not on what feels technically correct. A job search harness might have `leads/`, `materials/`, and `workflow/`. A technical support harness might have `playbooks/`, `environment/`, and `escalations/`. The structure should feel obvious to whoever maintains the harness. *** ## Use subdirectories for large directories When a top-level directory grows large, group related content into named subdirectories and add a routing file at each level. This keeps the agent from having to scan a long flat list. See [Organizing Large Harnesses](/harness-creation/organizing-large-harnesses) for the full pattern. *** ## Use termination to protect boundaries Mark directories that shouldn't be traversed by the harness routing layer: * Place `.harnessleaf` in directories with large document stores that have their own access skill * Declare keyword patterns in `.leaf-detectors` to automatically mark directories as leaves based on the files they contain Without termination, an agent may wander into skill internals or large content stores that are meant to be accessed through a dedicated tool. # Evaluating Harnesses Source: https://agentharnesses.io/harness-creation/evaluating-harnesses How to test that your harness behaves correctly and routes to the right content. # Evaluating Harnesses A harness that validates structurally may still fail in practice if descriptions are vague, `HARNESS.md` is too long, or content overlaps in confusing ways. This guide covers how to evaluate harness quality before deploying it to users. ## Structural validation Use the `harnesses-ref` CLI to check that your harness is structurally valid before testing behavior: ```bash theme={null} harnesses-ref validate ./my-harness ``` This checks: * `HARNESS.md` exists and has required frontmatter (`name`, `description`) * All skill leaves (directories detected as skills via `.leaf-detectors`) have valid frontmatter It also emits warnings (non-fatal) for: * Grouping subdirectories missing a routing file — routing files enable progressive disclosure but are not required * Markdown content files missing a `description` in their frontmatter — descriptions help agents decide whether to load a file Fix any structural errors before proceeding to behavioral testing. Warnings do not block validation but are worth addressing for larger harnesses where routing quality matters. *** ## Behavioral testing Structural validity doesn't guarantee the agent will navigate the harness correctly. Test behavior by running the agent with representative prompts and checking which content it loads. ### Build a test prompt set Write 10–20 prompts that represent real tasks the agent will receive. For each prompt, note which skills or documents you expect the agent to load. | Prompt | Expected content | | ----------------------------------------- | --------------------------- | | "Summarize this article for me" | `skills/summarize` | | "Write a blog post about our new feature" | `skills/create-blog-post` | | "What's our brand voice?" | `brand/voice-guidelines.md` | | "Generate a product image" | `skills/generate-images` | ### Check for routing errors Run each prompt and observe what the agent loads: * **Wrong content loaded** — the description of the correct skill or document doesn't match the user's vocabulary; revise the description * **Nothing loaded** — the task wasn't covered, or the description was too narrow; expand it or add new content * **Too much loaded unnecessarily** — descriptions overlap; tighten the scope of each ### Check HARNESS.md length If the agent is slow to respond or loses context mid-task, `HARNESS.md` may be too long. Count the approximate tokens in the body. As a rough guide: * Under 300 tokens — ideal * 300–600 tokens — acceptable for complex harnesses * Over 600 tokens — consider reorganizing with subdirectories and shortening to routing file pointers *** ## Regression testing Whenever you update a skill, add new content, or edit `HARNESS.md`, re-run your full test prompt set. Changes to one description can cause the agent to misroute prompts that previously worked. Keep your test prompt set in version control alongside the harness. *** ## Validation CLI reference ```bash theme={null} # Check structure harnesses-ref validate ./my-harness # Read a specific property from HARNESS.md harnesses-ref read ./my-harness name harnesses-ref read ./my-harness description # Render the harness as prompt XML for inspection harnesses-ref prompt ./my-harness ``` # Optimizing Descriptions Source: https://agentharnesses.io/harness-creation/optimizing-descriptions How to write descriptions that help agents navigate to the right content at the right time. # Optimizing Descriptions Descriptions are short but load-bearing. They are the primary signal an agent uses during the **Discovery** phase to decide which directories and files are relevant to a given task. A poor description means content gets ignored or loaded unnecessarily. ## The description field Every `HARNESS.md` and every routing file has a `description` field in its frontmatter. Individual markdown files should include one too. Write this field as if you're answering the question: *"When should an agent look here?"* ```yaml theme={null} --- description: Condense a piece of text into a concise summary preserving the main argument. --- ``` Not: ```yaml theme={null} --- description: Summarization skill. --- ``` *** ## Rules for good descriptions ### Be specific about the trigger A description should make it obvious when this skill, directory, or document applies. Include the input type, the output type, or the situation. | Weak | Strong | | -------------------- | ----------------------------------------------------------------- | | "Handles blog posts" | "Draft or edit a long-form blog article from an outline or brief" | | "Database stuff" | "Read from and write to the PostgreSQL product database" | | "Style information" | "Typography, tone, and formatting rules for all marketing output" | ### Use verbs for actions, nouns for context Skills and capabilities are actions; reference material is knowledge. This distinction helps agents classify what they're loading. * Capability: *"Generate a social media caption from a product description"* * Context: *"Brand voice guidelines and prohibited language list"* ### Don't describe implementation details The description is for relevance matching, not for explaining how something works. Keep implementation detail in the body. | Too much detail | Right level | | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- | | "Uses Python script to call the OpenAI images API with a 1024x1024 resolution and returns a URL" | "Generate an image prompt and produce a visual asset from a text description" | ### Match the vocabulary users will use Agents compare task descriptions against content descriptions. If your users say "summarize this" and your description says "condense and abridge", there's a mismatch. Use the words your users reach for naturally. *** ## Descriptions in HARNESS.md body Inside the `HARNESS.md` body, you list top-level directories with inline descriptions. These should be even shorter — one clause is ideal — because the agent is scanning a list, not reading a document. ```markdown theme={null} - `tools/` — capabilities for querying databases and processing files (see TOOLS.md) - `data/` — schemas, data quality notes, and field definitions (see DATA.md) - `outputs/` — skills for generating charts, tables, and reports (see OUTPUTS.md) ``` Each entry should be self-contained: a reader (or agent) who has never seen the harness should immediately understand what that directory is for. *** ## Testing descriptions The practical test for a description is to give it to a colleague (or the agent itself) and ask: "Based only on this description, would you know when to look here?" If the answer is "it depends" or "I'm not sure", the description needs work. See [Evaluating Harnesses](/harness-creation/evaluating-harnesses) for a systematic approach to testing description quality. # Organizing Large Harnesses Source: https://agentharnesses.io/harness-creation/organizing-large-harnesses How to use top-level directories and routing files to manage harnesses with many skills and documents. # Organizing Large Harnesses As a harness grows, listing every skill and document directly in `HARNESS.md` becomes unwieldy. Top-level subdirectories let you group related content together, keeping `HARNESS.md` short while still giving the agent a clear map of what's available. ## Top-Level Directories Choose top-level directory names that reflect your domain. There are no required names — structure the harness around how the agent actually thinks about its work: ``` data-analyst-harness/ ├── HARNESS.md ├── tools/ ├── data/ └── outputs/ ``` ``` marketing-assistant-harness/ ├── HARNESS.md ├── skills/ ├── brand/ └── campaigns/ ``` Each top-level directory establishes a **routing file** — a markdown file named after the directory in all-caps that summarizes and navigates its contents. ## Routing Files The routing file name is derived from the top-level directory name and propagates throughout the entire subtree. Every subdirectory within `tools/` uses `TOOLS.md`; every subdirectory within `data/` uses `DATA.md`: ``` data-analyst-harness/ ├── HARNESS.md ├── .leaf-detectors ← declares skill=SKILL.md ├── tools/ │ ├── TOOLS.md ← describes the tools/ branch │ ├── database/ │ │ ├── TOOLS.md ← describes this subgroup │ │ ├── query-database/ │ │ │ └── SKILL.md │ │ └── write-database/ │ │ └── SKILL.md │ └── files/ │ ├── TOOLS.md │ └── read-spreadsheet/ │ └── SKILL.md └── data/ ├── DATA.md ← describes the data/ branch ├── schemas/ │ ├── DATA.md │ └── table-definitions.md └── quirks/ ├── DATA.md └── known-issues.md ``` Routing files use the same frontmatter-plus-body format as `HARNESS.md`: ```markdown theme={null} --- description: Tools for querying databases and reading structured files. --- Use this group when the task involves retrieving or manipulating data from any external source. - `database/` — SQL tools for relational databases - `files/` — readers for spreadsheets and CSVs ``` The primary purpose of a routing file is to answer "should I look here?" — a brief narrative, a list of subdirectory descriptions, or both. It is not a directory listing; it is a routing decision support document. Because it is free-form markdown, it can express nuance: cross-references to other directories, ordering hints, exceptions, or anything else that helps the agent decide quickly without reading every file. ## Routing in HARNESS.md With routing files in place, `HARNESS.md` points to the top-level directories rather than listing every item individually: ```markdown theme={null} --- name: Data Analyst Assistant description: Answers data questions by querying databases, reading files, and generating reports. --- You are a data analyst assistant. - `tools/` — capabilities for data retrieval and computation (see TOOLS.md) - `data/` — schemas, quirks, and context about available data sources (see DATA.md) - `outputs/` — skills for generating charts, tables, and written reports (see OUTPUTS.md) ``` ## Termination By default an agent may explore any subdirectory. Two mechanisms stop traversal at the right boundary: * **`.harnessleaf`** — place this file in any directory to mark it as an explicit leaf the agent should not recurse into * **`.leaf-detectors`** — a file at the harness root that declares keyword patterns; any directory containing the named file is treated as a leaf of the declared type (e.g. `skill=SKILL.md`) This prevents the agent from wandering into skill internals (`scripts/`, internal `references/`) or large document stores that are meant to be accessed through a dedicated traversal skill. ## Nesting Subdirectories may be nested arbitrarily. Each level gets its own routing file, allowing the agent to incrementally drill down rather than loading everything at once: ``` tools/ ├── TOOLS.md ├── database/ │ ├── TOOLS.md │ ├── relational/ │ │ ├── TOOLS.md │ │ └── query-postgres/ │ │ └── SKILL.md │ └── warehouse/ │ ├── TOOLS.md │ └── query-bigquery/ │ └── SKILL.md └── files/ ├── TOOLS.md └── read-csv/ └── SKILL.md ``` Skill directories in this tree (`query-postgres/`, `query-bigquery/`, `read-csv/`) are treated as leaves because the harness root contains a `.leaf-detectors` file declaring `skill=SKILL.md`. Without that entry, those directories would be traversed as ordinary grouping directories. At each level the agent reads only the routing file to understand what's available, then drills in only when a task requires it — the same **progressive disclosure** model that governs the harness as a whole. This kind of nesting — plain grouping subdirectories under `tools/` — is different from **nesting harnesses**, covered next. Here, `TOOLS.md` propagates unchanged all the way down; nothing resets it. ## Nested Harnesses A directory can contain its own `HARNESS.md`, making it the root of an independent nested harness rather than just another grouping subdirectory. This resets routing-file propagation: the nested harness's own direct children each become a fresh top-level directory, the same way `tools/` and `data/` do beneath the true root. ``` tools/ ├── TOOLS.md └── plugin-x/ ├── HARNESS.md ← nested harness └── database/ ├── DATABASE.md ← fresh top-level directory, not TOOLS.md └── query-postgres/ └── SKILL.md ``` Use a nested harness when a subtree is conceptually its own self-contained unit — a bundled plugin, a vendored sub-package — that happens to live inside a larger harness rather than being organized as one more grouping level within it. A plain grouping subdirectory (like `tools/database/` above, without its own `HARNESS.md`) is the right choice for ordinary organizational nesting; reach for a nested harness only when the subtree genuinely stands on its own. # Quickstart Source: https://agentharnesses.io/harness-creation/quickstart Build and install your first Agent Harness in minutes. # Quickstart This guide walks you through creating a minimal harness from scratch. ## Prerequisites * An AI client that supports Agent Harnesses (see [Clients](/clients)) * Basic familiarity with markdown ## Step 1 — Create the harness directory ```bash theme={null} mkdir my-first-harness cd my-first-harness ``` ## Step 2 — Write HARNESS.md `HARNESS.md` is the only required file. Create it now: ```markdown theme={null} --- name: Writing Assistant description: Helps draft, edit, and improve written content. --- You are a writing assistant. Help the user draft, revise, and polish written content. Adapt your tone to the context: formal for business documents, conversational for blog posts. ``` That's a valid harness. You can stop here and install it in your client. ## Step 3 — Add a skill (optional) Create a skill to give your agent a specific, reusable capability: ```bash theme={null} mkdir -p skills/summarize ``` ```markdown theme={null} # skills/summarize/SKILL.md --- name: Summarize description: Condense a piece of text into a concise summary. --- To summarize a document: 1. Read the full text provided by the user. 2. Identify the main argument or purpose. 3. Extract the 3–5 most important supporting points. 4. Write a summary of 3–5 sentences using plain language. 5. Do not add information that isn't in the source text. ``` Create a `.leaf-detectors` file at the harness root so clients know to treat directories containing `SKILL.md` as skill leaves: ``` # .leaf-detectors skill=SKILL.md ``` Without this file, a compliant client will traverse into `skills/summarize/` as an ordinary directory rather than activating it as a skill. Update `HARNESS.md` to reference it: ```markdown theme={null} --- name: Writing Assistant description: Helps draft, edit, and improve written content. --- You are a writing assistant. Help the user draft, revise, and polish written content. - `skills/summarize` — condense any text into a concise summary ``` ## Step 4 — Add a directory (optional) You can add any top-level directory to bundle context relevant to your domain. The directory name is up to you. Create a routing file named after it in all-caps to help the agent navigate its contents: ```bash theme={null} mkdir context ``` ```markdown theme={null} # context/CONTEXT.md --- description: Style and tone guidelines that apply to all written output. --- Consult this directory for rules that govern how the agent should write. - `style-guide.md` — tone, formatting, and sentence-length rules ``` ```markdown theme={null} # context/style-guide.md --- description: Tone and formatting rules that apply to all written output. --- - Use active voice wherever possible. - Prefer short sentences (under 25 words). - Avoid jargon unless the user's context is clearly technical. - Headings use sentence case, not title case. ``` Update `HARNESS.md`: ```markdown theme={null} --- name: Writing Assistant description: Helps draft, edit, and improve written content. --- You are a writing assistant. Help the user draft, revise, and polish written content. - `skills/summarize` — condense any text into a concise summary - `context/` — style and tone guidelines (see CONTEXT.md) ``` ## Step 5 — Install the harness Refer to your AI client's documentation for how to install a local harness directory. Typically this involves pointing the client at the harness root folder. ## What's next * [Best Practices](/harness-creation/best-practices) — learn how to structure harnesses for maintainability * [Optimizing Descriptions](/harness-creation/optimizing-descriptions) — write descriptions that help agents activate the right skills * [Evaluating Harnesses](/harness-creation/evaluating-harnesses) — test that your harness behaves as expected # Using Scripts Source: https://agentharnesses.io/harness-creation/using-scripts How to bundle executable code with skills inside a harness. # Using Scripts Scripts give an agent the ability to take actions — running code, calling APIs, reading files — rather than just reasoning about them. Scripts live inside individual skills, not at the harness level. ## Where scripts live Scripts belong in the `scripts/` subdirectory of a skill, not in the harness root: ``` my-harness/ ├── HARNESS.md └── skills/ └── query-database/ ├── SKILL.md └── scripts/ └── run_query.py ``` The harness is responsible for bundling the right skills together. The skill is responsible for bundling the right scripts together. This separation keeps the harness root clean and makes skills independently portable. *** ## Referencing scripts from SKILL.md In `SKILL.md`, tell the agent when and how to invoke the script: ```markdown theme={null} --- name: Query Database description: Run a read-only SQL query against the product database and return results. --- To query the database: 1. Identify the data the user needs. 2. Write a read-only SQL SELECT statement. 3. Run `scripts/run_query.py` with the SQL as a command-line argument. 4. Return the results to the user in a readable format. **Script:** `scripts/run_query.py ` ``` Be explicit about the script's interface: arguments, expected output, and any error conditions the agent should handle. *** ## What belongs in scripts vs. in the SKILL.md body | Belongs in scripts | Belongs in SKILL.md | | -------------------------------------- | ----------------------------------------------- | | Code that calls an external API | When and why to call the API | | File I/O, database queries | What data to look for and how to interpret it | | Computations on structured data | How to present results to the user | | Authentication and credential handling | Which credential or environment variable to use | Scripts handle execution. `SKILL.md` handles reasoning. *** ## Script conventions These aren't enforced by the spec, but they produce more reliable agent behavior: * **Use stdin/stdout.** Scripts should read input from command-line arguments or stdin and write results to stdout. This makes them easy for agents to invoke and parse. * **Exit with a non-zero code on failure.** Agents can detect failure and reason about it if the script communicates errors through exit codes. * **Print structured output.** JSON or simple key-value output is easier for agents to parse than prose. * **Keep scripts focused.** One script per distinct action; let the agent decide which script to call, not the script itself. * **Don't embed credentials.** Use environment variables. Document which variables are required in `SKILL.md`. *** ## Harness-level scripts The spec does not define a `scripts/` directory at the harness root. If you find yourself wanting harness-level scripts, consider whether they belong in a shared skill that multiple other skills depend on, or whether they represent a new atomic capability that should become its own skill. # Agent Harnesses Source: https://agentharnesses.io/home A standardized way to give AI agents roles, context, and capabilities. # Agent Harnesses Agent Harnesses provide a lightweight, open format for defining the complete context an AI agent needs to fulfill a role. Harnesses do this by bundling capabilities and context into a single, portable, structured directory. ## What is a Harness? A harness is a folder containing a `HARNESS.md` file plus any number of top-level subdirectories the domain requires. At startup the full `HARNESS.md` is loaded, establishing the agent's role. As tasks arrive, the agent pulls in only the content each task requires — **progressive disclosure** applied at the harness level. ``` my-harness/ ├── HARNESS.md # Required: identity + overview ├── .leaf-detectors # Optional: leaf boundary patterns ├── tools/ # Example top-level directory — any name ├── brand/ # Example top-level directory — any name └── data/ # Example top-level directory — any name, any purpose ``` The subdirectory names are chosen by the harness author. `skills/` and `references/` are common conventions, but the spec places no constraints on what top-level directories exist or what they're called. ## How Harnesses Relate to Skills The [Agent Skills](https://github.com/agentskills/agentskills) standard defines how to package a single atomic capability — like "interact with a database" or "create brand assets". A harness bundles many of these skills together to define a **complete agent role**. One analogy is to conceptualize a harness as a job title, where skills are like job requirements. A "technical support" role/harness might have "database management", "ticket response", and "spreadsheet modification" requirements/skills. ## Routing Through a Harness For each top-level directory, the harness uses a **routing file** to help the agent navigate its contents. The routing file is named after the top-level directory in all-caps — `TOOLS.md` for `tools/`, `DATA.md` for `data/`, and so on. This convention propagates through every subdirectory in that branch: ``` my-harness/ ├── HARNESS.md ├── tools/ │ ├── TOOLS.md # Describes the tools/ branch │ ├── backend/ │ │ ├── TOOLS.md # Describes this subgroup │ │ └── create-api/ │ └── frontend/ │ ├── TOOLS.md │ └── build-ui/ └── data/ ├── DATA.md # Describes the data/ branch ├── schemas/ │ ├── DATA.md │ └── table-definitions.md └── quirks/ ├── DATA.md └── known-issues.md ``` By reading a routing file, an agent can quickly decide whether a branch is relevant to the current task — without opening every file inside it. `HARNESS.md` points to these routing files rather than listing every individual item, keeping the entry point short as the harness grows. Routing files are optional — for small directories, filenames and description frontmatter are often enough. For larger or more varied groups, a well-written routing file is the difference between efficient discovery and exhaustive scanning. ## Why do Harnesses Exist, and Why This Specification? Harnesses have emerged organically across the industry as a necessity. When defining complex agents, many skills need to be leveraged in tandem, and much information is required to contextualize those skills and how they relate to the environment the agent is working in. Because of the richness of information required, agents that employ large harnesses are often slow. The underlying LLM needs to scan through large sets of documentation and a wide array of skills to effectively make correct decisions. Harnesses don't currently have a defined structure, making it difficult to optimize agents to leverage the information within a harness efficiently. The goal of the "Agent Harnesses" standard is to standardize how agent harnesses are defined; making it easier to create harnesses, and to build agents that leverage them efficiently and effectively. ## Get Started Read the full format definition. Build your first harness in minutes. Learn how to structure harnesses well. Add harness support to your AI client. # Specification Source: https://agentharnesses.io/specification The complete Agent Harnesses format specification. # Specification ## Overview A harness is a directory that gives an AI agent everything it needs to fulfill a role. It contains a required `HARNESS.md` file, an optional `.leaf-detectors` configuration file, and any number of top-level subdirectories the domain requires: ``` my-harness/ ├── HARNESS.md ├── .leaf-detectors # e.g. skill=SKILL.md ├── tools/ │ └── query-db/ │ └── SKILL.md ├── brand/ │ └── style-guide.md └── data/ └── schema.md ``` The subdirectory names are chosen by the harness author to reflect the agent's domain. There are no required directory names beyond `HARNESS.md` itself. *** ## HARNESS.md `HARNESS.md` is the required entry point for every harness. It uses YAML frontmatter followed by a markdown body. ### Frontmatter ```yaml theme={null} --- name: description: --- ``` | Field | Required | Description | | ------------- | -------- | ---------------------------------------------------------------- | | `name` | Yes | Short human-readable name for the harness | | `description` | Yes | One sentence describing what this harness enables an agent to do | ### Body The body is free-form markdown. Its primary purpose is **routing**: an agent reading `HARNESS.md` should be able to decide which subdirectories to explore for a given task without opening anything else first. The body should be **as brief as possible**. It is loaded into the agent's context window on every activation — every token competes with task context. Avoid prose that restates the frontmatter description or explains concepts the agent already knows. A well-structured body typically includes: * A one-paragraph summary of the agent's role * A bulleted index of top-level directories with one-line descriptions * References to routing files within those directories for larger harnesses **Avoid over-indexing.** The more routing information the body contains, the more the agent must read before acting. Start with a minimal body and add detail only where routing demonstrably fails — not preemptively. ### Example ```markdown theme={null} --- name: Marketing Assistant description: Helps create and review marketing content across blog, social, and visual channels. --- You are a marketing assistant. Produce content that is on-brand, consistent, and appropriate for each channel. - `tools/` — capabilities for content creation and research (see TOOLS.md) - `brand/` — tone, typography, and visual guidelines (see BRAND.md) - `campaigns/` — active campaign briefs and goals (see CAMPAIGNS.md) ``` *** ## Top-Level Directories The harness root may contain any number of top-level subdirectories. Each one organizes content relevant to the agent's domain — capabilities, reference material, data, outputs, environment details, or anything else the harness author needs. ### Routing Files Each top-level directory establishes a **routing file** — a named markdown file used to summarize and navigate the contents of that directory and its descendants. The routing file is named after the top-level directory in all-caps with a `.md` extension: | Top-level directory | Routing file | | ------------------- | --------------- | | `skills/` | `SKILLS.md` | | `references/` | `REFERENCES.md` | | `tools/` | `TOOLS.md` | | `data/` | `DATA.md` | | `outputs/` | `OUTPUTS.md` | The routing file name is derived from the **top-level** directory and propagates throughout the entire subtree. Every grouping subdirectory within `tools/` uses `TOOLS.md` — not a name derived from the subdirectory itself: ``` tools/ ├── TOOLS.md ├── database/ │ ├── TOOLS.md │ └── query-database/ │ └── instructions.md └── files/ ├── TOOLS.md └── read-spreadsheet/ └── instructions.md ``` ### Routing File Format Routing files use the same frontmatter-plus-body format as `HARNESS.md`: ```markdown theme={null} --- description: --- ``` The `description` field characterizes the directory as a whole. The body is free-form markdown written to answer "should I look here?" — a brief narrative, a list of subdirectory descriptions, or both: ```markdown theme={null} --- description: Tools for querying databases and reading structured files. --- Use this group when the task involves retrieving or manipulating data from any external source. Subdirectories are organized by source type. - `database/` — SQL query tools for relational databases - `files/` — readers for spreadsheets, CSVs, and JSON - `compute/` — Python and SQL execution environments ``` Routing files are optional at any level — for small directories, filenames and `description` frontmatter fields in individual files are often sufficient. For larger or more varied groups, a well-written routing file is the difference between efficient discovery and exhaustive scanning. Subdirectories may be nested arbitrarily, with each grouping level getting its own routing file. ### Nested Harnesses A directory anywhere within a harness may itself contain a `HARNESS.md`. This makes it a **nested harness** — the root of its own independent tree — and it requires the same frontmatter (`name` and `description`) as a top-level `HARNESS.md`. A nested `HARNESS.md` resets routing-file propagation for what lies beneath it: each of its own direct child directories becomes a fresh top-level directory in its own right, exactly as top-level directories do beneath the true harness root. Propagation then continues unchanged from there until the next nested `HARNESS.md` is encountered. ``` my-harness/ ├── HARNESS.md └── skills/ ├── SKILLS.md └── plugin-x/ ├── HARNESS.md ← nested harness; resets propagation below here └── tools/ ├── TOOLS.md ← fresh top-level directory: tools/ itself └── query-db/ └── SKILL.md ``` `skills/plugin-x/tools/`'s routing file is `TOOLS.md`, not `SKILLS.md` — even though `plugin-x/` itself is still addressed via the `SKILLS.md` top-level directory it inherited from its parent (a nested `HARNESS.md` resets the top-level directory for a directory's *children*, not for the directory itself). `.leaf-detectors` is unaffected by nested-harness boundaries: the nearest ancestor config still applies regardless of nesting. *** ## Termination By default an agent traversing a harness may explore any subdirectory. Two mechanisms mark a directory as a **leaf** — a terminal point beyond which the harness routing logic does not recurse: ### `.harnessleaf` A file named `.harnessleaf` placed in a directory signals an explicit termination boundary. The agent treats the directory as a unit to be read or invoked rather than a branch to explore further. ### `.leaf-detectors` `.leaf-detectors` is an optional file at the harness root that defines **keyword patterns** — rules that automatically mark a directory as a leaf when it contains a specific file. It uses a simple line-based format: ``` # Lines beginning with # are comments. # Format: leaf_type=relative_path # A directory containing the specified path is treated as a leaf of that type. skill=SKILL.md ``` Each line declares that any directory containing the named file is a leaf of the given type. There are no built-in patterns — all detection is explicit. A harness that contains Agent Skills should declare `skill=SKILL.md`; without that entry, directories containing `SKILL.md` are traversed rather than treated as skill leaves. Leaf type names are meaningful: clients and tools use them to decide how to handle the leaf. A `skill` leaf is loaded and executed as an Agent Skill. Other types are treated as opaque boundaries — traversal stops, and the agent is expected to access the directory through a dedicated skill or tool. Termination gives the harness a well-defined boundary. It prevents the routing layer from recursing into skill internals (`scripts/`, internal `references/`, `assets/`) and into large content stores that are meant to be accessed through a purpose-built traversal skill. *** ## Loading Model Harnesses use **progressive disclosure** — agents load only what each task requires. | Phase | Trigger | Interaction with the harness | | -------------- | ------------------------ | ------------------------------------------------------------------------------ | | **Load** | Session start | Full `HARNESS.md` body is injected into context, establishing the agent's role | | **Discovery** | Task received | Agent reads routing files to find relevant subdirectories | | **Activation** | Routing aligns with task | Agent reads the full content of a relevant skill, directory, or file | | **Execution** | Action required | Agent runs a script bundled within a skill | `HARNESS.md` is the agent's map of the harness. From there the agent navigates progressively — reading routing files to decide which branch is relevant, then loading individual files only when a task requires them. This model allows a harness to contain dozens of capabilities and reference documents without consuming the full context window on every interaction. *** ## Versioning Harnesses do not define a required versioning scheme. It is recommended to version harnesses using standard version control (git) and to pin skill dependencies by directory rather than by registry reference.