Training Hands-on · Five Modules
M00 / 01

TechDays AI Agents

AGENTS.md · Commands · Skills · Plugins · MCP: the five layers for configuring an AI coding agent, from a single instruction file to live external tools.

Extension Layers One Mental Model
Presenter Daniel Bodnar
Reference tool Claude Code · open standards noted
Materials Lab Workbook · Lesson Plan
Runtime ~140 min · break included
M00 · WelcomeFundamentals
M00 / 02

Before any configuration

An agent is a model in a loop:
instructions, tools, context.

01 · Instructions What it should do

System prompts, your AGENTS.md, skills. Everything this session teaches lives in this layer or feeds it.

02 · Tools What it can call

File edits, shell, and (through MCP) anything you connect: ticket systems, databases, browsers.

03 · Context What it knows now

The finite window holding the conversation, files, and tool results. Every extension you add pays rent here.

No magic anywhere in this session: just these three, configured deliberately.

Recurring questionwhich layer does this belong in?
M00 · Welcome
M00 · WelcomeThe Map
M00 / 03

Five layers form one mental model.

M01 · Always loaded AGENTS.md

One file at repo root. The agent's baseline knowledge of your codebase.

15 min
M02 · Invoked Commands

The / menu: built-ins worth knowing, and what custom commands really are.

15 min
M03 · On demand Skills

Procedural knowledge that loads only when the task matches. The core of the day.

30 min
M04 · Packaged Plugins

Versioned, namespaced distribution, to your team and from the marketplaces.

20 min
M05 · Connected MCP

Live tools and data from outside the agent: tickets, databases, browsers.

30 min

Files first, connections last: each layer builds on the one before it. Break after Module 03.

Arcalways-loaded → invoked → on-demand → packaged → connected
M00 · Welcome
M00 · WelcomeFollowing Along
M00 / 04

Ground rule

This is hands-on.
Open a terminal.

Every module ends with a checkpoint from the Lab Workbook. The workbook is self-contained: anyone who misses the session can work through it alone.

Vendor note: the reference tool is Claude Code. AGENTS.md, Agent Skills, and MCP are open standards, so those modules transfer to Cursor, Codex, Gemini CLI, OpenCode, and others.

Verify now

# 1 · agent installed and current $ claude --version # 2 · authenticated $ claude # 3 · Node 18+ (Module 05 stdio servers) $ node --version # 4 · a real repo to experiment in $ git status
Stuck?workbook has a troubleshooting table per module
M00 · Welcome
Module 01
M01 / 05
01

AGENTS.md

The agent starts every session knowing nothing about your repository. One markdown file fixes that: the cheapest, highest-leverage configuration you will write today.

LayerAlways loaded · baseline context
StandardOpen, cross-vendor (agents.md) · Claude Code reads CLAUDE.md
Hands-on/init · edit · symlink · checkpoint
WorkbookTutorial 01
M01 · AGENTS.md
M01 · AGENTS.mdThe Instruction File
M01 / 06

One file, read automatically

It carries operating instructions,
not documentation.

A README explains the project to humans. AGENTS.md tells an agent how to operate: exact commands, conventions, prohibitions, and where the deeper docs live.

It loads on every session, which is both its power and its budget. Every line pays context rent whether the session needs it or not.

Cross-vendor: most agents read AGENTS.md natively. Claude Code reads CLAUDE.md; keep AGENTS.md canonical and symlink.

The shape that works

AGENTS.md## Commands - Build: `bun run build` - Test one file: `bun test path/to/x.test.ts` - Lint + fix: `bun run lint --fix` ## Conventions - Use internal `@acme/http` — never raw fetch() - Money is integer cents. Never floats. ## Do not - Touch `src/generated/` — codegen owns it - Add dependencies without flagging in the PR
Test per line"would the agent get this wrong without it?"
M01 · AGENTS.md
M01 · AGENTS.mdWhat Goes In
M01 / 07

Every line costs context
in every session.

