Get the first paragraph of a city's Wikipedia article
This is the smallest useful agent: one public page, one read-only tool, and everything else denied. It came from a recording of looking up Hanoi on Wikipedia, and Ditto AI installed it into Claude Code as a skill with its own MCP config and allowlist. It's the quickest way to see exactly what Ditto hands to Claude Code.
What it does
Ask for a city and it returns the first paragraph of that city's English Wikipedia article. Nobody needs an agent for this, which is the point: with nothing interesting in the task, what's left to look at is what Ditto produces.
The steps, as Ditto listed them
When this runs: "A request comes in for the Wikipedia summary of a city."
| # | Step | Tool it must use |
|---|---|---|
| 1 | navigate | the headless browser: open https://en.wikipedia.org/wiki/Hanoi |
| 2 | execute | Wikipedia |
Success, as recorded: the first paragraph of the Hanoi article, starting "Hanoi … is the capital and second-most populous centrally-governed city of Vietnam."
The recording used Hanoi, and the exported steps name Hanoi's page. The trigger is written for any city; whether another city's page gets opened is up to the model running the skill, since the export pins the page it saw.
What Ditto installed into Claude Code
A folder under ~/.claude/skills/ with three files.
SKILL.md, the procedure. Its header says where it came from:
---
name: get-first-paragraph-of-a-city-s-encyclopedia-article
description: Get first paragraph of a city's encyclopedia article. Derived from 1 observed runs; not written by hand.
---mcp.json, the one tool server it needs: a headless Chrome through the Playwright MCP server, isolated, with a normal Chrome user agent so sites don't answer with a bot wall.
{ "mcpServers": { "browser": { "command": "npx", "args": ["-y", "@playwright/mcp@latest",
"--browser", "chrome", "--headless", "--isolated", "--user-agent", "…"] } } }ditto-run.json, the allowlist and where the agent came from:
"allowedTools": ["Read", "mcp__browser"],
"understudy": { "derived_from": ["screen"], "episodes": 1,
"policy_derived_by": "deterministic-table-lookup", "authored_by_human": false }The permission policy
ALLOW Wikipedia read
DENY *A public page is always read-only. The agent gets the browser and nothing else, and policy_derived_by says honestly that no model and no person chose that scope: it's a lookup in a fixed table.
When Ditto runs the agent in Claude Code, it hands mcp.json to Claude Code as the run's MCP config and the list above as its --allowedTools, so any tool not on the list is refused.
Why start with something this small
Because it answers the questions a developer asks first, without any account in the way: what files appear, what the skill says, which MCP server gets attached, and what the allowlist contains. Once that looks right, record a task that uses your real tools. Ditto AI with Claude Code covers the install and the run.