# Context engineering for agents 101 (part 1): progressive skill disclosure and concise tools

When a coding agent loses track of your instructions around turn twenty, the instinct is to blame the model checkpoint and reach for a larger parameter count. In practice, most mid-session failures happen before the model even starts reasoning: the agent harness has quietly filled the context window with thirty thousand tokens of unused skill manuals, verbose MCP schemas, and raw database UUIDs.

Even when you run long-context open-weight models like **GLM-5.2** or **Qwen3.8-27B** on our API, treating a large context window like an infinite hard drive degrades recall and drives up latency on every turn. Research teams at [Anthropic Engineering](https://www.anthropic.com/research/effective-context-engineering-for-ai-agents), [LangChain](https://www.langchain.com/blog/the-anatomy-of-an-agent-harness), and [Chroma Research](https://research.trychroma.com/context-rot) call this effect **context rot**: every unnecessary token in the window competes for the model’s attention budget.

### How do you give daily coding agents like OpenCode, Claude Code, and Codex access to dozens of specialized skills and tools without paying a forty-thousand-token startup tax on every turn?

In Part 1 of our **Context Engineering for Agents 101** series, we build, test, and validate our first drop-in harness module (`piece1_progressive_skills.py`). It adds two core primitives to your agent loop: **progressive skill disclosure** and **concise tool response formatting**, backed by a local MCP server you can wire into OpenCode, Claude Code, and Codex in under a minute.

**Quick summary (TL;DR):** Preloading 10 full `SKILL.md` manuals and 8 raw GitHub REST API issue objects at startup bills **53,452 prompt tokens** (`7.63s` latency) on `qwen3.8-27b` before your coding agent reads a single repository file. Replacing eager loading with a one-line progressive skill menu (`35,685 → 293` prompt tokens, `-99.18%`) and concise tool formatting (`17,794 → 753` prompt tokens, `-95.77%`) cuts total Turn-1 prompt usage by **98.09%** (`53,452 → 1,019` tokens in `0.79s`) and keeps Turn 2 at **3,996 tokens (`-92.52%`)** when loading a needed skill on demand across OpenCode, Claude Code, Codex, and [Roo Code](https://regolo.ai/roo-code-ai-powered-autonomous-coding-in-vscode/) on our European API.

 TURN-1 CONTEXT WINDOW ANATOMY · PIECE 1 REAL API BENCHMARK### What actually enters your model's context window on Turn 1?

Comparing a naive coding agent (preloading 10 full `SKILL.md` manuals + 8 raw open issues from `modelcontextprotocol/python-sdk` via the GitHub REST API) against Piece 1 (1-line progressive menu + on-demand MCP loading + concise tool output) measured on `qwen3.8-27b`.

 

   BEFORE · NAIVE EAGER PRELOAD + RAW GITHUB JSONAll 10 skill manuals &amp; 8 raw GitHub issue payloads dumped at Turn 1

 

53,452 prompt tokens billed on Turn 1 (7.63s)

 

 10 full SKILL.md files preloaded: 35,685 tok (66.8%) — 9 of 10 unused! 

 8 raw GitHub issues: 17,794 tok (33.2%) 

 

1. System prompt bloat (35,685 prompt_tokens)

 `# Skill: ab-testing (12,525 chars)Full experiment checklists, ICE scoring tables...# Skill: ad-creative, ads, ai-evals, ai-seo...[+ 9 more full SKILL.md files preloaded at Turn 1]` 

2. Raw GitHub API JSON (17,794 prompt_tokens / 8 issues)

 `{"id": 3918273641, "node_id": "I_kwDOM...", "user": {"avatar_url": "https://avatars.githubusercontent.com/...",          "followers_url": "https://api.github.com/users/..."}, "title": "Issue #3804...", "state": "open", "body": "..."}` 

 

 

  AFTER · PIECE 1 PROGRESSIVE DISCLOSURE + CONCISE TOOLS1-line skill index + on-demand MCP fetch + concise GitHub issue output

 

1,019 prompt tokens billed on Turn 1 (-98.09%, 0.79s)

 

 52,433 tokens of startup &amp; JSON noise eliminated — 98.09% of attention budget preserved (3,996 tok / -92.52% on Turn 2 with 1 skill loaded) 

 

1. Compact 1-line index (293 prompt_tokens, -99.18%)

 `Available on-demand skills (call load_skill(name) only when needed):- ab-testing: When the user wants to plan, design, or implement...- ai-evals: Help users build robust infrastructure for measuring...  → Loading 1 full skill on demand at Turn 2 uses 3,996 tok (-92.52%)` 

2. Concise GitHub output (753 prompt_tokens, -95.77%)

 `[{"number":3804,"title":"...","status":"open","owner":"...",  "labels":["bug"],"summary":"First 160 chars of issue body..."}]  → Zero node_ids, follower URLs, or avatar URLs in context` 

 

 

 

 **35,685 → 293 tok** startup skill prompt tokens (-99.18%) measured on `qwen3.8-27b` across 10 real local `SKILL.md` files 

 **17,794 → 753 tok** tool payload tokens (-95.77%) on 8 real open issues from `modelcontextprotocol/python-sdk` 

 **1,019 tok (0.79s)** total Turn-1 prompt (-98.09% vs 53,452 tok in 7.63s), and 3,996 tok (-92.52%) when loading 1 skill on Turn 2 

 

Measured via live `usage.prompt_tokens` on `https://api.regolo.ai/v1` (`qwen3.8-27b`, `enable_thinking=False`, November 2, 2026) and GitHub REST API (`modelcontextprotocol/python-sdk`).

 

## The real numbers on Qwen3.8-27B: 10 local skills and 8 live GitHub REST API issues

Rather than relying on character-division heuristics or synthetic mock records, we measured every stage of Piece 1 directly against the server tokenizer on `https://api.regolo.ai/v1` (`model="qwen3.8-27b"`, `enable_thinking=False`) using 10 real local `SKILL.md` manuals and 8 real open issues fetched live from [`modelcontextprotocol/python-sdk`](https://github.com/modelcontextprotocol/python-sdk/issues) via the GitHub REST API:

### Measured prompt tokens and wall-clock latency on Qwen3.8-27B

Every row below records real `usage.prompt_tokens` and latency from `https://api.regolo.ai/v1/chat/completions` (November 2, 2026).

 

 100% Real API Tokenizer + Live GitHub JSON 

 | Benchmark Stage | Naive BaselineEager preload + raw JSON | Piece 1 Harness1-line menu + concise JSON | Measured Reductionusage.prompt\_tokens | Latency Impactqwen3.8-27b (EU API) |
|---|---|---|---|---|
| 1. Startup skill prefix10 local ~/.claude/skills/\*/SKILL.md files | 35,685 tok9 of 10 skills unused on task | 293 tok1-line name + summary index | -99.18%35,392 tokens saved at boot | 4.03s → **0.33s**12.2x faster prefix prefill |
| 2. External tool output8 open issues from modelcontextprotocol/python-sdk | 17,794 tok58,913 chars of raw GitHub JSON | 753 tok2,863 chars (concise mode) | -95.77%Strips avatar\_url, node\_id, URLs | Identical answer8 issues (#3804 first) |
| 3. Combined Turn 110 skills + 8 GitHub issues + user question | 53,452 tokOver 53k tokens on Turn 1 | 1,019 tok98.09% of window stays free | -98.09%52,433 tokens eliminated | 7.63s → **0.79s**9.6x faster Turn-1 response |
| 4. Turn 2 on-demand loadAgent calls load\_skill\_on\_demand("ab-testing") | 53,452 tokPays for all 10 skills every turn | 3,996 tokLoads only the 1 needed skill | -92.52%Even after loading a 12.5KB skill | 7.63s → **0.87s**Full skill instructions intact |

  SOVEREIGN EUROPEAN INFERENCE 

Run OpenCode, Claude Code, and Codex on our EU open-weight API

Get 600 million monthly tokens across GLM-5.2, Qwen3.8-27B, Qwen3.5-122B, GPT-OSS 120B, Qwen3-Embedding-8B, and Brick on our flat Core plan (€39/mo, ~€0.065/1M) with certified Zero Data Retention.

[Start 30-day free trial (no card required) →](https://regolo.ai/pricing/)

Free credits included · 100% green energy · ✓ EU Green Datacenters ✓ Certified ZDR

## Two harness primitives: progressive skill menus and concise tool responses

As highlighted in [LangChain’s Deep Agents guide](https://www.langchain.com/blog/context-engineering-deep-agents-remember) and [Anthropic’s tool engineering research](https://www.anthropic.com/research/writing-tools-for-agents), keeping irrelevant tokens out of the window starts with two structural changes in your harness:

1. **Progressive disclosure for skills:** Instead of injecting the full body of every `SKILL.md` file into the system prompt, scan your skills folder at startup and extract only the skill name and its first-sentence description. Ten skills occupy **293 prompt tokens** on `qwen3.8-27b` instead of **35,685 tokens** (`-99.18%`). When the agent encounters a task that matches a skill, it calls `load_skill_on_demand(skill_name)` to pull the full instructions just in time (bringing Turn 2 to **3,996 prompt tokens**, still **92.52% smaller** than preloading all ten manuals).
2. **A `response_format` toggle on every tool:** Add an enum parameter (`"concise"` vs `"detailed"`) to your custom tools. Default to `"concise"` so daily searches return issue numbers, titles, statuses, labels, and a 160-character summary without avatar URLs, GraphQL `node_id` strings, or nested API URLs (cutting 8 real GitHub issue records from **17,794 prompt tokens** down to **753 prompt tokens**, `-95.77%`).

 MEASURED HARNESS SAVINGS · PIECE 1 REAL API BENCHMARK### Real prompt tokens billed on Qwen3.8-27B before vs after

Measured across 10 local SKILL.md files and 8 live open issues from modelcontextprotocol/python-sdk.

Naive Turn 153,452 tok

Piece 1 Turn 11,019 tok

Full 10 skills35,685 tok

1-line menu293 tok

Raw GitHub17,794 tok

Concise JSON753 tok

Turn 2 (1 skill)3,996 tok

Verified via `python3 piece1_progressive_skills.py --self-test` on `https://api.regolo.ai/v1` (`qwen3.8-27b`, Nov 2, 2026).

## Build, test, and validate Piece 1 in Python (copy-paste &amp; run)

Save the complete script below as `piece1_progressive_skills.py` (also available in our [context-engineering-101 GitHub kit](https://github.com/regolo-ai/tutorials/tree/main/context-engineering-101)). It uses zero character-division estimates and zero synthetic data: when you run `--self-test`, it scans your local skills folder, fetches 8 real open issues from `https://api.github.com/repos/modelcontextprotocol/python-sdk/issues`, and measures the exact `usage.prompt_tokens` and wall-clock latency on `https://api.regolo.ai/v1` (`qwen3.8-27b` with `"chat_template_kwargs": {"enable_thinking": False}` so routine harness turns complete in under a second):

```
#!/usr/bin/env python3
"""
piece1_progressive_skills.py: Progressive skill menu + concise tool formatter.
Run `python3 piece1_progressive_skills.py --self-test` with REGOLO_API_KEY to verify
real usage.prompt_tokens and latency on https://api.regolo.ai/v1 (qwen3.8-27b) + GitHub REST API.
"""
from __future__ import annotations
import argparse, json, os, re, ssl, time, urllib.request
from pathlib import Path
from typing import Any, Dict, List

REGOLO_BASE_URL = os.environ.get("REGOLO_BASE_URL", "https://api.regolo.ai/v1")
MODEL = os.environ.get("REGOLO_MODEL", "qwen3.8-27b")
_SSL_CTX = ssl._create_unverified_context()

class ProgressiveSkillRegistry:
    """Loads only name + 1-line description at startup; reads full SKILL.md on demand."""

    def __init__(self, skills_dir: Path, max_skills: int = 10) -> None:
        self.skills_dir = Path(skills_dir).expanduser()
        self.max_skills = max_skills
        self._index: Dict[str, Dict[str, str]] = {}
        if self.skills_dir.exists():
            for skill_md in sorted(self.skills_dir.glob("*/SKILL.md"))[: self.max_skills]:
                raw = skill_md.read_text(encoding="utf-8", errors="ignore")
                m = re.search(r"description:\s*(.+)", raw)
                desc = m.group(1).strip().strip("'\"") if m else "On-demand agent skill."
                summary = re.split(r"(?<=[.!?])\s+", desc)[0][:110]
                self._index[skill_md.parent.name] = {"path": str(skill_md), "summary": summary}

    def compact_menu(self) -> str:
        lines = ["Available on-demand skills (call load_skill(name) only when needed):"]
        return "\n".join(lines + [f"- {k}: {v['summary']}" for k, v in self._index.items()])

    build_compact_menu = compact_menu

    def full_preload_text(self) -> str:
        return "\n\n".join(
            Path(meta["path"]).read_text(encoding="utf-8", errors="ignore")
            for meta in self._index.values()
        )

    def load_skill(self, name: str) -> str:
        if name not in self._index:
            return f"Skill '{name}' not found. Available: {', '.join(self._index)}."
        return Path(self._index[name]["path"]).read_text(encoding="utf-8", errors="ignore")

def format_tool_response(records: List[Dict[str, Any]], response_format: str = "concise") -> str:
    if response_format == "detailed":
        return json.dumps(records, indent=2)
    concise_rows = []
    for r in records:
        row: Dict[str, Any] = {}
        if "number" in r:
            row["number"] = r["number"]
        if "title" in r:
            row["title"] = r["title"]
        if "status" in r or "state" in r:
            row["status"] = r.get("status") or r.get("state")
        if "owner" in r:
            row["owner"] = r["owner"]
        elif isinstance(r.get("user"), dict) and "login" in r["user"]:
            row["owner"] = r["user"]["login"]
        if isinstance(r.get("labels"), list):
            row["labels"] = [lbl.get("name") if isinstance(lbl, dict) else str(lbl) for lbl in r["labels"]]
        if "summary" in r:
            row["summary"] = r["summary"]
        elif "body" in r and r["body"]:
            row["summary"] = re.sub(r"\s+", " ", str(r["body"]).strip())[:160]
        concise_rows.append(row)
    return json.dumps(concise_rows, separators=(",", ":"))

def fetch_real_github_issues(repo: str = "modelcontextprotocol/python-sdk", count: int = 8) -> List[Dict[str, Any]]:
    req = urllib.request.Request(
        f"https://api.github.com/repos/{repo}/issues?state=open&per_page=20",
        headers={"Accept": "application/vnd.github+json", "User-Agent": "regolo-context-101/1.0"},
    )
    with urllib.request.urlopen(req, timeout=30, context=_SSL_CTX) as resp:
        items = json.loads(resp.read().decode("utf-8"))
    pure = [it for it in items if "pull_request" not in it]
    return (pure if len(pure) >= count else items)[:count]

def measure_on_regolo_api(api_key: str, messages: List[Dict[str, str]], max_tokens: int = 80) -> Dict[str, Any]:
    t0 = time.perf_counter()
    body = json.dumps({
        "model": MODEL,
        "messages": messages,
        "max_tokens": max_tokens,
        "temperature": 0.0,
        "chat_template_kwargs": {"enable_thinking": False},
    }).encode("utf-8")
    req = urllib.request.Request(
        f"{REGOLO_BASE_URL}/chat/completions",
        data=body,
        headers={"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(req, timeout=90, context=_SSL_CTX) as resp:
        data = json.loads(resp.read().decode("utf-8"))
    return {
        "prompt_tokens": data.get("usage", {}).get("prompt_tokens"),
        "latency_s": round(time.perf_counter() - t0, 2),
        "reply": (data["choices"][0]["message"].get("content") or "").strip(),
    }

def run_self_test() -> Dict[str, Any]:
    api_key = os.environ.get("REGOLO_API_KEY", "").strip()
    if not api_key:
        raise RuntimeError("Export REGOLO_API_KEY before running --self-test")
    skills_path = Path("~/.claude/skills").expanduser()
    if not skills_path.exists():
        skills_path = Path("~/.agents/skills").expanduser()
    reg = ProgressiveSkillRegistry(skills_path, max_skills=10)
    full_skills, menu = reg.full_preload_text(), reg.compact_menu()
    gh_issues = fetch_real_github_issues("modelcontextprotocol/python-sdk", count=8)
    detailed_str, concise_str = format_tool_response(gh_issues, "detailed"), format_tool_response(gh_issues, "concise")

    skill_full = measure_on_regolo_api(api_key, [{"role": "system", "content": full_skills}, {"role": "user", "content": "Reply with OK."}], 8)
    skill_menu = measure_on_regolo_api(api_key, [{"role": "system", "content": menu}, {"role": "user", "content": "Reply with OK."}], 8)
    q = "Reply in one sentence naming how many open issues are in this list and the number of the first issue."
    tool_det = measure_on_regolo_api(api_key, [{"role": "system", "content": "You are a coding assistant."}, {"role": "user", "content": f"Here is the GitHub issue list:\n{detailed_str}\n{q}"}])
    tool_con = measure_on_regolo_api(api_key, [{"role": "system", "content": "You are a coding assistant."}, {"role": "user", "content": f"Here is the GitHub issue list:\n{concise_str}\n{q}"}])
    t1_unfiltered = measure_on_regolo_api(api_key, [{"role": "system", "content": full_skills}, {"role": "user", "content": f"Here is the GitHub issue list:\n{detailed_str}\n{q}"}])
    t1_piece1 = measure_on_regolo_api(api_key, [{"role": "system", "content": menu}, {"role": "user", "content": f"Here is the GitHub issue list:\n{concise_str}\n{q}"}])
    first_skill = next(iter(reg._index))
    t2_ondemand = measure_on_regolo_api(api_key, [{"role": "system", "content": menu}, {"role": "user", "content": f"[Tool result from load_skill_on_demand('{first_skill}')]:\n{reg.load_skill(first_skill)}\n\nHere is the concise GitHub issue list:\n{concise_str}\nReply in one sentence naming how many open issues are in this list."}])

    res = {
        "model": MODEL,
        "skills_scanned": len(reg._index),
        "skill_full_preload_prompt_tokens": skill_full["prompt_tokens"],
        "skill_compact_menu_prompt_tokens": skill_menu["prompt_tokens"],
        "skill_prefix_reduction_pct": round((1 - skill_menu["prompt_tokens"] / skill_full["prompt_tokens"]) * 100, 2),
        "tool_detailed_prompt_tokens": tool_det["prompt_tokens"],
        "tool_concise_prompt_tokens": tool_con["prompt_tokens"],
        "tool_response_reduction_pct": round((1 - tool_con["prompt_tokens"] / tool_det["prompt_tokens"]) * 100, 2),
        "turn1_unfiltered_prompt_tokens": t1_unfiltered["prompt_tokens"],
        "turn1_unfiltered_latency_s": t1_unfiltered["latency_s"],
        "turn1_piece1_prompt_tokens": t1_piece1["prompt_tokens"],
        "turn1_piece1_latency_s": t1_piece1["latency_s"],
        "turn1_total_reduction_pct": round((1 - t1_piece1["prompt_tokens"] / t1_unfiltered["prompt_tokens"]) * 100, 2),
        "turn1_reply": t1_piece1["reply"],
        "turn2_on_demand_skill_loaded": first_skill,
        "turn2_on_demand_prompt_tokens": t2_ondemand["prompt_tokens"],
        "turn2_vs_unfiltered_reduction_pct": round((1 - t2_ondemand["prompt_tokens"] / t1_unfiltered["prompt_tokens"]) * 100, 2),
    }
    print(json.dumps(res, indent=2))
    return res

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--self-test", action="store_true")
    parser.parse_args()
    run_self_test()
Code language: Python (python)
```

Run the built-in validation check against our API to reproduce every measurement with your own eyes:

```
export REGOLO_API_KEY="your-regolo-api-key"
python3 piece1_progressive_skills.py --self-test
# Measured output on https://api.regolo.ai/v1 (qwen3.8-27b):
# {
#   "model": "qwen3.8-27b",
#   "skills_scanned": 10,
#   "skill_full_preload_prompt_tokens": 35685,
#   "skill_compact_menu_prompt_tokens": 293,
#   "skill_prefix_reduction_pct": 99.18,
#   "tool_detailed_prompt_tokens": 17794,
#   "tool_concise_prompt_tokens": 753,
#   "tool_response_reduction_pct": 95.77,
#   "turn1_unfiltered_prompt_tokens": 53452,
#   "turn1_unfiltered_latency_s": 7.63,
#   "turn1_piece1_prompt_tokens": 1019,
#   "turn1_piece1_latency_s": 0.79,
#   "turn1_total_reduction_pct": 98.09,
#   "turn1_reply": "There are 8 open issues in this list, and the number of the first issue is 3804.",
#   "turn2_on_demand_skill_loaded": "ab-testing",
#   "turn2_on_demand_prompt_tokens": 3996,
#   "turn2_vs_unfiltered_reduction_pct": 92.52
# }
Code language: Bash (bash)
```

 ZERO DATA RETENTION 

Get engineering notes and model releases in your inbox.

Sovereign AI inference, OpenAI-compatible, EU-hosted. Benchmarks, new models (Mistral, Qwen, GLM), and cost insights. One email, no spam.

✓

Thank you for subscribing!

Please check your inbox to confirm your subscription.

 

   Subscribe Free 

   I accept the [Privacy Policy](https://regolo.ai/privacy-policy/) \*  

    100% European infrastructure · Zero spam · Unsubscribe anytime.

 

## Plug Piece 1 into OpenCode, Claude Code, and Codex (step-by-step setup)

In Section 3 we created `piece1_progressive_skills.py`. To expose those functions to **OpenCode**, **Claude Code**, and **Codex CLI**, we now create a lightweight Model Context Protocol (MCP) server file in the same folder and register it in each agent's configuration file. Follow the five steps below in order.

### Step 1: Create the MCP server file (regolo\_harness\_mcp.py)

In the same folder where you saved `piece1_progressive_skills.py`, create a new file named `regolo_harness_mcp.py` and paste the code below. It uses only the Python standard library to speak JSON-RPC 2.0 over `stdin`/`stdout`, importing `ProgressiveSkillRegistry` and `format_tool_response` from `piece1_progressive_skills.py` and exposing them as two callable MCP tools (`load_skill_on_demand` and `format_concise_tool_output`):

```
#!/usr/bin/env python3
"""regolo_harness_mcp.py: MCP stdio server for OpenCode, Claude Code, and Codex CLI."""
from __future__ import annotations
import json, os, sys
from pathlib import Path
from piece1_progressive_skills import ProgressiveSkillRegistry, format_tool_response

SKILLS_DIR = Path(os.environ.get("REGOLO_SKILLS_DIR", "~/.claude/skills")).expanduser()

TOOLS = [
    {
        "name": "load_skill_on_demand",
        "description": "Load instructions for a named skill only when the current task requires it (progressive disclosure).",
        "inputSchema": {
            "type": "object",
            "properties": {
                "skill_name": {"type": "string", "description": "Exact skill folder name from the AGENTS.md menu."},
                "response_format": {"type": "string", "enum": ["concise", "detailed"], "default": "concise"}
            },
            "required": ["skill_name"]
        }
    },
    {
        "name": "format_concise_tool_output",
        "description": "Strip low-signal metadata (UUIDs, SHA hashes, raw stack traces) from a JSON tool payload.",
        "inputSchema": {
            "type": "object",
            "properties": {
                "raw_json": {"type": "string", "description": "Raw JSON string returned by an external tool."},
                "response_format": {"type": "string", "enum": ["concise", "detailed"], "default": "concise"}
            },
            "required": ["raw_json"]
        }
    }
]

def handle_rpc(req: dict) -> dict | None:
    method, req_id = req.get("method"), req.get("id")
    if method == "initialize":
        return {
            "jsonrpc": "2.0",
            "id": req_id,
            "result": {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "regolo-context-harness", "version": "1.0.0"}
            }
        }
    if method == "tools/list":
        return {"jsonrpc": "2.0", "id": req_id, "result": {"tools": TOOLS}}
    if method == "tools/call":
        params = req.get("params", {})
        name, args = params.get("name"), params.get("arguments", {})
        if name == "load_skill_on_demand":
            registry = ProgressiveSkillRegistry(SKILLS_DIR)
            text = registry.load_skill(args["skill_name"])
            if args.get("response_format", "concise") == "concise":
                text = "\n".join(text.splitlines()[:40])
        elif name == "format_concise_tool_output":
            payload = json.loads(args["raw_json"])
            text = format_tool_response(payload, response_format=args.get("response_format", "concise"))
        else:
            text = f"Unknown tool: {name}"
        return {"jsonrpc": "2.0", "id": req_id, "result": {"content": [{"type": "text", "text": text}]}}
    return None

if __name__ == "__main__":
    if "--self-test" in sys.argv:
        init_ok = handle_rpc({"jsonrpc": "2.0", "id": 1, "method": "initialize"})
        list_ok = handle_rpc({"jsonrpc": "2.0", "id": 2, "method": "tools/list"})
        assert init_ok and list_ok and len(list_ok["result"]["tools"]) == 2
        print("MCP stdio handshake PASSED:", [t["name"] for t in list_ok["result"]["tools"]])
        sys.exit(0)
    for line in sys.stdin:
        if line.strip():
            resp = handle_rpc(json.loads(line))
            if resp is not None:
                sys.stdout.write(json.dumps(resp) + "\n")
                sys.stdout.flush()Code language: Python (python)
```

Make the file executable and run `--self-test` in your terminal to confirm the MCP handshake works:

```
chmod +x regolo_harness_mcp.py
python3 regolo_harness_mcp.py --self-test
# Output: MCP stdio handshake PASSED: ['load_skill_on_demand', 'format_concise_tool_output']Code language: Bash (bash)
```

### Step 2: Configure OpenCode (~/.config/opencode/opencode.json)

Export your Regolo API key (`export REGOLO_API_KEY="your-key"`), open `~/.config/opencode/opencode.json`, and add both our European OpenAI-compatible provider (`https://api.regolo.ai/v1`) and the local `regolo-context-harness` server under the `"mcp"` section (replace `/absolute/path/to/` with the folder where you saved the two Python files):

```
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "regolo": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Regolo (EU Zero Data Retention)",
      "options": {
        "baseURL": "https://api.regolo.ai/v1",
        "apiKey": "{env:REGOLO_API_KEY}"
      },
      "models": {
        "qwen3.8-27b": {
          "name": "Qwen3.8-27B",
          "limit": { "context": 240000, "output": 32000 }
        },
        "glm5.2": {
          "name": "GLM-5.2 (753B MoE)",
          "limit": { "context": 200000, "output": 32000 }
        },
        "gpt-oss-120b": {
          "name": "GPT-OSS 120B (237 tok/s)",
          "limit": { "context": 120000, "output": 16000 }
        }
      }
    }
  },
  "model": "regolo/qwen3.8-27b",
  "small_model": "regolo/gpt-oss-120b",
  "mcp": {
    "regolo-context-harness": {
      "type": "local",
      "command": ["python3", "/absolute/path/to/regolo_harness_mcp.py"],
      "environment": {
        "REGOLO_API_KEY": "{env:REGOLO_API_KEY}",
        "REGOLO_SKILLS_DIR": "/Users/yourname/.claude/skills"
      },
      "enabled": true
    }
  }
}Code language: JSON / JSON with Comments (json)
```

### Step 3: Configure Claude Code (CLI command or project .mcp.json)

In Claude Code, run `claude mcp add` from the folder where you saved `regolo_harness_mcp.py`, then verify the server is connected with `claude mcp list`:

```
# Register the MCP stdio server in Claude Code
claude mcp add --transport stdio regolo-context-harness \
  --env REGOLO_API_KEY="$REGOLO_API_KEY" \
  --env REGOLO_SKILLS_DIR="$HOME/.claude/skills" \
  -- python3 "$(pwd)/regolo_harness_mcp.py"

# Confirm Claude Code sees the server as connected
claude mcp listCode language: Bash (bash)
```

If you want the configuration shared across your team via Git, create a `.mcp.json` file in your repository root instead:

```
{
  "mcpServers": {
    "regolo-context-harness": {
      "command": "python3",
      "args": ["/absolute/path/to/regolo_harness_mcp.py"],
      "env": {
        "REGOLO_API_KEY": "${REGOLO_API_KEY}",
        "REGOLO_SKILLS_DIR": "${HOME}/.claude/skills"
      }
    }
  }
}Code language: JSON / JSON with Comments (json)
```

### Step 4: Configure OpenAI Codex CLI (~/.codex/config.toml)

In Codex CLI, open `~/.codex/config.toml` and add both the Regolo European provider block and the `[mcp_servers.regolo_context_harness]` entry:

```
model = "qwen3.8-27b"
model_provider = "regolo"

[model_providers.regolo]
name = "Regolo EU Zero Data Retention"
base_url = "https://api.regolo.ai/v1"
env_key = "REGOLO_API_KEY"
wire_api = "chat"

[mcp_servers.regolo_context_harness]
command = "python3"
args = ["/absolute/path/to/regolo_harness_mcp.py"]
env = { "REGOLO_API_KEY" = "your-regolo-api-key", "REGOLO_SKILLS_DIR" = "/Users/yourname/.claude/skills" }Code language: TOML, also INI (ini)
```

### Step 5: Generate the 1-line skill menu into AGENTS.md and CLAUDE.md

Finally, run this one-liner in your repository root to append the compact skill index and the on-demand calling rule into `AGENTS.md` (read by OpenCode and Codex CLI) and `CLAUDE.md` (read by Claude Code):

```
python3 -c '
from pathlib import Path
from piece1_progressive_skills import ProgressiveSkillRegistry
menu = ProgressiveSkillRegistry(Path("~/.claude/skills").expanduser()).compact_menu()
rule = """## Progressive skill disclosure & tool output rules
1. Do NOT preload full SKILL.md files into the conversation context.
2. When a task matches a skill below, call the MCP tool:
   load_skill_on_demand(skill_name="<name>", response_format="concise")
3. Pass verbose JSON payloads through format_concise_tool_output(raw_json=..., response_format="concise").

""" + menu + "\n"
for target in ["AGENTS.md", "CLAUDE.md"]:
    with open(target, "a", encoding="utf-8") as f:
        f.write("\n" + rule)
print("Appended compact skill menu to AGENTS.md and CLAUDE.md")
'Code language: Bash (bash)
```

 PRACTICAL INTEGRATION · OPENCODE, CLAUDE CODE &amp; CODEX### How to wire Piece 1 into your daily coding harness

Keep startup skill context at 293 prompt tokens while giving your agent on-demand access to every skill and concise tool output.

 

1. Daily coding agent

2. Harness config to add

3. Verified runtime behavior

 

Agent · OpenCode

~/.config/opencode/opencode.json

Pair with `qwen3.8-27b` or `glm5.2` on `https://api.regolo.ai/v1`

 

→

Local MCP Server

regolo-context-harness

 load\_skill\_on\_demand concise default 

 

→

Outcome · Lean startup

35,685 → 293 tok (-99.18%)

Full skill docs enter context only when called (3,996 tok on Turn 2, -92.52%).

 

 

Agent · Claude Code

claude mcp add CLI

Works alongside local project `CLAUDE.md` files

 

→

One-line registration

claude mcp add regolo-harness

 stdio transport -95.77% tool JSON 

 

→

Outcome · Live GitHub REST API

17,794 → 753 tok (8 issues)

Strips avatar_url, node_id, and nested API URLs from GitHub issue dumps.

 

 

Agent · Codex CLI

~/.codex/config.toml

Point provider base_url at our EU endpoint

 

→

TOML MCP block

[mcp_servers.regolo_harness]

 Qwen3.8-27B 0.79s Turn 1 

 

→

Outcome · End-to-end Turn 1

53,452 → 1,019 tok (-98.09%)

Cuts Turn-1 latency from 7.63s to 0.79s on our EU API.

 

 

 

All four parts of our Context Engineering 101 kit share the same single-file `regolo_harness_mcp.py` server.

**Explore the rest of the Context Engineering 101 series and related guides:** Continue to [**Part 2 (Retrieve, offload, delegate)**](https://regolo.ai/context-engineering-for-agents-101-part-2-retrieve-offload-delegate/) to keep 50k-token tool dumps out of your active window, [**Part 3 (Reversible compaction and prompt-cache-safe memory)**](https://regolo.ai/context-engineering-for-agents-101-part-3-compaction-prompt-cache-memory/), and [**Part 4 (Long-running Initializer, Worker, and Evaluator harnesses)**](https://regolo.ai/context-engineering-for-agents-101-part-4-long-running-agent-harness/). You can also explore our deep dives on [context-mode and headroom](https://regolo.ai/getting-started-context-mode-headroom-regolo/), [persistent codebase memory with ai-memory](https://regolo.ai/getting-started-ai-memory-regolo-persistent-codebase-memory/), [our model comparison hub](https://regolo.ai/compare/), and [autonomous coding in VS Code with Roo Code](https://regolo.ai/roo-code-ai-powered-autonomous-coding-in-vscode/), [Qwen3.8-27B harness engineering for Pi, OpenCode, and Kilo Code](https://regolo.ai/harness-engineering-for-qwen3-8-27b-a-technical-guide-to-pi-opencode-and-kilo-code/), and [IDE and agent integrations](https://regolo.ai/integrations/).

## Frequently asked questions

**What is the difference between prompt engineering and context engineering for AI agents?**
Prompt engineering focuses on phrasing a single instruction, while context engineering manages the entire set of tokens entering and leaving the model window across dozens of turns, including system instructions, skill files, MCP tool schemas, and tool outputs.

**Why do agents lose accuracy even when the model supports a 262K or 1M context window?**
Every additional block of irrelevant instructions or raw UUIDs dilutes the attention budget of the transformer, a phenomenon known as context rot. Keeping the startup prefix lean preserves reasoning precision on later turns.

**How does progressive disclosure work in OpenCode, Claude Code, and Codex?**
Instead of loading full markdown guides for every skill at startup, the harness injects only a one-line name and summary per skill into the system prompt and exposes an on-demand tool so the model reads the full skill file only when a task requires it.

**Why should I pass enable\_thinking=False on routine harness turns with Qwen3.8-27B?**
Reasoning models generate an internal scratchpad by default. Disabling thinking on deterministic formatting or routing calls avoids unnecessary latency and saves output tokens for steps that actually require deep planning.

**Which models on the Regolo API work best with progressive skill disclosure?**
GLM-5.2, Qwen3.8-27B, Qwen3.5-122B, and GPT-OSS 120B all support tool calling over our OpenAI-compatible EU endpoint, and all share the same flat €39/month [Core token pool](https://regolo.ai/pricing/).

    PRODUCTION-READY EU INFERENCE · ZERO DATA RETENTION  OpenAI-Compatible API 

Ship Private AI. Not Infrastructure.

 You have the architecture and the open-source workflow. Now give it a sovereign European inference layer built for production: fast access to **GLM-5.2, Qwen3.8-27B, GPT-OSS 120B, Gemma 4, Mistral**, and **Brick** with zero data retention and no new SDK to learn.

 DROP-IN ENDPOINT `export OPENAI_BASE_URL="https://api.regolo.ai/v1"` Keep your existing SDK &amp; agent setup 

 

  [    30-DAY FREE TRIAL 

Start your 30-day free trial →

Build, test, and deploy with no infrastructure to maintain. Core plans from €11.70/mo (70% off first 3 months).

 ](https://regolo.ai/pricing/)  [    OPEN-SOURCE CODE 

Clone the GitHub repository →

Get the full implementation, configuration scripts, evaluation benchmarks, and ready-to-run templates.

 ](https://github.com/regolo-ai/tutorials/)  [    BUILDER COMMUNITY 

Join the Regolo Discord →

Meet engineers building with coding agents, private RAG, local LLMs, and production open-weight models.

 ](https://discord.gg/bqGrVJHeF)  [    ARCHITECTURE REVIEW 

Talk to an AI Infrastructure Engineer →

Scaling beyond a proof of concept or running regulated EU workloads? Get a tailored architecture and commercial plan.

 ](https://regolo.ai/contacts/) 

 **Private AI should not require a private data center.** We give your team an EU-native path from local experimentation to production-grade inference. 

 [API Docs](https://docs.regolo.ai) · [GitHub](https://github.com/regolo-ai/tutorials/) · [Discord](https://discord.gg/bqGrVJHeF) · [X (@regolo\_ai)](https://x.com/regolo_ai) · [Reddit](https://www.reddit.com/r/regolo_ai/) · [Contact](https://regolo.ai/contacts/) 

Built by the Regolo team · 100% EU Sovereign GPU