Belongs in What every session needs

Build, test, and lint commands, exactly as your team runs them. House conventions an outsider couldn't guess. Internal libraries to prefer. Directories never to touch. Pointers to deeper docs.

Stays out Everything else

Anything the model already knows (what a PDF is, how git works). Prose essays. And procedures: the moment a section becomes step-by-step instructions for an occasional task, it belongs in a skill (Module 03).

Monorepos: nested AGENTS.md per package; the closest file wins. Keep the root file global, push specifics down.

Rule of thumbmost first drafts shrink by a third on audit
M01 · AGENTS.md
M01 · AGENTS.mdHands-on
M01 / 08

Generate, then edit critically.

  • Step 01
    /init writes a draft
    Claude explores the repo and writes a starting CLAUDE.md. It's a bootstrapper, not a deliverable; verify every command it guessed.
  • Step 02
    Add what only your team knows
    The valuable content is in your head, not the file tree: conventions, banned patterns, the directory codegen owns.
  • Step 03
    Make it cross-vendor
    mv CLAUDE.md AGENTS.md && ln -s AGENTS.md CLAUDE.md: one source of truth, every agent reads it.
  • Step 04
    /memory when it drifts
    Edits the file in-session. An AGENTS.md that lies is worse than none, because the agent trusts it completely.
✓ Checkpoint Fresh session: "What test command should you use here, and which directories are off-limits?" Answered from the file, without searching.
WorkbookTutorial 01 · exercises + troubleshooting
M01 · AGENTS.md
Module 02
M02 / 09
02

Commands

Everything behind the / key is one of two things: a built-in command, or a skill. Fluency with the first; a door into the second.

LayerInvoked · the interface to everything else
ScopeClaude Code's command set · concepts transfer
Hands-onthe working set · /context · a custom command
WorkbookTutorial 02
M02 · Commands
M02 · CommandsTwo Kinds
M02 / 10

Behind the slash sits
fixed logic or a prompt.

Built-in commands Fixed logic

Shipped with the tool: /clear, /permissions, /mcp, /config. They manage the session and the machinery around it. You can't write these, but the next slide's working set is worth memorizing.

Skills Prompt-based

Everything else: every custom command you'll ever write, plus the bundled ones like /debug and /batch. Extensible, shareable, and the subject of Module 03.

Type / and read your own list; entries vary by platform and plan. MCP servers add a third source later: /mcp__server__prompt.

Deprecation note/review is now a plugin: code-review@claude-plugins-official
M02 · Commands
M02 · CommandsThe Working Set
M02 / 11

Nine commands are
worth memorizing.

CommandWhat it does
/contextColored-grid view of what's filling the window. Run it after every module today.
/permissionsAllow / ask / deny rules for tools: the guardrail surface.
/mcpServer status, tool counts, OAuth. Module 05 home base.
/compactSummarize the conversation to free space; keeps the thread.
/clearWipe and start fresh; cheaper when you don't need the thread.
CommandWhat it does
/rewindRoll back conversation and/or code. The undo most people don't know exists.
/skillsList every skill currently available. Module 03 home base.
/modelSwitch model; configure effort.
/doctorDiagnose installation and settings. First stop when anything misbehaves.
…plus /init and /memory from Module 01.
Demo/context · find your AGENTS.md in the grid
M02 · Commands
M02 · CommandsCustom Commands
M02 / 12

The pivot to Module 03

A custom command
is a skill.

Drop a folder in .claude/skills/, restart, and /standup exists. The !`…` line runs before the model reads the prompt: its output is injected into the text.

The legacy form (a flat file in .claude/commands/) still works, but skills win name conflicts and are the form to write going forward.

✓ Checkpoint Your /standup runs, and you can explain where its git log came from.

.claude/skills/standup/SKILL.md

