- Published on
Build Your Own Claude Code Skill — A Hands-On Deep Dive Into SKILL.md, Invocation, and Distribution (2026, english)
- Authors

- Name
- Youngju Kim
- @fjvbn20031
Prologue — "Am I pasting this same instruction again?"
After a month or two with Claude Code, every user hits the same realization.
You keep pasting the same instructions into chat. "Use conventional commits when making PRs." "Format release notes our team's way." "Only merge after tests pass and the build is green." It works the first two times, but the fifth time the same procedure goes into the prompt, the question forms — am I supposed to type this every time?
Why not put it in CLAUDE.md? Partly correct. The problem is that CLAUDE.md is global and always loaded, so the procedure rides along on every task. Tokens cost something, and more importantly procedures unrelated to the current task pull on the model's attention. A 70-line PR checklist sits in memory even during a one-line typo fix.
Anthropic answered this in October 2025. Agent Skills. The name sounds grand but the substance is small — one directory holding one SKILL.md. Write a description in the frontmatter, and the model decides on its own whether the Skill is relevant to the current task. It is not always loaded — it enters context only when invoked. Check the same directory into git and the entire team shares the procedure.
In December 2025 Anthropic went one step further and made Skills an open standard. The same SKILL.md format works in Claude.ai, Claude Code, the Agent SDK, and the API. OpenAI's Codex CLI and several third-party tools adopted the same spec. The format has effectively become the lingua franca for an "agent capability unit" expressed as Markdown plus YAML.
As of May 2026, a healthy team typically carries a catalog of 30 to 50 Skills. Distribution is either a git push or a plugin marketplace install. This post is for someone writing their first Skill. We will lay out exactly what happens — every SKILL.md field, the invocation model, the directory layout, distribution, and a hands-on build of a release-notes-from-git-log Skill from empty directory to working Skill.
1. What exactly is a Skill
A one-line definition: one directory containing a SKILL.md (YAML frontmatter plus markdown instructions) and, optionally next to it, scripts and reference files.
The smallest possible Skill looks like this.
---
name: pr-summary
description: Summarize the current PR's changes and surface risks. Use when the user asks to review a PR, check what changed before merging, or wants a pre-merge sanity check.
---
## Task
Read the current PR diff and produce a summary in this format:
1. Intent of the change (two to three sentences)
2. New dependencies or configuration introduced
3. Risk areas — missing error handling, hardcoded values, tests that need updating
End with a single-line verdict: "ship it / needs review / hold".
That is the whole thing. Save it at ~/.claude/skills/pr-summary/SKILL.md and starting from the next session, when the user says "take a look at my PR" Claude reads the description and invokes the Skill automatically. Or the user can type /pr-summary for the same effect.
What a Skill unlocks
- Encapsulation of repeated procedures. You stop pasting the same instruction every time.
- Lazy loading. Only the description sits in the catalog; the body enters context at invoke time. Tokens are cheap.
- Named invocation.
/skill-nametriggers it deterministically when you want. - Shareability. Check into git, and every teammate runs the same procedure.
What a Skill is not
- Not an MCP server. No external process. No JSON-RPC. It is a text file.
- Not a fine-tune. The model is unchanged; only how context is injected differs.
- Not a hardcoded function. The body is natural-language instruction, interpreted by the model. The same Skill may behave slightly differently each invocation.
Where Skills sit inside Claude Code
Claude Code already had several extension points — Custom Commands (slash commands), Subagents (.claude/agents/), MCP servers, Plugins, CLAUDE.md. Skills arrived and absorbed Custom Commands, and have become the most-used extension unit. A file at .claude/commands/foo.md and a Skill at .claude/skills/foo/SKILL.md both create /foo — they compete for the same slot. Skills have richer features (their own directory, automatic invoke, bundled scripts), so new work goes into Skills.
2. The SKILL.md format — every field laid out
The single most confused topic, so all fields in one place. Every field is optional, but in practice description is mandatory.
---
name: my-skill
description: One sentence on what this Skill does and when to use it.
when_to_use: If description was not enough, add trigger phrases and example requests.
argument-hint: "[issue-number]"
arguments: [issue, branch]
disable-model-invocation: false
user-invocable: true
allowed-tools: Read Grep Bash(git *)
model: inherit
effort: high
context: fork
agent: Explore
paths: ["src/**/*.py", "tests/**/*.py"]
shell: bash
hooks:
PreToolUse:
- matcher: "Bash"
command: "echo running bash"
---
Free-form markdown body. The entire body enters context when invoked.
What each field means:
| Field | Meaning | Used often? |
|---|---|---|
name | Display name. Defaults to the directory name. Lowercase, digits, hyphens; max 64 chars. | Sometimes |
description | What it does, when to use it. The single most important signal for the model's invoke decision. | Almost always |
when_to_use | Trigger phrases and examples that did not fit in description. | Sometimes |
argument-hint | Autocomplete hint, e.g. [name]. | Often |
arguments | Named positional arguments. With arguments: [a, b] the body uses $a, $b. | Often |
disable-model-invocation | true means only the user can invoke. Recommended for any command with side effects (/deploy, /commit). | Frequently |
user-invocable | false hides from the / menu. For background knowledge Skills. | Sometimes |
allowed-tools | Tools pre-approved while this Skill is active. | Frequently |
model | Override model for this Skill. inherit is safest. | Sometimes |
effort | Reasoning effort level (low to max). Use high or above for precision work. | Sometimes |
context: fork | Run in a forked subagent context, isolated from chat history. | Often |
agent | When context: fork, which subagent type to use (Explore, Plan, general-purpose). | Often |
paths | Glob patterns. Auto-invoke is only considered when the active file matches. | Sometimes |
shell | bash or powershell. Meaningful on Windows. | Rarely |
hooks | Hooks scoped to this Skill's lifecycle only. | Sometimes |
Writing a good description — the single most important line
The description is the search key matched against the user's utterance. Properties of a good description:
- What it does — "Summarizes PR changes and surfaces risks."
- When to use it — "When the user asks about changes, requests a commit message, or wants a diff review."
- Keywords the user is actually likely to say — "PR", "changes", "diff", "review".
Bad: description: A nice tool. The model has no signal about when to fire.
Good: description: Commits the staged changes following conventional commit rules. Use when the user asks to commit, save changes, or wrap up a unit of work.
The combined description + when_to_use is exposed in the catalog up to 1,536 characters. Put the critical keywords up front so they survive any truncation.
String substitution — $ARGUMENTS and friends
A handful of placeholders let you inject dynamic values into the body.
$ARGUMENTS— full argument string typed at invoke.$ARGUMENTS[0]or$0— the first positional argument.$name— a named argument declared viaarguments: [name].${CLAUDE_SESSION_ID}— current session ID.${CLAUDE_EFFORT}— current effort level.${CLAUDE_SKILL_DIR}— the directory containing this SKILL.md. Essential when referring to bundled scripts.
Dynamic context injection — run shell before the model sees anything
If the body contains an inline-code line that starts with !, the command is run before Claude reads the Skill, and its output is inlined into the body. For multi-line cases, open a fenced code block with !.
## Current changes
!`git diff HEAD`
## PR information
```!
gh pr view --json title,body,labels
gh pr diff --name-only
```
## Task
Write the release notes based on the information above.
This pattern is enormously powerful — the model does not need to call a tool to "show me the diff," and the run always starts from facts, because the actual state at invocation time is inlined into the body.
3. The invocation model — when does Claude call a Skill
The most common question, with two answer paths.
Path 1: explicit invocation by the user. /skill-name [args]. Picking from the menu is equivalent. This path always works.
Path 2: automatic invocation by the model. At session start every Skill's name + description (+ when_to_use) is loaded into the model's context as a catalog. When the user speaks, the model scans the catalog and fires the matching Skill.
Automatic invocation requires:
disable-model-invocation: trueis not set on the Skill.- The description semantically matches the user's utterance.
- If
pathsis set, the file in focus matches one of the globs.
"My Skill is not firing" — debugging checklist
The single most likely complaint. Run through:
- Does the description contain keywords the user is likely to say?
- Does the Skill show up under
What skills are available? - Has the catalog overflowed its budget and been truncated? Run
/doctor. - Is another Skill scoring higher on this utterance?
- Does the name collide with a legacy file in
.claude/commands/?
"My Skill fires too often"
The opposite is just as common. An overly generic description nominates the Skill for every utterance.
- Tighten the description.
- For anything with side effects, set
disable-model-invocation: true. - Use
pathsto narrow the trigger surface.
4. Directory layout and where Skills live
A Skill is one directory. There are four homes.
| Scope | Path | Applies to |
|---|---|---|
| Enterprise | Distributed via managed settings | Entire organization |
| Personal | ~/.claude/skills/<name>/SKILL.md | All your projects |
| Project | .claude/skills/<name>/SKILL.md | This project only |
| Plugin | <plugin>/skills/<name>/SKILL.md | Wherever the plugin is enabled |
When names collide, Enterprise wins over Personal wins over Project. Plugin Skills live in a plugin-name:skill-name namespace, so they do not collide with the rest.
Files inside the directory
The smallest Skill is one file. Once the body grows or supporting assets are needed, additional files sit in the same directory.
release-notes/
├── SKILL.md # Required. Entrypoint.
├── template.md # Output template referenced by SKILL.md.
├── examples/
│ ├── good.md # Example output 1
│ └── bad.md # Example output 2 (counter-example)
├── references/
│ └── changelog-spec.md # Detailed reference, e.g. Keep a Changelog spec
└── scripts/
└── collect.sh # Shell script invoked from SKILL.md
To reference another file from the body, write it explicitly so the model knows what it contains and when to load it.
## Additional resources
- Full output format: see `template.md`.
- Good example: `examples/good.md`. Counter-example: `examples/bad.md`.
- Changelog spec details: `references/changelog-spec.md`.
## Data collection
```!
bash ${CLAUDE_SKILL_DIR}/scripts/collect.sh
```
The rule of thumb: keep SKILL.md under 500 lines and push longer material into references/. Once invoked, the SKILL.md body sits in context for the rest of the session — every line is a recurring token cost.
5. Hands-on — building release-notes-from-git-log end to end
Now we build a real Skill. The goal is concrete — examine commits since the last git tag and generate a Keep a Changelog-formatted release notes section. It is one step deeper than a PR summary and lets us exercise arguments, dynamic context, helper scripts, and a template.
Step 1: create the directory
mkdir -p ~/.claude/skills/release-notes/{scripts,references,examples}
cd ~/.claude/skills/release-notes
Step 2: helper script — collect commits since last tag
Save as scripts/collect.sh.
#!/usr/bin/env bash
set -euo pipefail
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [[ -z "$LAST_TAG" ]]; then
echo "## No previous tag — full log"
git log --pretty=format:"- %h %s (%an)" --no-merges
else
echo "## Last tag: $LAST_TAG"
echo ""
echo "## Commits since"
git log "${LAST_TAG}..HEAD" --pretty=format:"- %h %s (%an)" --no-merges
echo ""
echo "## Merge commits since"
git log "${LAST_TAG}..HEAD" --merges --pretty=format:"- %h %s"
echo ""
echo "## Diff stats summary"
git diff --stat "${LAST_TAG}..HEAD" | tail -1
fi
Make it executable.
chmod +x scripts/collect.sh
Step 3: output template
Save as references/template.md. Skeleton aligned with Keep a Changelog 1.1.
## [VERSION] - YYYY-MM-DD
### Added
- New, user-visible additions only.
### Changed
- Changes to existing behavior. Non-breaking changes go here.
### Deprecated
- Marked for removal in the next major.
### Removed
- Removed in this release.
### Fixed
- Bug fixes. One-line impact description.
### Security
- Security patches. Link the CVE when applicable.
Step 4: good and bad examples
examples/good.md.
## [1.4.0] - 2026-05-10
### Added
- OAuth2 device flow support (#234).
- Environment variable `RATE_LIMIT_PER_MIN` to tune token-bucket throttling.
### Fixed
- Memory leak at ~10k concurrent connections (#241).
- Path separator handling on Windows.
### Security
- Upgrade `axios` to 1.7.0 (CVE-2025-12345).
examples/bad.md.
## v1.4.0
- Fixed various things.
- Bug fixes.
- Performance improved.
- Refactoring.
- Code cleanup.
Step 5: SKILL.md — the entrypoint
Now the entrypoint, tying together every asset we wrote.
---
name: release-notes
description: Analyze commits and merges since the last git tag and write release notes in Keep a Changelog format. Use when the user asks for release notes, a changelog entry, "next version notes", or "v1.5.0 release notes".
when_to_use: "draft release notes", "write the changelog for this release", "v1.5.0 release notes" — any phrase suggesting a per-release summary.
argument-hint: "[version]"
arguments: [version]
allowed-tools: Bash(git *) Read
effort: high
---
# Release Notes — Keep a Changelog
Target version: `$version` (if missing, infer the next reasonable SemVer bump).
## Input data
```!
bash ${CLAUDE_SKILL_DIR}/scripts/collect.sh
```
## Output format
Follow the skeleton in `${CLAUDE_SKILL_DIR}/references/template.md`. The
allowed categories are exactly Added, Changed, Deprecated, Removed, Fixed,
Security.
Good example: `${CLAUDE_SKILL_DIR}/examples/good.md`
Counter-example to avoid: `${CLAUDE_SKILL_DIR}/examples/bad.md`
## Classification rules
1. When a conventional commit prefix is present, trust it first:
- `feat:` to Added
- `fix:` to Fixed
- `refactor:` / `perf:` / `chore:` go to Changed only if user-visible
- `security:` / `sec:` to Security
2. Without a prefix, infer from message and diff stats.
3. Pure refactors, test-only changes, and CI tweaks are **excluded** unless they have user-visible effect.
## Tone and length
- One line per entry. The reader should immediately know what is different.
- No internal function names or file paths.
- If an issue or PR number is available, end with `(#123)`.
- ASCII Markdown only. No emojis.
## Result verification
After drafting, confirm:
- Every merge commit is reflected somewhere.
- No catch-all "miscellaneous" or "other" section was created.
- Security entries link a CVE when one exists.
If anything is unclear, ask the user "where should I classify this commit?" before finishing.
Step 6: test
Start a session and exercise both invocation paths.
cd /path/to/your/repo
claude
# 1) Automatic invocation
> draft the release notes for v1.5.0
# 2) Explicit invocation
> /release-notes 1.5.0
Both paths should arrive at the same result. If the Skill is not firing, the description lacks keywords; if it fires too eagerly, tighten the description.
Step 7: share with the team
Once the personal version is solid, move it to the project or a plugin.
# Project-scope sharing
mv ~/.claude/skills/release-notes /path/to/repo/.claude/skills/
git add .claude/skills/release-notes
git commit -m "skill: add release-notes generator (Keep a Changelog)"
Anyone who clones the repo and runs Claude Code now inherits the Skill.
6. Packaging and distribution
Three roads to share a Skill.
6-1. Git, plain — the simplest
Check .claude/skills/ into the repo. Clone, run Claude Code, done. This covers 90% of cases.
Pros: no extra infrastructure, version control is free, the code review process applies. Cons: cross-repo reuse means copy-paste — supplement with plugins or dotfile sync.
6-2. Plugin — when bundling Skills, subagents, hooks
A Claude Code Plugin packages Skills, subagents, hooks, and commands into one distributable unit. Plugin Skills live at <plugin>/skills/<name>/SKILL.md. Plugins are installed through a marketplace.
When to reach for a plugin:
- Five or more related Skills to ship together.
- Skills plus custom subagents or hooks that should travel together.
- External consumers should install with one command.
6-3. Anthropic Skills Marketplace — public catalog
Launched December 2025 as a directory of partner-built Skills. Atlassian, Figma, Canva, Stripe, Notion, Zapier, and others publish Skills tied to their workflows. Use this route to put your own Skill in front of the public.
Security note
Pre-approving permissions via allowed-tools and checking that into git grants everyone who clones the same authority. Claude Code raises a workspace trust dialog the first time, but never enable someone else's Skill without reading it. Read the SKILL.md body, anything under scripts/, and the allowed-tools list.
7. Skills vs MCP vs Subagent vs Plugin — a decision tree
The most-confused part. The four mechanisms have distinct sweet spots.
| Mechanism | What | When |
|---|---|---|
| Skill | One YAML+markdown file. Inlined into context when invoked. | Procedures, checklists, repeated instructions. Code limited to shell scripts. |
| MCP server | External process, JSON-RPC, exposes tools. | Talking to external APIs, databases, custom toolchains. When other agents should reuse the same tool. |
| Subagent | Isolated context with its own system prompt. | Large tasks that need context isolation (codebase exploration, deep research). |
| Plugin | Distribution unit packaging the above. | When multiple Skills, Subagents, or Hooks must ship together. |
The decision tree
Question 1: Do you need to talk to an external system? (Database, external API, a specialized file-system tool.)
- Yes — MCP server. New tools come from MCP. A Skill does not create tools; it teaches the model how to use existing ones.
- No — Question 2.
Question 2: Do you need execution isolated in a separate context? (Long exploration, restricted permissions.)
- Yes — Subagent, or a Skill with
context: fork. - No — Question 3.
Question 3: Are you bundling multiple Skills, Subagents, or Hooks together?
- Yes — Plugin, even for a single Skill if it is going through a marketplace.
- No — Skill.
Concrete examples
| Situation | Choice |
|---|---|
| Auto-fetch and update Jira tickets | MCP (needs the Jira API) |
| PR summary procedure | Skill |
| Deep codebase exploration | Subagent or a Skill with context: fork |
| "Release workflow" bundle (3 Skills + 2 hooks) | Plugin |
| A check that must run on every commit | Hook, not a Skill |
The principle: a Skill does not create tools, it teaches tool usage. "I need a new tool" means MCP. "I am tired of re-explaining how to use existing tools" means a Skill.
8. Advanced patterns
8-1. Delegating to a subagent with context: fork
Large tasks pollute the main conversation. context: fork makes the Skill body the task for a fresh isolated context, and only the result flows back to main.
---
name: deep-research
description: Research a topic thoroughly in the codebase. Use when the user asks "where is this implemented?", "why was it written this way?", or wants a deep dive.
context: fork
agent: Explore
---
Research $ARGUMENTS in this codebase:
1. Locate relevant files via Glob and Grep.
2. Read the key files and sketch a call graph.
3. Summarize findings with concrete `file:line` references.
Upside: 200 files do not flow back into your main chat. Downside: only the summary returns, so there is little room for human steering mid-task.
8-2. Reducing friction with allowed-tools
If you do not want a permission prompt every time, pre-approve. Keep the scope narrow.
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
Do not pre-approve Bash(*). That opens the door for the Skill to run something dangerous you did not anticipate.
8-3. Tightening auto-invoke with paths
A Skill that is only meaningful for certain files can constrain trigger using paths.
paths: ["src/**/*.py", "tests/**/*.py"]
When the file in focus does not match, the Skill drops out of the auto-invoke candidate set. Explicit user invocation still works.
8-4. Starting from facts via dynamic context
One of the most powerful patterns. At invoke time the shell command runs and the output is inlined into the body.
## Environment
```!
node --version
npm --version
git status --short
```
## Recent changes
!`git log --oneline -10`
## Task
Given the environment above ...
The model does not need to call a tool to "show me the environment," and the run always starts from real data.
8-5. Deterministic enforcement with hooks
Hooks scoped to a Skill's lifecycle can live in the frontmatter. Use PostToolUse to enforce a linter, or PreToolUse to block dangerous commands.
8-6. Use ultrathink for one-off deep reasoning
The word ultrathink anywhere in the body switches the model to a deeper reasoning mode for the duration of that Skill. Useful for Skills that orchestrate complex decisions (e.g. migration planning). Overusing it across every Skill explodes cost and latency.
9. Real examples — Skills people are actually shipping
As of May 2026, recurring patterns.
PR Summary — takes a diff and PR body and produces a one-screen summary with risk flags. The most common Skill.
Conventional Commit — disable-model-invocation: true, triggered only via /commit. Stage, write message, commit. allowed-tools: Bash(git add *) Bash(git commit *).
Release Notes — the one we just built. Format varies by company, so this is a high-value Skill to roll yourself.
Code Review Checklist — checklist matching your house style. references/ holds security, performance, and accessibility guides; SKILL.md is the entrypoint.
Runbook Executor — operational automation. "Roll back the deploy" triggers the precise sequence: helm rollback, Slack notification, memory cleanup.
Bug Triage — reads an issue body, recommends labels, priority, and assignee. Pairs with a GitHub MCP.
Migration Guide — moving part of the codebase from React 16 to React 19. arguments: [from, to, target].
Content Drafting — blog drafts, tweet threads, change announcements. Tone guide in references/.
Security Review — checklist for new dependencies or new API endpoints. CWE mapping.
Database Migration — schema-change procedure: dry-run, diff, approve, deploy. PreToolUse hook protects prod.
Postmortem Drafter — incident retrospective draft. Five whys, blameless tone.
Docs Sync — after code changes, update README, API docs, and changelog together. Leans on paths.
Cost Reporter — estimates how the last PR moves cloud spend. terraform plan plus a pricing table.
This list is just common shapes. The most valuable Skill is the one that captures your team's actual procedure. Every "wait, am I typing this again?" moment is one new Skill candidate.
10. Anti-patterns — common failure modes
After building dozens of Skills, the recurring traps.
- Vague description. "A nice tool" — the model has nothing to match against.
- Overly generic description. "Writes code" — matches every utterance and fires constantly.
- Body over 500 lines. Recurring token cost. Push into references/.
allowed-tools: Bash(*). Pre-approves every shell command. Asking for accidents. Narrow it.disable-model-invocation: falseon a side-effecting command. Claude calls/deployon its own. Anything with side effects should be user-only.- Duplication with CLAUDE.md. The same instruction in both places means conflicts and confusion. CLAUDE.md is for always-true facts; Skills are for situational procedures.
- Using a Skill where MCP belongs. Working around an external API in markdown. Write the MCP server.
- No tests. A Skill is code. Verify both automatic and explicit invocation every time the Skill changes.
- No version control. Skill behavior changes when the Skill changes. Git history is the answer.
- Name collisions. Same name in Personal, Project, and Plugin scopes. The priority rules exist but they are confusing — name to avoid the collision.
11. Skill content lifecycle — token mechanics
A detail people miss. Once invoked, a Skill's body enters the conversation as one message and stays for the rest of the session. It is not re-read each turn.
When auto-compaction fires, the most recently invoked Skills are partially preserved — up to 5,000 tokens of each, sharing a 25,000-token budget across all preserved Skills, filled from the most recently invoked first. Older Skills can be dropped entirely after compaction.
If a Skill seems to stop influencing behavior — the body is almost certainly still in context, and the model has chosen a different approach. Strengthen the description and add stronger language ("must", "never") in the body, or enforce deterministically via hooks.
Epilogue — keep Skills in mind
A Skill is the cheapest way to add one more line to "what the agent can do." You do not wait on a new model and you do not write a new MCP server. Write the procedure into one directory, push to git, and from the next session the entire team shares the procedure.
A 9-item checklist
- Does the description carry what, when, and the keywords?
- Is the body under 500 lines, with longer material in references/?
- Are side-effecting commands gated by
disable-model-invocation: true? - Is
allowed-toolsscoped narrowly? - Is dynamic context (
!) starting the run from facts? - Have you tested both automatic and explicit invocation?
- Does the name avoid collision with other Skills and commands?
- Did you consciously pick Personal vs Project vs Plugin scope?
- Should this actually be an MCP server or Subagent?
Anti-pattern quick recall
Vague description / over-broad description / sprawling body / wide allowed-tools / auto-invoked dangerous commands / CLAUDE.md duplication / Skill where MCP belongs / no tests / no version control / name collisions.
Coming up next
The next post in this thread — building an MCP server from scratch with the TypeScript SDK in 30 minutes — covers the other half. Skills encapsulate procedures; MCP creates new tools. After that, publishing a plugin to the marketplace, and a Claude Code Hooks playbook for deterministic guardrails when handing more authority to an agent.
The release-notes Skill we just built is exactly the kind of one-page markdown that changes a team's procedure forever. Every "am I typing this again?" moment is the next Skill candidate.
References
- Anthropic — Extend Claude with skills (Claude Code official docs)
- GitHub — anthropics/skills (official example Skill repo)
- Anthropic — The Complete Guide to Building Skills for Claude (PDF)
- Agent Skills open standard
- Anthropic — Subagents (Claude Code)
- Anthropic — Plugins (Claude Code)
- Anthropic — Hooks (Claude Code)
- Anthropic — Memory / CLAUDE.md
- Anthropic — Permissions
- The New Stack — Agent Skills: Anthropic's Next Bid to Define AI Standards
- VentureBeat — Anthropic launches enterprise Agent Skills and opens the standard
- Keep a Changelog 1.1 spec
- Model Context Protocol official site