Unveiling Claude Code: How Rules, MCP, and Skills Power the Coding Agent

This article dissects the leaked Claude Code v2.1.88 source to reveal how the three core concepts—Rules, MCP, and Skills—are implemented, where they are injected in the Anthropic LLM API request, and when developers should prefer each mechanism for reliable, secure, and token‑efficient coding agent workflows.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
Unveiling Claude Code: How Rules, MCP, and Skills Power the Coding Agent

Background

Claude Code, Cursor and similar coding agents expose three mechanisms for extending model behavior: Rules , Model Context Protocol (MCP) and Skills . They are implemented on top of the Anthropic tool_use protocol but differ in where the supporting data is injected into the API request.

Key Concepts

Rules

Rules are project‑level natural‑language directives stored in .claude/rules/*.md or a top‑level CLAUDE.md. During request preparation the client walks from the repository root to the current working directory, merges all discovered rule files and injects the formatted text as a hidden user message at the beginning of the messages array ( {role:"user", isMeta:true}). The model sees the rules as part of its prompt and obeys them automatically.

Model Context Protocol (MCP)

MCP standardises calls to external services. Each MCP tool is represented in the tools[] array with a name of the form mcp__<server>__<tool>. The client reads a configuration file ( .mcp.json in the project or ~/.claude.json for the user) and performs an initialize handshake that returns a list of tools and an optional instructions field. The tool definitions are added to tools[] and the server‑level instructions are concatenated into the dynamic part of the system prompt. When the model outputs a tool_use block with an mcp__ prefix, Claude Code routes the call to the MCP server, which executes the real operation (e.g., a GitHub API request) and returns the result as a tool_result.

Skills

Skills are reusable Markdown prompt files ( SKILL.md) that describe a structured workflow. They are discovered under .claude/skills and listed via a skill_listing attachment. When the model triggers a Skill with tool_use: {name:"Skill", input:{skill:"commit",args:""}}, Claude Code reads the corresponding Markdown, wraps it as a hidden user message ( role:"user", isMeta:true) and injects it into the conversation. The model then follows the instructions using built‑in tools (Read, Edit, Bash). Skills can run in two modes:

Inline (default) : the injected prompt becomes part of the current conversation.

Fork : the Skill runs in an isolated agent context with its own cache, permission tracking and abort control.

Implementation Details

The core API call looks like:

anthropic.messages.create({
  system: TextBlockParam[],   // static role definition and system instructions
  tools: BetaToolUnion[],     // tool definitions (name, description, input_schema)
  messages: MessageParam[]    // conversation history, including hidden injections
})

Key utility functions in the source include: prependUserContext() – injects Rules into messages as a hidden user entry. appendSystemContext() – adds dynamic system information such as Git status. processMemoryFile() – reads a rule or skill file, parses front‑matter, resolves @include directives (max depth 5), applies conditional paths matching, and formats the output. toolToAPISchema() – converts an MCP tool definition into the tools[] schema (name, description, input_schema).

Rules are never placed in the system prompt because their content varies per project and would break the organization‑level prompt cache. By keeping them in messages they remain project‑specific while still benefiting from the shared cache for the static part of system.

Practical Guidance

When to use Rules : short, project‑wide conventions that must apply to every model call (e.g., coding style, security policies). They are automatically injected and incur no token‑budget decisions.

When to use Skills : longer, reusable workflows that benefit from explicit triggering or isolation (e.g., a multi‑step commit process). Use context:"fork" for tasks that should not pollute the main conversation.

When to use MCP : scenarios requiring persistent connections, atomic multi‑step operations, or permission isolation (e.g., database connection pools, authenticated API calls). MCP adds a server process and JSON‑RPC layer, so prefer Bash for simple one‑off CLI commands.

Comparison of the Three Mechanisms

All three are built on the same tool_use protocol; the difference lies in the injection point:

Rules → hidden user message at the start of messages.

MCP → entries in tools[] **and** optional instructions injected into the dynamic part of system.

Skills → hidden user message added **after** the model’s tool_use call, with optional forked execution.

Because the model only sees the final prompt text, the functional distinction is minimal; the engineering choice determines how and when the content is supplied.

Implementation Highlights

Rules

Discovery order (higher‑level overrides lower‑level):

CLAUDE.md → .claude/CLAUDE.md → .claude/rules/*.md → CLAUDE.local.md

. Each file is processed by processMemoryFile(), which:

Reads the file.

Parses front‑matter (e.g., paths for conditional matching).

Strips HTML comments.

Resolves @include directives (max depth 5).

Applies paths filters based on the current file being processed.

Formats the result for injection.

Conditional rules allow a rule file to apply only to matching paths, e.g.:

---
paths:
  - "src/components/**/*.tsx"
  - "src/hooks/**/*.ts"
---
In React components always use functional components and hooks.

Rules are injected via prependUserContext() as a hidden user message wrapped in a <system-reminder> tag with role:"user" and isMeta:true. The injected block begins with a mandatory instruction reminding the model that the following text overrides default behavior.

MCP Tools

Configuration files ( .mcp.json or ~/.claude.json ) list servers and their tools. During initialize the client builds the tool schema using toolToAPISchema() : <code>async function toolToAPISchema(tool) { return { name: tool.name, // e.g. "mcp__github__create_issue" description: await tool.prompt(), input_schema: tool.inputJSONSchema }; } </code> The server‑level instructions (if provided) are concatenated by getMcpInstructions() and appended to the dynamic part of the system prompt, unless a feature flag routes them as an attachment to avoid breaking prompt cache. Execution flow: <code>Model outputs tool_use {name:"mcp__github__create_issue", input:{...}} → Claude Code detects the <code>mcp__</code> prefix and forwards the call to the MCP client → MCP client sends a JSON‑RPC request to the MCP server → Server performs the real operation (e.g., GitHub API) → Result is returned as tool_result.content → Model receives the result and continues reasoning </code> MCP is valuable when you need persistent state, atomic multi‑step encapsulation, or strict permission boundaries. For simple one‑off CLI tasks (e.g., gh , curl , psql ) Bash is usually sufficient. Skills Skill files are discovered under .claude/skills . The client builds a skill_listing attachment that enumerates available skills (limited to ~1 % of the token budget, ~250 characters per description). Each skill description may contain a blocking requirement clause such as: When a skill matches the user's request, this is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task. When the model emits tool_use: {name:"Skill", input:{skill:"commit",args:""}} the client reads the corresponding SKILL.md , wraps its content as a hidden user message, and injects it into the conversation. The tool result for a Skill is merely a label (e.g., "Launching skill: commit" ); the real work happens in the next round when the model processes the injected prompt and calls built‑in tools (Read, Edit, Bash) as instructed. Two execution modes: Inline (default): the injected prompt becomes part of the current dialogue. Fork : the Skill runs in an isolated agent context; all tool calls and state are scoped to the fork and do not affect the main conversation. Skills are not code‑level flow controllers; they are essentially structured prompt templates. Their reliability depends on the quality of the Markdown and the model’s instruction‑following ability. Recommendations Use Rules for short, always‑on project conventions (coding style, security policies). Keep each file under 40 000 characters to avoid size warnings. Use Skills when you have a lengthy, reusable workflow that benefits from explicit triggering or isolation. Provide clear whenToUse descriptions to improve automatic triggering, and consider the fork mode for complex multi‑step tasks. Use MCP only when you need persistent connections, atomic multi‑step operations, or permission‑restricted access to external services. For simple CLI interactions prefer Bash. Reference Claude Code source (v2.1.88 leaked): https://github.com/anthropics/claude-code

MCPtool useLLM agentsSkillsrulesClaude Code
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.