--- description: Summarize my recent work as a standup update. Use when asked for a standup. --- Summarize the last day of git history by the current author as three bullets: done, in progress, blocked. !`git log --author="$(git config user.name)" --since=yesterday --oneline`
Arguments$ARGUMENTS · $1 · argument-hint · Tutorial 02, exercise 2
M02 · Commands
Module 03
M03 / 13
03

Skills

Procedural knowledge the agent loads only when the task matches. The open standard, the anatomy, and how to write skills that actually work. The core of the session.

LayerOn demand · pay context only when used
StandardAgent Skills (agentskills.io) · adopted by 20+ agents
Hands-onwrite · place · trigger · tune · publish
WorkbookTutorial 03 · break afterwards
M03 · Skills
M03 · SkillsThe Economics
M03 / 14

Why skills exist

AGENTS.md loads always.
A skill loads when relevant;
until then it costs ~100 tokens.

At startup the agent sees only each skill's name and description. The body (up to ~5k tokens of instructions, plus unlimited referenced files) enters context only when a task matches. That asymmetry is the entire design.

Ruleevery session needs it → AGENTS.md · some sessions need it → skill
M03 · Skills
M03 · SkillsProgressive Disclosure
M03 / 15

Skills load in three stages,
on three budgets.

Stage 01 · ~100 tokens Discovery

At startup, only the name and description of every installed skill load. The description is the trigger: it decides everything downstream.

always in context
Stage 02 · <5k tokens Activation

A task matches the description; the full SKILL.md body enters context. Keep it under 500 lines: concise steps, one worked example.

on match
Stage 03 · as needed Execution

The agent follows the instructions, running bundled scripts and reading referenced files only when the work calls for them.

scripts/ · references/

For big skills, push depth down a stage: move detail into references/ and tell the agent when to read each file: "Read references/api-errors.md if the API returns non-200."

Specagentskills.io/specification
M03 · Skills
M03 · SkillsAnatomy
M03 / 16

.claude/skills/money-handling/SKILL.md

--- name: money-handling description: Conventions for money values in this codebase. Use when writing or reviewing code that handles prices, payments, refunds, or currency. --- # Money handling - All monetary values are integer cents. Never floats, never strings. - Construct with Money.fromCents() from @acme/money. ## Gotchas - Legacy orders.total_price is DECIMAL dollars — convert at the boundary, nowhere else.

Two fields
carry the system.

  • name
    Lowercase, hyphenated, ≤64 chars, and it must match the folder name.
  • description
    What it does and when to use it, ≤1024 chars, with the trigger words of the task. The only thing the model sees before activating.
  • body
    Plain markdown. Steps, one example, a Gotchas section. No schema.

"Helps with PDFs" never triggers. "Extracts text and tables from PDF files — use when working with PDF documents" does.

Validateskills-ref validate ./my-skill
M03 · Skills
M03 · SkillsControl Surfaces
M03 / 17

Who invokes it: you, the model, or both.

FrontmatterWho can invokeUse for
(default) You and the model Most skills: conventions, procedures, reference knowledge.
disable-model-invocation: true Only you, via /name Side effects: /deploy, /commit, /release. The model never decides to run these on its own.
user-invocable: false Only the model Background knowledge, hidden from the / menu entirely.

Claude Code extensions, same file: $ARGUMENTS and named arguments, !`command` pre-injection, context: fork to run in a subagent, allowed-tools to pre-approve tools while the skill is active.

Vendor noteClaude Code superset · name + description are portable
M03 · Skills
M03 · SkillsScopes
M03 / 18

The most specific scope
wins the name.

Scope 01 · org Enterprise

Pushed through managed settings. Wins all name conflicts; the org's rules are not optional.

admin-controlled
Scope 02 · you Personal

Your habits, every project you open. Yours beats the repo's on a name collision.

~/.claude/skills/
Scope 03 · repo Project

Committed to version control, so the whole team gets it on clone. Where team conventions live.

.claude/skills/

Edits to an existing SKILL.md apply live in the session. New top-level folders need a restart. Plugin skills (Module 04) are namespaced: they never collide.

Monoreponested .claude/skills/ discovered on demand
M03 · Skills
M03 · SkillsWriting Skills That Work
M03 / 19

Write from scar tissue,
not from imagination.

  • Source
    Start from real expertise
    Your last ten code-review comments, a runbook, an incident report. Generated skills without domain context produce filler: "handle errors appropriately" helps no one.
  • Budget
    One test per line
    "Would the agent get this wrong without this?" If no, delete it. A default beats a menu: name one library, not five options.
  • Gotchas
    The highest-value section
    Concrete facts that defy assumptions: "the /health endpoint returns 200 even when the queue is down." Add one every time you correct the agent.
  • Iterate
    Execute, then revise (once)
    Run it on a real task and read the trace, not just the output. Wandering means vague instructions; ignored sections mean cut them.
Senior materialagentskills.io/skill-creation/best-practices
M03 · Skills
M03 · SkillsScripts & Ecosystem
M03 / 20

Bundled scripts

Your operator
is an agent.

A script that asks "Continue? [y/N]" hangs forever, because agents can't answer prompts. Design accordingly:

  • ·
    Flags and env vars only; missing input → clear error + usage
  • ·
    Structured output on stdout; diagnostics on stderr
  • ·
    Idempotent, because agents retry; --dry-run for anything destructive
  • ·
    One-offs: pin versions (npx eslint@9 · uvx ruff@0.8.0 · bunx)

The skills directory

One folder works
in twenty agents.

$ npx skills add anthropics/skills # installs across Claude Code, Cursor, Codex, # Copilot, Gemini CLI, OpenCode, …

skills.sh is the public directory: trending lists, official collections, and security audits. Worth knowing: skill-creator (Anthropic's skill for writing skills) and the document skills (pdf, docx, xlsx, pptx).

✓ Checkpoint A project skill that triggers on natural language, a user-only skill, one community skill installed, and you can name the three context budgets.
Breakten minutes after this checkpoint
M03 · Skills
Module 04
M04 / 21
04

Plugins

A skill in .claude/skills/ serves one repo. A plugin packages skills (plus hooks, subagents, and MCP configs) into a versioned, namespaced unit you can install anywhere.

LayerPackaged · distribution and versioning
ScopeClaude Code mechanism · contents stay portable
Hands-onbuild one · install from the marketplace
WorkbookTutorial 04
M04 · Plugins
M04 · PluginsStandalone vs Plugin
M04 / 22

Start standalone,
then convert when you share.

Standalone · .claude/ One repo, fast iteration

Personal or project-specific. Short names like /standup. Commit the folder and same-repo teammates already share it. Quick experiments live and die here, cheaply.

Plugin Cross-repo, versioned, namespaced

Deliberate releases via semver, or every commit ships, SHA-versioned. Names become /team-standards:standup: no collisions with anyone else's /standup. Installable by people who've never seen your repo.

The conversion is mechanical: a manifest file plus your existing folders. The decision is organizational: who else needs this, and how do they get updates?

Same-repo teamcommit .claude/skills/; a plugin is overkill
M04 · Plugins
M04 · PluginsAnatomy
M04 / 23

team-standards/

team-standards/ ├── .claude-plugin/ │ └── plugin.json ← manifest, NOTHING else here ├── skills/ │ └── money-handling/ │ └── SKILL.md ├── hooks/hooks.json ← optional ├── agents/ ← optional └── .mcp.json ← optional plugin.json{ "name": "team-standards", "description": "Acme conventions", "version": "0.1.0" }

Only the manifest
lives inside.

The #1 structural mistake, per the official docs: putting component directories inside .claude-plugin/. Only the manifest lives there.

name is the namespace. version pins releases: omit it and the git SHA versions every commit.

Paths inside the plugin: always ${CLAUDE_PLUGIN_ROOT}, because the install directory moves on update.

Validateclaude plugin validate ./team-standards
M04 · Plugins
M04 · PluginsThe Dev Loop
M04 / 24

The dev loop is
four commands.

  • scaffold
    claude plugin init my-tool
    Generates the manifest and folder structure, with components in the right places.
  • test
    claude --plugin-dir ./team-standards
    Loads the plugin from disk for this session. Confirm the namespaced skill appears in /skills.
  • iterate
    /reload-plugins
    Picks up edits without restarting the session.
  • ship
    claude plugin validate · git push
    Validate structure, push to a git repo; that repo can itself be a marketplace.
✓ Checkpoint Your skill responds at /team-standards:money-handling, and `claude plugin details` shows nothing unexpected in the always-on token column.
Debugclaude --debug · /plugin Errors tab
M04 · Plugins
M04 · PluginsMarketplaces
M04 / 25

Install from catalogs:
three kinds are worth knowing.

Catalog 01 Language servers

pyright, gopls, rust-analyzer, typescript… The agent sees type errors after every edit (no compile step) and navigates by symbol instead of grep.

binary on PATH required
Catalog 02 Integrations

GitHub, GitLab, Linear, Sentry, Figma, Supabase: plugins that bundle a pre-configured MCP server. The cleanest way to hand a team a connection.

bundled .mcp.json
Catalog 03 Workflows

commit-commands, pr-review-toolkit, and code-review (the replacement for the deprecated /review built-in).

skills + agents

Browse with /plugin. Install scopes: user (all your projects) · project (committed, team-shared) · local (this repo, just you) · managed (pushed by admins). Team catalogs: /plugin marketplace add acme-org/claude-plugins.

Securityplugins run arbitrary code with your privileges; curate sources
M04 · Plugins
M04 · PluginsBeyond Skills
M04 / 26

A plugin can carry
six component types.

ComponentFileAdds
Skillsskills/*/SKILL.mdEverything from Module 03, namespaced.
Hookshooks/hooks.jsonChecks at ~30 lifecycle events; PreToolUse can block a call before it runs.
Subagentsagents/*.mdSpecialized agents with their own tools, model, and isolation.
MCP servers.mcp.jsonConnections that start when the plugin is enabled (Module 05).
LSP.lsp.jsonLive diagnostics and code navigation.
PATH toolsbin/Executables available to the agent's shell while enabled.

Today you ship skills. The rest are pointers; each is a tutorial of its own.

Referencecode.claude.com/docs · plugins-reference
M04 · Plugins
Module 05
M05 / 27
05

MCP Servers

Everything so far has been files the agent reads. MCP adds connections: typed tools and live data from the systems around your code.

LayerConnected · tools and live data
StandardModel Context Protocol (modelcontextprotocol.io) · open
Hands-onadd remote · add local · scope · verify · debug
WorkbookTutorial 05
M05 · MCP
M05 · MCPThe Signal
M05 / 28

When to reach for MCP

The moment you catch yourself
copy-pasting from another tool
into the chat.

Tickets, error traces, database rows, design specs: if you ferry it by hand, a server can hand it to the agent directly. Skills carry knowledge; MCP carries capability. They compose: this module ends with skills that build MCP servers.

Exerciselist your three most-pasted sources; that's your server shortlist
M05 · MCP
M05 · MCPAdding Servers
M05 / 29

Servers speak remote HTTP
or local stdio.

Remote · HTTP

$ claude mcp add --transport http \ claude-code-docs \ https://code.claude.com/docs/mcp # add · transport · your name · url

Cloud services: docs, Sentry, GitHub, Notion. Zero install; OAuth where needed.

Local · stdio

$ claude mcp add playwright -- \ npx -y @playwright/mcp@latest # no --transport flag (stdio is default) # the bare -- separates Claude's flags # from the server's own command line

Local processes: browsers, filesystems, databases. The missing -- is the #1 add-time failure.

Verify with claude mcp list: five statuses from ✓ Connected to ⏸ Pending approval. First tool use prompts for permission; calls are labeled with the server name. SSE transport is deprecated.

First-run notestdio may show "failed" while npx downloads; retry once
M05 · MCP
M05 · MCPScopes
M05 / 30

Who gets this server?

ScopeLives inWho sees it
local~/.claude.json (per-project)You, this project. The default.
project.mcp.json at repo rootThe whole team; committed, approval-gated.
user~/.claude.json (top level)You, every project.

Scope is fixed at add time: changing it means remove and re-add with --scope.

.mcp.json · no secrets, ever

{ "mcpServers": { "github": { "type": "http", "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer ${GITHUB_PAT}" } } } }

${VAR} expansion keeps keys out of version control; teammates get an approval prompt before anything launches.

OAuth servers/mcp → Authenticate → browser · tokens auto-refresh
M05 · MCP
M05 · MCPCost & Trust
M05 / 31

Every server costs context.
Some cost trust.

The context bill Run /context, then decide

Tool Search keeps the bill down by default: full schemas load on demand, not at startup. Output is capped (MAX_MCP_OUTPUT_TOKENS, default 25k). The cheapest mitigation: claude mcp remove for servers you stopped using.

The trust bill Content can carry instructions

A server that fetches external content (web pages, tickets, emails) can carry prompt injection in that content. Treat server trust like dependency trust: prefer official and curated servers for anything that touches credentials.

✓ Checkpoint A remote and a local server both ✓ Connected, one tool exercised from each, and you can say what they cost in /context.
Triage tableTutorial 05 · from "No servers configured" to reset-project-choices
M05 · MCP
M05 · MCPBuilding & Publishing
M05 / 32

The standards compose

Skills can
build servers.

> /plugin install mcp-server-dev@ claude-plugins-official > Build an MCP server for our internal weather API

Three composing skills interview you (what it connects to, who uses it, how it authenticates) and then scaffold the right deployment shape: remote HTTP for cloud APIs, a bundle for local machine access, stdio for prototypes.

Watch-only today

Publishing goes through
the registry.

$ npm publish --access public $ mcp-publisher init $ mcp-publisher login github $ mcp-publisher publish

The registry holds metadata, not code: your package still lives on npm, with an mcpName field tying the two together.

Full circleskills build MCP servers · plugins distribute both
M05 · MCP
M06 · CloseThe Layer Model
M06 / 33

One question routes everything:
which layer does this belong in?

"I want the agent to…"LayerWhy
know our build commandsAGENTS.mdEvery session needs it.
follow our review checklist on requestSkillSome sessions need it; pay on use.
never run deploys on its ownSkill · user-onlydisable-model-invocation, plus /permissions.
give the whole org our conventionsPluginVersioned, namespaced, installable.
read tickets without copy-pasteMCP serverCapability, not knowledge.
Mnemonicalways-loaded · invoked · on-demand · packaged · connected
M06 · Close
M06 · CloseHomework
M06 / 34

Three steps that compound

One AGENTS.md,
one skill from a real correction,
and one server you'll actually use.

In that order, on one real repo, this week. The AGENTS.md takes twenty minutes. The skill comes from your last code review. The server comes from your copy-paste audit.

Anti-goalinstalling ten plugins you never open again
M06 · Close
M06 · CloseResources & Q&A
M06 / 35

Resources

Docs code.claude.com/docs

Commands, skills, plugins, MCP: the reference for everything in Modules 02–05.

also: an MCP server of itself
Standard agentskills.io

The Agent Skills spec, best practices, and script guidance.

open standard
Directory skills.sh

Community skills with install counts and security audits.

npx skills add <owner/repo>
Standard modelcontextprotocol.io

The MCP spec, registry, and server-building guides.

spec · registry · sdks
Standard agents.md

The cross-vendor instruction-file convention from Module 01.

CLAUDE.md → AGENTS.md
This course Lab Workbook

All five tutorials with checkpoints, exercises, and troubleshooting; self-contained for anyone who missed today.

share freely
Q&ADaniel Bodnar
M06 · Close