<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Zhengxin</title>
    <description>The latest articles on DEV Community by Zhengxin (@_94be737e156beb4d74df2).</description>
    <link>https://dev.to/_94be737e156beb4d74df2</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4043494%2F624f59c0-0fbb-4fb6-a54b-92fb2d93c548.jpg</url>
      <title>DEV Community: Zhengxin</title>
      <link>https://dev.to/_94be737e156beb4d74df2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_94be737e156beb4d74df2"/>
    <language>en</language>
    <item>
      <title>Claude Code Skills Deep Dive (1): From a Markdown File to a Portable Folder</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Thu, 05 Nov 2026 02:09:39 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-1-from-a-markdown-file-to-a-portable-folder-41f9</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-1-from-a-markdown-file-to-a-portable-folder-41f9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The Agent Skills format defines a portable folder: &lt;code&gt;SKILL.md&lt;/code&gt; supplies discovery metadata and core instructions; references hold knowledge to read when needed; scripts perform deterministic operations; and assets provide templates and materials. Claude Code accepts that core, then adds product-specific invocation, execution, permission, and path behavior. Write the portable core first, and be explicit about which behavior depends on Claude Code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-0-from-repeated-prompts-to-callable-capabilities-213f"&gt;Part 0&lt;/a&gt;, we placed Skills in the capability stack: they participate in selection somewhat like tools, but activation loads operational knowledge rather than entering a separate atomic executor.&lt;/p&gt;

&lt;p&gt;Now look at the filesystem. Why is a Skill an entire folder instead of a single &lt;code&gt;deploy.md&lt;/code&gt; file?&lt;/p&gt;

&lt;h2&gt;
  
  
  One Markdown file soon becomes three kinds of material
&lt;/h2&gt;

&lt;p&gt;Start with a &lt;code&gt;release-check&lt;/code&gt; Skill containing four steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;1.&lt;/span&gt; Inspect the working tree.
&lt;span class="p"&gt;2.&lt;/span&gt; Run tests.
&lt;span class="p"&gt;3.&lt;/span&gt; Check the changelog.
&lt;span class="p"&gt;4.&lt;/span&gt; Summarize risks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the workflow matures, it needs a detailed versioning policy to consult, a version-number validator to run, and a release-report template to fill in. Putting all three into the same Markdown file would load policy, code, and template alongside the core procedure. It would also blur the distinction between instructions needed every time and material needed only for a particular branch of the work.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;Agent Skills specification&lt;/a&gt; therefore defines a Skill as a directory with &lt;code&gt;SKILL.md&lt;/code&gt; at its entry point, not merely as a Markdown document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release-check/
├── SKILL.md
├── scripts/
│   └── validate-version.sh
├── references/
│   └── version-policy.md
└── assets/
    └── release-report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These locations express different roles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;How Claude uses it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;SKILL.md&lt;/code&gt; frontmatter&lt;/td&gt;
&lt;td&gt;Capability index&lt;/td&gt;
&lt;td&gt;Decides whether the Skill is relevant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;SKILL.md&lt;/code&gt; body&lt;/td&gt;
&lt;td&gt;Core instructions&lt;/td&gt;
&lt;td&gt;Enters context when the Skill is activated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;references/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;On-demand knowledge&lt;/td&gt;
&lt;td&gt;Read when a relevant question arises&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scripts/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deterministic operations&lt;/td&gt;
&lt;td&gt;Run when needed, without loading the entire source into context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;assets/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Templates and resources&lt;/td&gt;
&lt;td&gt;Used to create or transform the final output&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The folder is both a &lt;strong&gt;capability manual&lt;/strong&gt; and a &lt;strong&gt;bundle of working materials&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;SKILL.md&lt;/code&gt; is an entry point, not a warehouse
&lt;/h2&gt;

&lt;p&gt;The entry file does at least three jobs: its metadata says what the Skill is and when to use it; its body explains what to do after activation; and it points Claude toward supporting files at the right moment.&lt;/p&gt;

&lt;p&gt;The third job is easy to miss. Merely placing &lt;code&gt;version-policy.md&lt;/code&gt; in &lt;code&gt;references/&lt;/code&gt; does not tell Claude why or when to read it. The entry file should supply conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Supporting resources&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; When evaluating a version number, read &lt;span class="sb"&gt;`references/version-policy.md`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; For a mechanical format check, run &lt;span class="sb"&gt;`scripts/validate-version.sh`&lt;/span&gt;.
&lt;span class="p"&gt;-&lt;/span&gt; For the final report, use &lt;span class="sb"&gt;`assets/release-report.md`&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is navigation, not a redundant directory listing. Progressive disclosure works only if Claude can find the next resource when it becomes relevant. Think of &lt;code&gt;SKILL.md&lt;/code&gt; as a map: the description tells Claude when to open it, the body identifies the main route, and supporting files are branches that need not be copied into the map itself. Too little guidance makes the map unusable; too much detail defeats the purpose of loading information in stages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the open format standardizes
&lt;/h2&gt;

&lt;p&gt;The open specification requires YAML frontmatter followed by a Markdown body. A minimal portable core looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-check&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check whether a version is ready to release; use when preparing a release.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here &lt;code&gt;name&lt;/code&gt; gives the folder a stable identity, &lt;code&gt;description&lt;/code&gt; says both what it does and when to use it, and the Markdown body stores the instructions. &lt;code&gt;scripts/&lt;/code&gt;, &lt;code&gt;references/&lt;/code&gt;, and &lt;code&gt;assets/&lt;/code&gt; are optional conventional locations. The specification also defines optional metadata such as &lt;code&gt;license&lt;/code&gt;, &lt;code&gt;compatibility&lt;/code&gt;, and an extensible &lt;code&gt;metadata&lt;/code&gt; map; &lt;code&gt;allowed-tools&lt;/code&gt; is experimental.&lt;/p&gt;

&lt;p&gt;The format does &lt;strong&gt;not&lt;/strong&gt; standardize Claude Code's UI, subagent types, or session lifecycle. Another agent can understand the same folder's instructions, but each host decides where to discover it, how to show the metadata to the model, how to activate it, where a script runs, and what to do with the result. This is the boundary between a &lt;strong&gt;format standard&lt;/strong&gt; and a &lt;strong&gt;product runtime&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Claude Code adds
&lt;/h2&gt;

&lt;p&gt;Claude Code plugs Skills into its commands, tools, subagents, hooks, and permission system. Its frontmatter can therefore express additional, product-specific behavior. Group those extensions by the question they answer:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Claude Code-specific direction&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Who can invoke it?&lt;/td&gt;
&lt;td&gt;User invocation, model invocation, and visibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where does it run?&lt;/td&gt;
&lt;td&gt;Current conversation or a forked subagent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What input does it receive?&lt;/td&gt;
&lt;td&gt;Arguments and dynamic context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;What may it do?&lt;/td&gt;
&lt;td&gt;Tool pre-approval, hooks, and other execution controls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Where is it relevant?&lt;/td&gt;
&lt;td&gt;Path-based conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A deployment Skill might be user-invoked only; a research Skill might run in a separate subagent context; a frontend Skill might apply only to particular paths. These features are useful, but they are not promises made by every Agent Skills-compatible host. The same file effectively contains two layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Portable Agent Skills core
  name · description · instructions · supporting files
        ↓ interpreted by a host
Claude Code extensions
  invocation · fork · paths · hooks · permissions · dynamic context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When authoring a Skill, know which layer a behavior depends on. “Works in Claude Code” should not silently become “guaranteed by the Agent Skills standard.” The &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code Skills guide&lt;/a&gt; documents its own extensions; the &lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;open specification&lt;/a&gt; defines the portable baseline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The apparently contradictory &lt;code&gt;name&lt;/code&gt; field
&lt;/h2&gt;

&lt;p&gt;The open specification requires &lt;code&gt;name&lt;/code&gt; and expects it to match the parent directory. Claude Code can derive a local Skill's command identity from that directory, so its own documentation allows the frontmatter &lt;code&gt;name&lt;/code&gt; to be omitted in some local cases.&lt;/p&gt;

&lt;p&gt;These are answers to different questions. The open format asks how a folder preserves a verifiable identity outside the current host. Claude Code asks which &lt;code&gt;/skill-name&lt;/code&gt; a user types when the local directory is already known. A personal, Claude Code-only Skill can rely on directory inference. For a Skill intended to travel between clients, explicitly writing a standards-compliant &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; is the safer choice.&lt;/p&gt;

&lt;p&gt;The same principle applies to other extensions: &lt;strong&gt;write the portable core explicitly, add host-specific controls where useful, and do not make an extension carry the whole meaning of the workflow.&lt;/strong&gt; For example, “wait for user confirmation before deployment” belongs in the body instructions, not solely in a Claude Code setting that prevents automatic invocation. The setting is an extra safeguard; the instructions preserve the workflow's intent.&lt;/p&gt;

&lt;h2&gt;
  
  
  A script does not turn a Skill into a tool
&lt;/h2&gt;

&lt;p&gt;Bundling a script does not erase the Skill/tool boundary. A host-registered tool has a defined invocation interface, permission identity, and result protocol. A script inside a Skill is implementation material carried by that Skill. Claude still follows the instructions to decide when to run it through an existing execution capability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Skill instructions: “Check the version file first.”
        ↓
Existing execution capability: Bash / code execution
        ↓
Bundled script: scripts/validate-version.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scripts suit steps with clear inputs and repeatable outputs. Instructions suit contextual judgment, exceptions, and orchestration. Leaving every deterministic check in natural language asks the model to reinterpret it each time. Hard-coding the entire workflow into one script, however, sacrifices Claude's ability to handle context and exceptions. The Skill folder lets the two approaches work together.&lt;/p&gt;

&lt;h2&gt;
  
  
  An asset is not a reference
&lt;/h2&gt;

&lt;p&gt;Both &lt;code&gt;references/&lt;/code&gt; and &lt;code&gt;assets/&lt;/code&gt; might contain Markdown, JSON, images, or templates. Their distinction is purpose, not extension: a &lt;strong&gt;reference&lt;/strong&gt; is read to inform Claude's judgment; an &lt;strong&gt;asset&lt;/strong&gt; is used to make the final deliverable. An API specification belongs with references, while a report template belongs with assets.&lt;/p&gt;

&lt;p&gt;This distinction helps with review. Changing a reference may change Claude's decisions. Changing an asset mainly changes the output's form. Changing a script may change a deterministic operation. Changing &lt;code&gt;SKILL.md&lt;/code&gt; can change discovery and the overall workflow. A folder gives us clearer change boundaries than a single versioned prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why custom commands converged with Skills
&lt;/h2&gt;

&lt;p&gt;An older custom command could already expose Markdown as &lt;code&gt;/deploy&lt;/code&gt;: the user could save a prompt and invoke it repeatedly. Skills add a discoverable description, a folder of supporting files, and richer frontmatter for invocation and execution. Claude Code still supports older command files, but &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;recommends Skills for new work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is more than renaming slash commands. It moves from “the user expands a stored prompt” toward “the user or model can discover a capability bundle.” Still, not every built-in command is a Skill: some commands trigger product-internal behavior, while a bundled Skill primarily supplies instructions and orchestrates tools. Sharing a &lt;code&gt;/name&lt;/code&gt; entry point does not imply identical execution semantics.&lt;/p&gt;

&lt;p&gt;The open standard makes the bundle recognizable; the product runtime makes it participate in a session. Both layers matter, and they should not be confused.&lt;/p&gt;

&lt;p&gt;The next article follows metadata, instructions, and resources through their different loading times to examine the context-cost trade-off behind progressive disclosure.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;Agent Skills specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview" rel="noopener noreferrer"&gt;Anthropic Platform: Agent Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code: Extend Claude with Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-0-from-repeated-prompts-to-callable-capabilities-213f"&gt;Part 0: From Repeated Prompts to Callable Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code Skills Deep Dive (0): From Repeated Prompts to Callable Capabilities</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Wed, 04 Nov 2026 02:09:41 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-0-from-repeated-prompts-to-callable-capabilities-213f</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-skills-deep-dive-0-from-repeated-prompts-to-callable-capabilities-213f</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A Skill packages instructions, checklists, and multi-step workflows into an on-demand capability. Claude can discover it from its name and description, load the full instructions when they matter, and then use existing tools to do the work. A Skill participates in capability selection, but it is not a new atomic executor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When preparing a release, you may find yourself telling Claude the same thing again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First check the working tree, then run the tests, prepare a changelog,
verify the version number, and list the files that would be released.
Do not actually publish anything until I confirm.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not a fact that applies to every task in a project, so putting it in &lt;code&gt;CLAUDE.md&lt;/code&gt; would make unrelated sessions carry an occasional procedure. Nor is it one atomic tool action: it involves checking Git state, running tests, reading a changelog, and summarizing risks in a deliberate order. It is a reusable &lt;strong&gt;way of working&lt;/strong&gt; that otherwise has to be restated in each conversation.&lt;/p&gt;

&lt;p&gt;That is the problem a Skill solves: &lt;strong&gt;how can operational knowledge persist without entering every task's context?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Save the workflow as a folder
&lt;/h2&gt;

&lt;p&gt;Put the release procedure in a directory called &lt;code&gt;release-check&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release-check/
└── SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file has two parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;release-check&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;whether&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;release;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;preparing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;release."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="p"&gt;1.&lt;/span&gt; Inspect the working tree.
&lt;span class="p"&gt;2.&lt;/span&gt; Run tests and a build.
&lt;span class="p"&gt;3.&lt;/span&gt; Check the version number and changelog.
&lt;span class="p"&gt;4.&lt;/span&gt; Summarize risks and wait for user confirmation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontmatter fields &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are &lt;strong&gt;metadata&lt;/strong&gt;: a compact index entry that helps Claude recognize when this capability is relevant. The Markdown after the frontmatter is the &lt;strong&gt;instructions&lt;/strong&gt;: the actual workflow Claude follows when the Skill is used. The &lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;Agent Skills specification&lt;/a&gt; defines this basic directory-and-&lt;code&gt;SKILL.md&lt;/code&gt; shape; &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code's Skills guide&lt;/a&gt; explains how Claude Code discovers and invokes it.&lt;/p&gt;

&lt;p&gt;The distinction is about timing. The description can be available for selection without loading the entire procedure. Once the task matches, Claude reads the full Skill body. Supporting files can be opened later, only if needed. This staged approach is called &lt;strong&gt;progressive disclosure&lt;/strong&gt;. It keeps a large library of Skills practical, although metadata itself still has a context cost—descriptions should be useful and concise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Selection resembles tool selection—but execution does not
&lt;/h2&gt;

&lt;p&gt;If the user asks, “Is this version ready to release?”, Claude can decide whether &lt;code&gt;release-check&lt;/code&gt; matches the request. The user can also invoke it explicitly with &lt;code&gt;/release-check&lt;/code&gt;. This resembles tool selection in one respect: the model sees a capability's name and purpose, then decides when it applies.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; make a Skill the same thing as a tool. A tool has an executable operation behind it: &lt;code&gt;Read&lt;/code&gt; reads a file; &lt;code&gt;Bash&lt;/code&gt; runs a command. A tool call goes to a runtime and returns a result. Loading &lt;code&gt;release-check&lt;/code&gt; instead gives Claude a set of instructions. Claude still uses existing tools to inspect the repository, run tests, and read the changelog. The Skill governs sequence, judgment, and stopping conditions; the tools perform the individual actions.&lt;/p&gt;

&lt;p&gt;That is also why a Skill is not merely another name for &lt;code&gt;CLAUDE.md&lt;/code&gt;. The latter carries standing project guidance into a session. A Skill is a discoverable, reusable candidate whose detailed instructions are loaded when relevant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools turn “I can describe an action” into “I can perform an action.” Skills organize those actions into a reliable method for a recurring class of work.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The folder can carry more than instructions
&lt;/h2&gt;

&lt;p&gt;Four Markdown steps are already more reusable than a prompt pasted into chat. But the directory can also contain &lt;strong&gt;supporting resources&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;release-check/
├── SKILL.md
├── references/version-policy.md
├── scripts/validate-version.sh
└── assets/release-report.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;references/version-policy.md&lt;/code&gt; records the project's versioning rules. Claude reads it when deciding whether a change warrants a major release, not during every task. &lt;code&gt;scripts/validate-version.sh&lt;/code&gt; turns a deterministic format check into executable logic instead of asking the model to improvise that check each time. &lt;code&gt;assets/release-report.md&lt;/code&gt; gives the final report a consistent template.&lt;/p&gt;

&lt;p&gt;The main instructions answer &lt;strong&gt;how to carry out this task now&lt;/strong&gt;. A reference file supplies &lt;strong&gt;what the agent should know when a particular question arises&lt;/strong&gt;. Both can enter context on demand, but they serve different purposes. The &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Skills guide&lt;/a&gt; documents supporting files and scripts; the next article in this series will look more closely at the folder format.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens after installation?
&lt;/h2&gt;

&lt;p&gt;Several questions remain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discovery:&lt;/strong&gt; How does Claude know this Skill exists?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activation:&lt;/strong&gt; Is typing &lt;code&gt;/release-check&lt;/code&gt; the same path as Claude choosing it from the description?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution:&lt;/strong&gt; Do the instructions run in the current conversation, or can they be delegated to a separate agent that returns only a summary?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance:&lt;/strong&gt; Who can distribute the Skill, invoke it, and authorize the tools it uses?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions lead to a broader design rule: stable facts belong in standing guidance, atomic actions belong in tools, and reusable operational knowledge belongs in Skills. The series will reach that boundary in its conclusion. First, it will follow the lifecycle of a Skill like &lt;code&gt;release-check&lt;/code&gt;, rather than translating documentation field by field.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three layers, three costs
&lt;/h2&gt;

&lt;p&gt;The folder structure is not merely a way to organize files. It determines &lt;strong&gt;when&lt;/strong&gt; each piece becomes visible:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;When it enters context&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;release-check&lt;/code&gt; example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Metadata&lt;/td&gt;
&lt;td&gt;During capability discovery&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;SKILL.md&lt;/code&gt; body&lt;/td&gt;
&lt;td&gt;When the Skill is activated&lt;/td&gt;
&lt;td&gt;The four-step procedure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supporting resources&lt;/td&gt;
&lt;td&gt;When needed&lt;/td&gt;
&lt;td&gt;Version policy, validator, report template&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the description is vague, Claude may never think to use the Skill for a release request. If it is bloated, every capability-discovery step carries unnecessary text. If the main body contains every detail, one activation loads too much. If no instruction points Claude to a reference file, that file may never be read. And if a deterministic check remains prose when it could be a script, the model has to reconstruct the same decision each time.&lt;/p&gt;

&lt;p&gt;The next article examines which parts of this folder are defined by the open Agent Skills format and which behaviors are specific to Claude Code.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code: Extend Claude with Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview" rel="noopener noreferrer"&gt;Anthropic Platform: Agent Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agentskills.io/specification" rel="noopener noreferrer"&gt;Agent Skills: Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (9): Where MCP Ends and Skills, Tools, and Plugins Begin</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Mon, 02 Nov 2026 02:01:01 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-9-where-mcp-ends-and-skills-tools-and-plugins-begin-4a3</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-9-where-mcp-ends-and-skills-tools-and-plugins-begin-4a3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Use a script bundled with a Skill for private, deterministic logic. Use an existing local tool or executable for reusable work that does not need a separate integration. Reach for MCP when the capability belongs to another process or service. Put multiple related components into a plugin when you need a versioned, shareable installation unit. And when designing MCP servers, choose their boundaries with trust and administration in mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-8-from-mcp-client-to-mcp-server-26n"&gt;Part 8&lt;/a&gt;, Claude Code could act as both an MCP client and an MCP server. That closes the mechanism-level loop: configuration, handshake, transport, tool exposure, permissions, authentication, resources, elicitation, and finally the reversal of roles.&lt;/p&gt;

&lt;p&gt;This final installment asks a more practical question: &lt;strong&gt;when a new capability is needed, should MCP be part of the solution at all?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the boundary, not the acronym
&lt;/h2&gt;

&lt;p&gt;The decision tree from the companion Skills research series can be summarized like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Does the model need a new atomic action?
  ├─ Private, deterministic logic for one Skill → bundled script
  ├─ Reusable, local action                → existing tool / executable
  └─ External system or independent process → MCP tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a design heuristic, not a rule enforced by Claude Code. The dividing questions are: &lt;strong&gt;who else needs this action, and must it run independently of Claude Code?&lt;/strong&gt; &lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code's Skills documentation&lt;/a&gt; explicitly supports helper scripts inside a Skill directory, while its &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP documentation&lt;/a&gt; covers connections to external tools, databases, and APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bundled script, a local tool, or an MCP server?
&lt;/h2&gt;

&lt;p&gt;Suppose a Skill needs to validate version strings according to one project's conventions. If the check has no useful identity outside that Skill, make it a small bundled script and let the Skill's instructions decide when to run it. Turning it into a general-purpose tool—or an MCP server—would add an interface and maintenance burden without adding a meaningful boundary.&lt;/p&gt;

&lt;p&gt;Now suppose many unrelated tasks need the same local operation. If it is still just a local executable, with no separate service or authentication lifecycle, an existing tool surface can invoke it. MCP is not automatically better merely because the action is reusable.&lt;/p&gt;

&lt;p&gt;The stronger MCP case is an action whose natural home is &lt;strong&gt;another process or service&lt;/strong&gt;. The Jira example from &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1&lt;/a&gt; fits: the data lives in somebody else's system, access follows that system's authorization rules, and the available operations can evolve independently. An MCP server gives that integration a defined discovery and invocation boundary instead of making Claude assemble ad hoc shell commands each time.&lt;/p&gt;

&lt;p&gt;That boundary has concrete consequences. &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4&lt;/a&gt; followed the tool schema into Claude Code's exposed tool list; &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0"&gt;Part 5&lt;/a&gt; examined permission rules; and &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-6-from-one-authorization-to-multiple-servers-4g1c"&gt;Part 6&lt;/a&gt; traced authentication. A shell script can certainly call an external API, but it does not thereby acquire MCP's standardized tool discovery, schemas, and client/server lifecycle. Those concerns would have to be handled separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  One new server, or one more tool on an existing server?
&lt;/h2&gt;

&lt;p&gt;Once several MCP servers are installed, a subtler choice appears: should a new operation go into an existing server, or should it live behind a new one?&lt;/p&gt;

&lt;p&gt;Claude Code does not make that organizational decision. It connects to servers and exposes what they provide; server authors decide how many tools each server contains. But the boundary is visible to users. Operations that belong to the same internal system and are usually enabled, disabled, and maintained together may be easier to administer in one server. Operations with materially different trust requirements—say, read-only search versus changes to production data—may deserve separate servers.&lt;/p&gt;

&lt;p&gt;This is not a claim that server separation alone makes a dangerous operation safe. Tool-level permissions and the server's own authorization still matter. Rather, separation gives administrators a cleaner unit for configuration and server-level policy. The trade-off is between a convenient shared installation and finer isolation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Many servers: should they become a plugin?
&lt;/h2&gt;

&lt;p&gt;A plugin is &lt;strong&gt;not another behavioral layer&lt;/strong&gt; that replaces Skills or MCP. According to the &lt;a href="https://code.claude.com/docs/en/plugins" rel="noopener noreferrer"&gt;Claude Code plugin overview&lt;/a&gt;, it packages components such as Skills, agents, hooks, and MCP servers into one installable unit. The &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;MCP guide&lt;/a&gt; also describes how plugin-provided servers are started when the plugin is enabled.&lt;/p&gt;

&lt;p&gt;Imagine a team that needs the same internal issue tracker, documentation service, and deployment integration, plus Skills explaining how to use them together. Rather than asking every teammate to recreate the setup in personal configuration or each repository's &lt;code&gt;.mcp.json&lt;/code&gt;, a plugin can distribute and version the collection as one unit.&lt;/p&gt;

&lt;p&gt;The same boundary test applies here: if one project needs the configuration and no shared release process is needed, keep it in project or personal configuration. If multiple repositories or teammates need the same curated collection and updates, a plugin becomes useful. Packaging is about &lt;strong&gt;distribution and lifecycle&lt;/strong&gt;, not about making an MCP tool more powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing the series
&lt;/h2&gt;

&lt;p&gt;The opening distinction was: &lt;strong&gt;a Skill tells Claude how to do something; MCP gives it access to something it can do&lt;/strong&gt;. Across this series, we saw how a configuration becomes a connection, how an external tool appears in the tool list, how permissions and authentication shape trust, how resources and elicitation extend the interaction, and how Claude Code can itself become a server.&lt;/p&gt;

&lt;p&gt;Together, these mechanisms answer one question: &lt;strong&gt;when the model needs an action it did not ship with, where should that action live, how should it enter the loop, and who should be allowed to trust it?&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Connect to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/skills" rel="noopener noreferrer"&gt;Claude Code: Extend Claude with Skills&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/plugins" rel="noopener noreferrer"&gt;Claude Code: Plugins overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/docs/2026-07-28/getting-started/intro" rel="noopener noreferrer"&gt;Model Context Protocol: Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1: From Built-In Tools to Extensible Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-8-from-mcp-client-to-mcp-server-26n"&gt;Part 8: From MCP Client to MCP Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (8): From MCP Client to MCP Server</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Fri, 30 Oct 2026 02:24:06 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-8-from-mcp-client-to-mcp-server-26n</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-8-from-mcp-client-to-mcp-server-26n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The first seven articles treated Claude Code as an MCP client connecting to someone else's servers. Claude Code can also run in the opposite role. &lt;code&gt;claude mcp serve&lt;/code&gt; starts a local stdio MCP server so another MCP client can discover and call capabilities exposed by Claude Code. The direction changes, but the protocol still uses the familiar &lt;code&gt;tools/list&lt;/code&gt; and &lt;code&gt;tools/call&lt;/code&gt; boundary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-7-from-calling-tools-to-reading-resources-and-asking-users-2agk"&gt;Part 7&lt;/a&gt; covered resources and elicitation, it is time to reverse the connection. In &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1&lt;/a&gt;, we separated the host, client, and server roles. For most of this series Claude Code has been the client: it connects to an external server, discovers what that server offers, and makes those capabilities available in its own agent loop. Now turn the picture around. Another application can connect to Claude Code as a server.&lt;/p&gt;

&lt;p&gt;This is not just a theoretical reading of the protocol. Claude Code's current documentation gives the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It starts Claude Code as a &lt;strong&gt;stdio MCP server&lt;/strong&gt;, meaning the calling application launches it as a local subprocess and communicates over standard input and output. That is the same transport pattern we examined in &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb"&gt;Part 3&lt;/a&gt;, but with Claude Code on the server side of the pipe.&lt;/p&gt;

&lt;h2&gt;
  
  
  One tool definition, another exit
&lt;/h2&gt;

&lt;p&gt;Inside Claude Code, a tool has a name, a description, an input schema, and an implementation. During an ordinary conversation, the agent loop presents those definitions to the model and validates the model's arguments before executing a selected tool. As an MCP server, Claude Code can adapt the relevant definitions to the protocol's tool listing format instead.&lt;/p&gt;

&lt;p&gt;The source path examined for this series does that conversion at the server entry point. When an external client asks for &lt;code&gt;tools/list&lt;/code&gt;, Claude Code enumerates the tools it exposes and converts their input schemas to JSON Schema. When the client sends &lt;code&gt;tools/call&lt;/code&gt;, Claude Code locates the requested implementation, checks that it is available, validates the arguments, runs it, and packages the result for the MCP response.&lt;/p&gt;

&lt;p&gt;Conceptually, the two directions look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude Code as client:
  Claude Code → external MCP server → external tool

Claude Code as server:
  external MCP client → Claude Code MCP server → Claude Code tool
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The protocol does not force every host to implement a different tool engine for each direction. The useful implementation insight is that the tool's description, schema, and execution logic can be reused while the boundary around them changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the reuse does—and does not—prove
&lt;/h2&gt;

&lt;p&gt;This symmetry supports an architectural inference: Claude Code's tool abstraction is not solely a piece of prompt text tied to one conversation loop. It is structured enough to be projected outward as MCP tool metadata and executed when a different program initiates the call.&lt;/p&gt;

&lt;p&gt;But there is a limit to that inference. “Same underlying tool implementation” does &lt;strong&gt;not&lt;/strong&gt; mean an external caller inherits exactly the same context, permissions, or user interaction as an interactive Claude Code conversation. The MCP server has its own runtime conditions, tool availability, and security boundary. A client author should inspect what &lt;code&gt;tools/list&lt;/code&gt; actually returns and test the calls they intend to make rather than assuming every internal feature is exposed or behaves identically.&lt;/p&gt;

&lt;p&gt;The analogy with &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4&lt;/a&gt; is still useful. There, Claude Code brought &lt;em&gt;external&lt;/em&gt; MCP tools into its tool catalog, giving each one a server-qualified name. Here, it takes tool definitions on the &lt;em&gt;inside&lt;/em&gt; and presents them through MCP. Both directions depend on describing an operation in a way another component can discover and call.&lt;/p&gt;

&lt;p&gt;The permission discussion in &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0"&gt;Part 5&lt;/a&gt; remains relevant too. Exposing a callable capability is not the same as declaring every call safe. If you let another application launch &lt;code&gt;claude mcp serve&lt;/code&gt;, treat that application's configuration and the resulting tool access as a real trust decision. The outside client is no longer merely reading a document; it is gaining a path to actions performed by the Claude Code process.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical integration shape
&lt;/h2&gt;

&lt;p&gt;A compatible local MCP client generally needs a server configuration that launches the &lt;code&gt;claude&lt;/code&gt; executable with &lt;code&gt;mcp serve&lt;/code&gt; as its arguments. The client starts the subprocess, negotiates MCP, requests &lt;code&gt;tools/list&lt;/code&gt;, and can then issue &lt;code&gt;tools/call&lt;/code&gt; for the exposed names. There is no separate remote HTTP endpoint implied by this command. Standard input and output are the transport; process lifecycle and the local environment are part of the integration.&lt;/p&gt;

&lt;p&gt;That makes this feature useful for an IDE or another automation host that already speaks MCP and wants to reuse capabilities Claude Code exposes, rather than reimplementing them from scratch. It is a narrower use case than connecting Claude Code to a familiar Jira or database server, but it completes the picture of MCP as a &lt;em&gt;role-based protocol&lt;/em&gt;, not a one-way plugin mechanism.&lt;/p&gt;

&lt;p&gt;Earlier drafts of this research treated the reverse role as something visible mainly in source code. The public documentation now explicitly includes “Use Claude Code as an MCP server” and the &lt;code&gt;claude mcp serve&lt;/code&gt; command. The implementation detail about converting internal tool schemas remains a source-level observation; the existence of the user-facing command is documented behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Claude Code can be an MCP client, a stdio MCP server, or part of a larger host that mediates several integrations. The roles describe which side discovers and invokes capabilities on a given connection. They do not dictate that a product must have only one role forever.&lt;/p&gt;

&lt;p&gt;The final article returns to a practical design question: when a new capability is needed, should it be a Tool, a Skill, an MCP server, or a Plugin?&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Use Claude Code as an MCP server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/server/tools" rel="noopener noreferrer"&gt;MCP specification: Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/basic/transports" rel="noopener noreferrer"&gt;MCP specification: Transports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb"&gt;Part 3: From a Child Process to a Remote Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4: From Tools List to an Entry in the Tool List&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (7): From Calling Tools to Reading Resources and Asking Users</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Thu, 29 Oct 2026 02:05:39 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-7-from-calling-tools-to-reading-resources-and-asking-users-2agk</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-7-from-calling-tools-to-reading-resources-and-asking-users-2agk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; An MCP server can offer more than actions for Claude to call. It can expose resources that a client reads by URI, and it can request information from a person during an operation through elicitation. Claude Code provides common ways to list and read resources across servers, while elicitation can appear as a form or an external browser step. These features make the client–server relationship less one-directional than a simple tool call.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most of this series has followed one path: Claude chooses a tool, the MCP server runs it, and a result comes back. That is the &lt;em&gt;tools&lt;/em&gt; capability introduced in &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1&lt;/a&gt;. This article turns to two other paths: the server makes information available for reading, or it asks the user for information it needs to continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources: identify and read, rather than invoke an action
&lt;/h2&gt;

&lt;p&gt;Imagine an issue record, a documentation page, or a database schema. A server can expose this material as an MCP &lt;strong&gt;resource&lt;/strong&gt;. The resource has a URI that identifies what should be read; the client asks the server for its contents using the protocol's &lt;code&gt;resources/read&lt;/code&gt; operation. This is different from inventing a separate tool and input schema for every kind of document.&lt;/p&gt;

&lt;p&gt;In Claude Code, a user can type &lt;code&gt;@&lt;/code&gt; to find resources from connected MCP servers alongside local files. A particular resource can be referenced in a prompt as &lt;code&gt;@server:protocol://resource/path&lt;/code&gt;. When referenced, Claude Code fetches it and includes it as an attachment. It also provides general list-and-read tools for MCP resources when connected servers support them.&lt;/p&gt;

&lt;p&gt;That is the useful contrast with &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4&lt;/a&gt;. MCP tools are distinct operations whose descriptions and schemas matter individually. Resource discovery and reading are standardized operations; the interesting variation lies in the URIs and the content they return. Claude Code does not need to register a new specialized “read this server's document” tool every time another server is connected.&lt;/p&gt;

&lt;p&gt;Resources are often read-oriented context, but “resource” should not be mistaken for a guarantee that every URI is an ordinary text file. MCP resource responses may carry text or binary data, with MIME types indicating what was returned. Claude Code's handling of large or binary output can keep it from dumping an encoded blob directly into the conversation: the implementation examined for this series stores some binary resource content separately and returns a path and description instead. The model can then use the appropriate file workflow if it actually needs to inspect that content.&lt;/p&gt;

&lt;p&gt;There is also a boundary worth noting in current Claude Code documentation. Some MCP resources are &lt;strong&gt;MCP Apps UI resources&lt;/strong&gt;, intended for a host application to render. They do not appear in the normal &lt;code&gt;@&lt;/code&gt; resource suggestions or list-tool results, even though reading one by its URI can work. “The server exposes a resource” does not necessarily mean “the resource appears as a document in autocomplete.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Elicitation: the server asks the user mid-task
&lt;/h2&gt;

&lt;p&gt;Sometimes the server cannot finish an operation with the inputs it has. It may need a missing field, a choice that only the user can make, or a browser-based authorization step. &lt;strong&gt;Elicitation&lt;/strong&gt; is the MCP mechanism for asking the client to obtain that information from a person and return an answer to the server.&lt;/p&gt;

&lt;p&gt;This reverses the usual direction of a tool call. Claude or the client initiated an operation, but the server now has a question. The client remains responsible for presenting that question and controlling what information is shared. Elicitation is not a license for a remote server to silently scrape user input.&lt;/p&gt;

&lt;p&gt;The capability is negotiated as part of the MCP connection discussed in &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;Part 2&lt;/a&gt;. A server can use a mode only when the client has declared that it supports it. In current Claude Code, the user-facing forms are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Form mode:&lt;/strong&gt; Claude Code displays fields supplied by the server and returns the submitted answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL mode:&lt;/strong&gt; Claude Code asks whether to open an external link, so the user can finish a step such as sign-in in the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude Code's documentation says no special user configuration is required for these dialogs to appear. It also documents an &lt;code&gt;Elicitation&lt;/code&gt; hook that can supply a programmatic response without showing a dialog. That shortcut is a client-side automation choice, not the general definition of elicitation in the MCP protocol. It should be configured with care: an automatic answer may be appropriate for a predictable, low-risk question, but not for a consent decision the user ought to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why protocol version matters here
&lt;/h2&gt;

&lt;p&gt;Elicitation is younger than the basic tools-and-resources model. The June 2025 specification explicitly introduced it as a feature whose design could evolve. Current Claude Code documentation describes form and URL modes, with the capabilities it declares varying by the protocol revision used on a connection.&lt;/p&gt;

&lt;p&gt;The MCP specification has also been moving toward stateless operation and more explicit ways to resume work after user input. In that model, a server need not hold an entire request and connection open while a person thinks or switches to a browser; it can return a description of the missing input and enough state to continue later. That direction is useful for scalable server deployments, but it is important not to treat every revision's interaction details as interchangeable. Check the protocol version and client support when implementing or debugging elicitation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bigger picture
&lt;/h2&gt;

&lt;p&gt;Tools, resources, and elicitation solve different problems:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Direction&lt;/th&gt;
&lt;th&gt;Main purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tool&lt;/td&gt;
&lt;td&gt;Client → server&lt;/td&gt;
&lt;td&gt;Invoke an operation with structured arguments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource&lt;/td&gt;
&lt;td&gt;Client → server&lt;/td&gt;
&lt;td&gt;Retrieve context identified by a URI.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Elicitation&lt;/td&gt;
&lt;td&gt;Server → client → user&lt;/td&gt;
&lt;td&gt;Obtain missing information while work is underway.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The same MCP connection can make all three useful, but it does not force them into the same UI or permission path. An issue tracker may expose actions for editing issues, resources for reading existing issue data, and elicitation for a decision that cannot safely be inferred.&lt;/p&gt;

&lt;p&gt;Next, the series changes perspective. Claude Code is not only an MCP client that connects to other servers; it can also run as an MCP server and offer capabilities to another client.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: MCP resources and elicitation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/server/resources" rel="noopener noreferrer"&gt;MCP specification: Resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/client/elicitation" rel="noopener noreferrer"&gt;MCP specification: Elicitation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/" rel="noopener noreferrer"&gt;MCP specification release candidate: protocol evolution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4: From Tools List to an Entry in the Tool List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;Part 2: From a Configuration Entry to a Handshake&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (6): From One Authorization to Multiple Servers</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Wed, 28 Oct 2026 02:02:40 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-6-from-one-authorization-to-multiple-servers-4g1c</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-6-from-one-authorization-to-multiple-servers-4g1c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A remote MCP server that needs authentication has not necessarily failed to connect permanently. Claude Code can guide a user through browser-based OAuth, retain credentials securely, and refresh them later. In an enterprise deployment that supports Cross-App Access, one login to the organization's identity provider can also be reused to obtain server-specific access tokens without a separate browser prompt for every server.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0"&gt;Part 5&lt;/a&gt; explored the permission decision &lt;em&gt;after&lt;/em&gt; a tool becomes available. But &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;Part 2&lt;/a&gt; left another gate open: what happens when a remote server exists in configuration but cannot yet authenticate the client?&lt;/p&gt;

&lt;p&gt;This is a different problem from deciding whether Claude may invoke a tool. OAuth determines whether the MCP client has a credential that the remote service accepts. Claude Code's tool permissions determine whether an individual call should proceed. Passing one gate does not automatically pass the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  “Needs authentication” is an actionable state
&lt;/h2&gt;

&lt;p&gt;Claude Code distinguishes a remote server that needs sign-in from an ordinary connection failure. Its current documentation says that an HTTP &lt;code&gt;401 Unauthorized&lt;/code&gt; or &lt;code&gt;403 Forbidden&lt;/code&gt; can mark a remote server as needing authentication. The &lt;code&gt;/mcp&lt;/code&gt; panel shows which servers need sign-in; an interactive user can authenticate there, or run &lt;code&gt;claude mcp login &amp;lt;name&amp;gt;&lt;/code&gt; from a shell.&lt;/p&gt;

&lt;p&gt;The distinction matters because an authentication challenge has a clear next step. The server definition does not need to be deleted and recreated merely because credentials are missing. Finish the authorization flow and Claude Code can reconnect with valid credentials.&lt;/p&gt;

&lt;p&gt;The code path examined for this series also includes a useful bridge back into the model's tool list. For an eligible server in the &lt;code&gt;needs-auth&lt;/code&gt; state, it can expose a synthetic &lt;code&gt;mcp__&amp;lt;server&amp;gt;__authenticate&lt;/code&gt; tool instead of leaving the model with no actionable capability. Calling that tool starts the OAuth flow and returns an authorization URL for the user. Once the callback succeeds, the client reconnects and replaces the temporary authentication entry with the server's real tools. This model-facing route complements the documented &lt;code&gt;/mcp&lt;/code&gt; and CLI routes; it does not mean the model can sign in on the user's behalf.&lt;/p&gt;

&lt;p&gt;There are boundaries to this behavior. The synthetic entry is for the HTTP/SSE OAuth path in the implementation examined here. A claude.ai connector uses its own authorization flow, and a noninteractive run cannot simply pop open an interactive &lt;code&gt;/mcp&lt;/code&gt; sign-in dialog. In those cases the user needs the appropriate interactive route first.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ordinary OAuth round trip
&lt;/h2&gt;

&lt;p&gt;For a remote server that supports OAuth, the sequence is familiar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude Code discovers the authorization information associated with the remote MCP endpoint.&lt;/li&gt;
&lt;li&gt;It starts a temporary local callback listener and opens, or provides, the authorization URL.&lt;/li&gt;
&lt;li&gt;The user signs in and grants the requested access in a browser.&lt;/li&gt;
&lt;li&gt;The authorization server redirects to the callback address with an authorization result.&lt;/li&gt;
&lt;li&gt;Claude Code exchanges that result for credentials, stores them securely, and reconnects to the MCP server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Claude Code's documentation notes that tokens are stored securely and refreshed automatically. That should not be paraphrased as “the token is always in the operating system keychain on every platform”: storage details vary by platform and credential type. The practical point is that the access token is not meant to be pasted into a shared &lt;code&gt;.mcp.json&lt;/code&gt; server definition.&lt;/p&gt;

&lt;p&gt;The browser step also has a headless-friendly path. If no local browser is available—for example, when &lt;code&gt;claude mcp login &amp;lt;name&amp;gt;&lt;/code&gt; runs over SSH—the command prints the authorization URL. The user opens it on a machine with a browser and pastes the &lt;strong&gt;full redirect URL&lt;/strong&gt; back into the interactive terminal. A failed browser redirect can be recovered in the same way. This is why the flow can still work when the terminal and browser are not on the same machine.&lt;/p&gt;

&lt;p&gt;Once signed in, the ordinary case is quiet: Claude Code refreshes credentials when needed rather than requiring a browser login for every tool call. If an already-authorized remote server rejects a stored token with &lt;code&gt;401&lt;/code&gt;, current documentation says Claude Code refreshes it, reconnects, and retries the request once. Only if recovery fails does it surface the need to re-authenticate. A configured static &lt;code&gt;Authorization&lt;/code&gt; header is different: if the server rejects that header, Claude Code reports a failed connection instead of silently switching to OAuth.&lt;/p&gt;

&lt;h2&gt;
  
  
  One enterprise identity, several server-specific tokens
&lt;/h2&gt;

&lt;p&gt;A team may operate separate MCP servers for issues, documents, metrics, and internal APIs. Making every employee complete an unrelated browser consent flow for each server is cumbersome. Enterprise-Managed Authorization, also called &lt;strong&gt;Cross-App Access&lt;/strong&gt; (SEP-990), addresses this with a shared enterprise identity provider (IdP).&lt;/p&gt;

&lt;p&gt;The high-level sequence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One browser login to the enterprise IdP
  → reusable IdP identity token
  → token exchange for the target MCP authorization server
  → server-specific MCP access token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intermediate exchanges are not a claim that one bearer token should be sent indiscriminately to every server. The client uses the existing enterprise identity to request a credential scoped to the target authorization server. The MCP TypeScript SDK describes the two protocol steps: RFC 8693 token exchange produces an Identity Assertion Authorization Grant (ID-JAG), and RFC 7523's JWT bearer grant exchanges that assertion for an access token at the MCP authorization server.&lt;/p&gt;

&lt;p&gt;In the Claude Code implementation examined for this series, the IdP login is cached and reused across servers configured for this flow. The IdP connection is configured once, while each participating MCP server opts in and supplies the details its authorization server needs. With a valid cached identity token, a subsequent server can complete the exchange without another browser interruption. It is &lt;strong&gt;not&lt;/strong&gt; an unconditional “log in once and gain access to every server” promise: the enterprise IdP, each authorization server, the server configuration, and organizational policy must all support and permit the exchange.&lt;/p&gt;

&lt;p&gt;This path is explicitly gated. The implementation uses a feature switch and enterprise IdP setup, and a server that opts into Cross-App Access does not silently fall back to ordinary per-server OAuth if the enterprise flow is misconfigured. A visible error is better than an ambiguous security posture where the configuration says one thing and the client does another.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication can expire after a successful connection
&lt;/h2&gt;

&lt;p&gt;A sign-in problem can arise at two points. The first is the initial connection, before the client can list tools. The second is later, after a working server rejects a call because a token expired, was revoked, or lacks the required scope.&lt;/p&gt;

&lt;p&gt;The recovery path is not always “show the browser again.” Claude Code first uses its stored refresh credential where possible, reconnects, and retries once. If the refresh token itself is rejected, it points the user back to &lt;code&gt;/mcp&lt;/code&gt; for re-authentication. If the server requests an additional OAuth scope, that is a different signal: the client may need a new consent flow with the appropriate scope, and an administrator's pinned scope policy may need review.&lt;/p&gt;

&lt;p&gt;Treating these outcomes distinctly prevents two mistakes. A transient &lt;code&gt;401&lt;/code&gt; need not make a working integration look permanently broken, while a genuinely missing permission must not be hidden behind endless retries. The server's authentication state and the next action should remain legible to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to remember
&lt;/h2&gt;

&lt;p&gt;An MCP connection can be configured, discoverable, and still unusable until the client is authenticated. Claude Code's OAuth flow turns that state into an actionable sign-in path; secure credential storage and refresh make subsequent use less disruptive. Enterprise Cross-App Access can reduce repeated sign-ins further, but only for servers and organizations explicitly configured to support it.&lt;/p&gt;

&lt;p&gt;The next article moves beyond tool calls. MCP servers can also offer resources for reading, and elicitation provides a way to request information from the user while a server-side workflow is in progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Connect Claude Code to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ts.sdk.modelcontextprotocol.io/v2/api/%40modelcontextprotocol/client/client/authExtensions.html" rel="noopener noreferrer"&gt;MCP TypeScript SDK: Cross-App Access provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ts.sdk.modelcontextprotocol.io/v2/api/%40modelcontextprotocol/client/client/crossAppAccess.html" rel="noopener noreferrer"&gt;MCP TypeScript SDK: Cross-App Access protocol utilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.modelcontextprotocol.io/posts/enterprise-managed-auth/" rel="noopener noreferrer"&gt;MCP: Enterprise-Managed Authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0"&gt;Part 5: From Tool Name Matching to Server-Level Authorization&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;Part 2: From a Configuration Entry to a Handshake&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (5): From Tool Name Matching to Server-Level Authorization</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Tue, 27 Oct 2026 02:08:47 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-5-from-tool-name-matching-to-server-level-authorization-ke0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; An MCP tool’s canonical name carries its server identity. That gives Claude Code a useful permission scope: a single rule can cover every tool from one server. It does &lt;strong&gt;not&lt;/strong&gt; make an external tool intrinsically safe, though. In the usual manual-permission flow, a call without an applicable allow rule asks the user; a server can also mark a sensitive tool as requiring an explicit approval on every call.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;The previous article&lt;/a&gt; ended at the point where a discovered MCP capability becomes a tool in Claude Code’s tool list. That raises the next question: once Claude can see a renamed MCP tool, may it simply invoke it?&lt;/p&gt;

&lt;p&gt;The answer is shaped by the permission system. This article focuses on the MCP-specific part of that system: how a tool name becomes a policy boundary, why that boundary can be a whole server, and why server trust and per-call authorization remain separate decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  One rule can cover an entire server
&lt;/h2&gt;

&lt;p&gt;A Claude Code MCP tool is named in the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__&amp;lt;server&amp;gt;__&amp;lt;tool&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That name is more than display metadata. It preserves where the capability came from. For example, the tool name &lt;code&gt;mcp__jira__create_issue&lt;/code&gt; says both &lt;em&gt;what&lt;/em&gt; Claude wants to call and &lt;em&gt;which server&lt;/em&gt; provides it. The MCP protocol itself asks a client to discover tools with &lt;code&gt;tools/list&lt;/code&gt;; each tool definition has a unique name, a description, and an input schema. Claude Code adds the server-qualified name so that separately connected servers do not collapse into one flat, ambiguous namespace.&lt;/p&gt;

&lt;p&gt;That structure gives permission rules a useful extra level of granularity. According to Claude Code’s current permission syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"mcp__jira__*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule matches every tool exposed by the &lt;code&gt;jira&lt;/code&gt; server. A rule such as &lt;code&gt;mcp__jira__create_issue&lt;/code&gt; instead targets just that one tool. For a configured server with punctuation or spaces, Claude Code uses its normalized server segment in the tool name. A server supplied by a plugin uses a plugin-scoped server name.&lt;/p&gt;

&lt;p&gt;This is particularly practical for a server that exposes a family of related operations. A Jira server might provide issue lookup, creation, comments, transitions, and project metadata. A team can decide that this specific integration is acceptable and express the policy once, rather than maintain an ever-growing list of individual tool names as the server evolves.&lt;/p&gt;

&lt;p&gt;There is an important constraint: allow-rule wildcards are intentionally narrower than deny and ask wildcards. An allow rule needs the literal &lt;code&gt;mcp__&amp;lt;server&amp;gt;__&lt;/code&gt; prefix, so a broad entry such as &lt;code&gt;mcp__*&lt;/code&gt; does not silently auto-approve every MCP tool from every server. The policy must name the particular configured server it trusts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The name creates a policy boundary
&lt;/h2&gt;

&lt;p&gt;The useful comparison is not “MCP tools versus safe built-in tools.” It is “a capability from a known server versus a capability from somewhere else.” Claude Code’s built-in tools can have tool-specific rules and, for some categories, additional action-specific handling. An MCP tool is an extension supplied by a server: it can query an API, edit a ticket, read a database, or trigger an operation outside the local project.&lt;/p&gt;

&lt;p&gt;Its server-qualified name lets the client apply a consistent rule before issuing the &lt;code&gt;tools/call&lt;/code&gt; request:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server advertises a tool through &lt;code&gt;tools/list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Claude Code gives the exposed capability a full &lt;code&gt;mcp__&amp;lt;server&amp;gt;__&amp;lt;tool&amp;gt;&lt;/code&gt; name.&lt;/li&gt;
&lt;li&gt;Permission policy checks that canonical name against deny, ask, and allow rules.&lt;/li&gt;
&lt;li&gt;Only an allowed call is sent to the server as &lt;code&gt;tools/call&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is also why a server-wide rule is meaningful. It does not claim that all tools are harmless; it records a deliberate trust decision about the server namespace. An organization may allow all tools from an approved internal service, ask before calls to a staging service, and deny an unapproved server altogether.&lt;/p&gt;

&lt;p&gt;The reverse works too. A deny or ask rule can use a full-name pattern such as &lt;code&gt;mcp__*&lt;/code&gt; to govern MCP tools across servers. A policy can therefore make the default posture explicit rather than relying on the apparent friendliness of a tool’s description.&lt;/p&gt;

&lt;h2&gt;
  
  
  No rule should be mistaken for no decision
&lt;/h2&gt;

&lt;p&gt;In Manual mode, Claude Code’s permission system normally presents an approval prompt for actions that require approval. MCP tool prompts are part of that flow, and the permission dialog lets the user approve or deny the proposed call. A matching allow rule can avoid routine prompts for the precise scope it names; a deny rule blocks the call.&lt;/p&gt;

&lt;p&gt;That distinction matters when installing a new MCP server. Connecting a server, exposing its tools, and authorizing a particular action are related but different events. A server may be correctly configured and successfully connected while its tools still require approval according to the active policy.&lt;/p&gt;

&lt;p&gt;The Model Context Protocol makes the same safety principle explicit: implementations should keep a human able to deny tool invocations, show which tools are exposed, and present confirmations for operations. The protocol defines how a server advertises and receives tool calls; it does not declare that a given remote operation is safe.&lt;/p&gt;

&lt;p&gt;Claude Code also supports a stronger signal from the server itself. An MCP server author can set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"_meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"anthropic/requiresUserInteraction"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;on an individual &lt;code&gt;tools/list&lt;/code&gt; entry. Claude Code then requires an explicit approval on &lt;strong&gt;every&lt;/strong&gt; call to that tool, even if a matching allow rule exists or a permissive mode is active. This is appropriate for actions where the human confirmation is itself the point, such as granting access to a protected resource.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust is layered, not inherited
&lt;/h2&gt;

&lt;p&gt;The server-level wildcard is a convenience, not an automatic security proof. MCP servers may reach external services and handle data outside Claude Code’s local runtime. Claude Code’s MCP documentation therefore advises users to verify that they trust each server before connecting it, especially when a server can fetch external content and expose prompt-injection risk.&lt;/p&gt;

&lt;p&gt;A sound policy separates several questions:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Example decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Should this server connect?&lt;/td&gt;
&lt;td&gt;Approve a known internal Jira server; reject an unknown one.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Should Claude see this capability?&lt;/td&gt;
&lt;td&gt;Deny a particular tool or all tools from a server.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Should this call run now?&lt;/td&gt;
&lt;td&gt;Ask for approval, or allow a narrowly defined trusted scope.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Must a person always confirm?&lt;/td&gt;
&lt;td&gt;Mark a sensitive server tool with &lt;code&gt;requiresUserInteraction&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This layered model is more durable than trying to infer safety from a tool name or natural-language description. A permission rule makes the intended boundary visible, reviewable, and shareable through settings. The server still owns the implementation; the client still owns the decision to invoke it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to remember
&lt;/h2&gt;

&lt;p&gt;MCP tool names encode provenance, and that provenance becomes a practical authorization boundary. Use a full tool name when one operation deserves its own policy. Use &lt;code&gt;mcp__&amp;lt;server&amp;gt;__*&lt;/code&gt; when a team has consciously chosen to trust a particular server’s whole tool family. Avoid broad allow rules that erase the distinction between servers.&lt;/p&gt;

&lt;p&gt;Most importantly, do not equate discovery with authorization. Seeing a tool in the list means Claude Code knows how to call it. A permission rule and, when appropriate, a human approval determine whether it should call it now.&lt;/p&gt;

&lt;p&gt;The next article follows the other gate that can prevent a server from becoming usable: authentication. We will trace how a server moves from “needs authentication” to an active connection, including the browser-based authorization step and how credentials can be reused across servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/permissions" rel="noopener noreferrer"&gt;Claude Code: Configure permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Connect Claude Code to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/server/tools" rel="noopener noreferrer"&gt;Model Context Protocol specification: Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53"&gt;Part 4: From Tools List to an Entry in the Tool List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1: From Built-In Tools to Extensible Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (4): From Tools List to an Entry in the Tool List</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Mon, 26 Oct 2026 05:37:49 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-4-from-tools-list-to-an-entry-in-the-tool-list-3i53</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; An MCP server can say, “I have a tool named &lt;code&gt;create_issue&lt;/code&gt;,” but Claude Code does not simply put that bare name beside its built-in tools. It gives the tool a namespaced callable identity and adapts the server’s definition into the client’s tool surface. The namespace prevents collisions; the adapter makes a built-in action and an external action look like one coherent tool system to the model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb"&gt;The previous article&lt;/a&gt; covered how bytes move between Claude Code and an MCP server. This article starts after the connection and initialization succeed: how does a tool declared by the server become something the model can actually call?&lt;/p&gt;

&lt;h2&gt;
  
  
  First, give every external tool a stable namespace
&lt;/h2&gt;

&lt;p&gt;Imagine two connected servers, &lt;code&gt;jira&lt;/code&gt; and &lt;code&gt;linear&lt;/code&gt;. Both happen to offer a tool called &lt;code&gt;create_issue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If a client placed two bare &lt;code&gt;create_issue&lt;/code&gt; entries in a shared tool list, the model would have no reliable way to select one. The collision can be even more confusing when a server declares a name that resembles a built-in tool. A call named &lt;code&gt;Write&lt;/code&gt; should not ambiguously mean either “write a local file” or “invoke an unrelated external service.”&lt;/p&gt;

&lt;p&gt;Claude Code resolves this by constructing a callable name that records the tool's origin. For a normally configured server, the shape is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__&amp;lt;server-name&amp;gt;__&amp;lt;tool-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the two issue-creation tools become distinct entries such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__jira__create_issue
mcp__linear__create_issue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact shape can gain more scope when a plugin bundles the server. Claude Code's current documentation, for example, gives plugin-provided tools the form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__plugin_&amp;lt;plugin-name&amp;gt;_&amp;lt;server-name&amp;gt;__&amp;lt;tool-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That additional context is not cosmetic. It lets names remain unique even when plugins, manually configured servers, and built-in capabilities share a session.&lt;/p&gt;

&lt;p&gt;A useful consequence is that a tool name is also provenance information. The &lt;code&gt;mcp__&lt;/code&gt; prefix signals an MCP-provided capability, and the following namespace identifies the server that owns it. In the next article, that naming pattern will matter again because permission rules can target a server's tools as a group rather than requiring one rule per tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The server supplies the tool contract
&lt;/h2&gt;

&lt;p&gt;Built-in tools are implemented and described by Claude Code itself. An MCP tool arrives differently: the server declares it through the protocol.&lt;/p&gt;

&lt;p&gt;The MCP &lt;code&gt;tools/list&lt;/code&gt; response includes a tool name, a human-readable description, and an &lt;code&gt;inputSchema&lt;/code&gt; expressed as JSON Schema. It may also include a title, an output schema, and annotations. Claude Code can use that declaration to present a call surface to the model without inventing a second, client-owned parameter format for every server.&lt;/p&gt;

&lt;p&gt;This is an important division of responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The server&lt;/strong&gt; owns the meaning of its tool and the shape of its arguments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The client&lt;/strong&gt; owns connection, namespacing, tool availability, presentation, and safety controls.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model&lt;/strong&gt; receives a usable tool definition and decides whether that capability fits the user's request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suppose a server declares this simplified tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"create_issue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Create an issue in the selected project"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inputSchema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"object"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client does not need to translate &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; into a separate proprietary language before the model can use them. It preserves the server's contract while wrapping the invocation route: when the model calls the namespaced tool, Claude Code can map it back to the owning server and issue the corresponding &lt;code&gt;tools/call&lt;/code&gt; request.&lt;/p&gt;

&lt;p&gt;That is why adding an MCP server can add useful capabilities without requiring Claude Code to ship a new built-in implementation for each service. The server provides the domain-specific schema and behavior; the client provides the integration framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  One tool surface, regardless of origin
&lt;/h2&gt;

&lt;p&gt;After adaptation, an MCP tool participates in the same broad decision loop as a built-in tool: it has a callable name, a description, an input contract, and a result.&lt;/p&gt;

&lt;p&gt;The model should not need a separate decision procedure just because one action came from a remote issue tracker and another came from the local environment. It evaluates the available capabilities against the request, chooses an action, supplies arguments, and receives a result.&lt;/p&gt;

&lt;p&gt;That does not mean origin disappears. It remains important for permissions, connection health, timeouts, and diagnostics. But it is intentionally not a burden on the model-facing interface. The client hides the transport and server-routing machinery behind a consistent tool abstraction.&lt;/p&gt;

&lt;p&gt;For server authors, this has a practical implication: invest in a precise description and a clear JSON Schema. A vague description or underspecified schema does not become clearer when it crosses the MCP boundary. The client's wrapper can make the tool available; only the server can explain what a valid invocation means.&lt;/p&gt;

&lt;h2&gt;
  
  
  A namespace is safer than a replacement
&lt;/h2&gt;

&lt;p&gt;The normal behavior is namespacing, not replacement. A distinct &lt;code&gt;mcp__...&lt;/code&gt; callable name means an external tool cannot silently shadow a built-in tool with the same short name.&lt;/p&gt;

&lt;p&gt;Some embedding environments can make more specialized choices about their tool surface, including in-process SDK-hosted servers. Those are host-level design decisions, not a reason for a normally configured third-party server to depend on unprefixed overrides. Claude Code's public MCP configuration documentation explicitly distinguishes an SDK-only in-process server type from the regular configuration types.&lt;/p&gt;

&lt;p&gt;The boundary is worth keeping clear: if a system intentionally replaces or aliases a capability, it still needs reliable internal provenance for routing and permissions. A display or callable name alone cannot be the whole security model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources should not multiply into duplicate tools
&lt;/h2&gt;

&lt;p&gt;MCP has more than tools. Servers may also offer &lt;strong&gt;resources&lt;/strong&gt;: readable pieces of context or data.&lt;/p&gt;

&lt;p&gt;It would be wasteful for every resource-capable server to register its own separate “list resources” and “read resource” tools with identical client-side behavior. A client can instead expose generic resource operations and route a selected resource back to the server that owns it. The user-facing result is a single resource capability model rather than a list that grows with duplicated plumbing every time another server connects.&lt;/p&gt;

&lt;p&gt;The same principle appears throughout a good integration layer: server-specific content belongs to the server; cross-server mechanics belong to the client. A later article will examine resources and elicitation in more detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  A tool list can change after connection
&lt;/h2&gt;

&lt;p&gt;A connection does not freeze a server's capabilities forever. An MCP server that declares the &lt;code&gt;tools&lt;/code&gt; capability can say that its list may change by advertising &lt;code&gt;listChanged&lt;/code&gt;. When the list changes, the server can send a &lt;code&gt;notifications/tools/list_changed&lt;/code&gt; notification.&lt;/p&gt;

&lt;p&gt;Claude Code handles this as a refresh problem rather than requiring the user to disconnect and reconnect the server. Its current documentation says that an interactive session fetches the updated list; &lt;code&gt;claude -p&lt;/code&gt; and Agent SDK sessions refresh the tool list on the notification. If refresh fails, Claude Code keeps the previously discovered tools, prompts, and resources until a later refresh succeeds.&lt;/p&gt;

&lt;p&gt;This explains an otherwise surprising observation: an MCP server can gain or lose a tool during one session without a manual reconnection. The list was not permanently copied at handshake time; it is a cached view that the protocol allows the server to invalidate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Many servers, one coherent result
&lt;/h2&gt;

&lt;p&gt;With several MCP servers installed, connections can complete at different times. One local process may start quickly while a remote service takes longer; another server may still be authenticating.&lt;/p&gt;

&lt;p&gt;The important conceptual result is not the order of those events. Claude Code maintains a unified tool surface with stable naming and routes each namespaced call to the server that provided it. The model sees a coherent set of capabilities rather than needing to reason about a separate ad hoc interface for every connection.&lt;/p&gt;

&lt;p&gt;This same design can scale further with tool search and deferred loading, but the basic transformation remains the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A server advertises a tool through &lt;code&gt;tools/list&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Claude Code associates it with the server that advertised it.&lt;/li&gt;
&lt;li&gt;Claude Code gives it a collision-safe callable identity and exposes its schema.&lt;/li&gt;
&lt;li&gt;A later call is routed back to that server as &lt;code&gt;tools/call&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Next: naming becomes a permission boundary
&lt;/h2&gt;

&lt;p&gt;A namespaced MCP tool appearing in the list does not mean every call is automatically approved. One of the questions from the opening article was: who gets to authorize the action?&lt;/p&gt;

&lt;p&gt;The naming rule introduced here makes it possible to describe permissions at a useful granularity, including rules that cover an entire server. The next article continues from that boundary: &lt;strong&gt;from matching a tool name to server-level authorization&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/server/tools" rel="noopener noreferrer"&gt;MCP specification: Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Connect to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;Part 0: The Connection Lifecycle and Tool Exposure Map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1: From Built-In Tools to Extensible Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb"&gt;Part 3: From a Child Process to a Remote Service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (3): From a Child Process to a Remote Service</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Sat, 24 Oct 2026 04:20:59 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-3-from-a-child-process-to-a-remote-service-49nb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; The MCP specification defines two standard transports: a locally launched subprocess over &lt;code&gt;stdio&lt;/code&gt;, and a remote endpoint using Streamable HTTP. Claude Code also documents compatibility paths such as legacy SSE and WebSocket. Those client-specific options should not be mistaken for the protocol's portable baseline. The transport moves bytes; it does not decide which tools, resources, or prompts the server exposes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;The previous article&lt;/a&gt; ended just before the handshake: Claude Code knows a server exists, but it still needs a way to speak to it.&lt;/p&gt;

&lt;p&gt;MCP calls that way of speaking a &lt;strong&gt;transport&lt;/strong&gt;. A transport determines how messages travel between client and server. It is separate from the question of &lt;em&gt;what&lt;/em&gt; those messages describe—tools, resources, prompts, and the other capabilities a server may advertise. The next article will examine how a declared server tool enters Claude Code's tool list.&lt;/p&gt;

&lt;h2&gt;
  
  
  The protocol standardizes two transports
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol standard defines two standard client-server transports:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;stdio&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streamable HTTP&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both carry the same JSON-RPC messages. That separation is deliberate: once the protocol layer abstracts the communication mechanism, the application-level interaction should look the same regardless of the transport.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;stdio&lt;/code&gt;: launch a local subprocess
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;stdio&lt;/code&gt;, the client starts the MCP server as a child process. The server reads JSON-RPC messages from standard input and writes JSON-RPC messages to standard output. Its standard error stream remains available for logging, but standard output must contain valid MCP messages only.&lt;/p&gt;

&lt;p&gt;This is the natural shape for a local integration. If an issue-tracker helper is an executable installed on your machine, Claude Code can launch it directly rather than putting a network hop in the middle. Claude Code's MCP documentation describes local &lt;code&gt;stdio&lt;/code&gt; servers as a fit for custom scripts and tools that need direct access to the system.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;stdio&lt;/code&gt; transport is not “MCP over a terminal” in the casual sense. The process boundary matters. Claude Code owns the child process lifecycle, while the server owns the logic behind the protocol. If the server exits, the connection is gone because the program that supplied it is gone.&lt;/p&gt;

&lt;h3&gt;
  
  
  Streamable HTTP: connect to a remote endpoint
&lt;/h3&gt;

&lt;p&gt;Streamable HTTP is the standard remote option. The client sends JSON-RPC messages with HTTP requests, and the server may return either a normal JSON response or an SSE stream. A server can also use an HTTP GET request to open an SSE stream for server-to-client messages.&lt;/p&gt;

&lt;p&gt;This replaced the older HTTP-plus-SSE transport from the 2024-11-05 protocol revision. The current specification keeps a backwards-compatibility path, but new servers should implement Streamable HTTP rather than build on the retired design.&lt;/p&gt;

&lt;p&gt;For a remote server, this distinction matters operationally as well as architecturally. An HTTP endpoint may be separately deployed, authenticated, monitored, and shared by many clients. The transport boundary is now a network boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  The same message shape travels through either path
&lt;/h2&gt;

&lt;p&gt;A transport is a delivery mechanism, not a capability model.&lt;/p&gt;

&lt;p&gt;Whether the server is a subprocess or an HTTPS endpoint, the client and server exchange JSON-RPC protocol messages. The server implementation should not need one set of tool semantics for local use and a different set for remote use. It can expose a &lt;code&gt;tools/list&lt;/code&gt; response, accept &lt;code&gt;tools/call&lt;/code&gt;, and participate in initialization with the same MCP-level meaning on either transport.&lt;/p&gt;

&lt;p&gt;That is the practical payoff of the abstraction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the connection layer chooses how messages get there;&lt;/li&gt;
&lt;li&gt;the protocol layer gives those messages a common shape; and&lt;/li&gt;
&lt;li&gt;later layers decide how discovered capabilities become available to the agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the code that discovers a tool or calls it, “local process” and “remote service” should not produce two unrelated APIs. They are two implementations of the same connection contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code supports more than the portable baseline
&lt;/h2&gt;

&lt;p&gt;The protocol's two standard transports are the portable baseline. A particular MCP client can additionally support compatibility or product-specific connection paths, and Claude Code does.&lt;/p&gt;

&lt;p&gt;Its current public documentation describes four externally configurable server types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local &lt;code&gt;stdio&lt;/code&gt; servers;&lt;/li&gt;
&lt;li&gt;remote HTTP servers, with &lt;code&gt;streamable-http&lt;/code&gt; accepted as an alias in JSON configuration;&lt;/li&gt;
&lt;li&gt;legacy remote SSE servers; and&lt;/li&gt;
&lt;li&gt;remote WebSocket servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The latter two are useful examples of the difference between a specification and a client implementation. SSE remains available because some services still expose an older endpoint, but Claude Code marks it deprecated and recommends HTTP when possible. WebSocket is a persistent bidirectional connection that is useful for servers that push events without waiting for a request; Claude Code's own docs recommend HTTP when a server only needs request-response behavior.&lt;/p&gt;

&lt;p&gt;MCP itself also permits pluggable custom transports. That permission does &lt;strong&gt;not&lt;/strong&gt; make every client-specific transport universally available. When you build a third-party server intended to interoperate broadly, &lt;code&gt;stdio&lt;/code&gt; and Streamable HTTP are the dependable choices because they are the two mechanisms the specification standardizes.&lt;/p&gt;

&lt;p&gt;The distinction is easy to blur when reading a client codebase. A client may contain adapters for legacy protocols, SDK-hosted integrations, browser or IDE components, or internal wiring that reuse MCP's message handling. Reuse of the message format and lifecycle code does not turn each internal pathway into a general-purpose transport that an outside server author should choose.&lt;/p&gt;

&lt;h2&gt;
  
  
  An in-process integration can remove the channel entirely
&lt;/h2&gt;

&lt;p&gt;The most extreme client-specific case is an in-process integration: no child process and no network request. Both sides are already in the same process, so they can exchange messages directly while presenting a common MCP-shaped interface to code above them.&lt;/p&gt;

&lt;p&gt;Why preserve the abstraction when there is no real transport to manage? Because the rest of the client benefits from a uniform contract. The capability-discovery layer does not need separate logic for “a remote server,” “a local executable,” and “a built-in integration.” It can ask for tools, resources, and prompts through one conceptual interface.&lt;/p&gt;

&lt;p&gt;This illustrates what the transport layer is buying: upper layers should not need to care how the bytes moved—or, in an in-process case, whether bytes crossed a boundary at all. The next stage can focus on naming, discovery, permissions, and invocation instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Local and remote failures have different recovery paths
&lt;/h2&gt;

&lt;p&gt;A transport choice also changes what a disconnection means.&lt;/p&gt;

&lt;p&gt;For a local &lt;code&gt;stdio&lt;/code&gt; server, an exit or failed startup points to a process-level problem: a missing executable, invalid arguments, a bad environment, or a crash. Claude Code's current guidance does not automatically retry a failed first &lt;code&gt;stdio&lt;/code&gt; connection. In an interactive session, the server is marked failed and can be reconnected from &lt;code&gt;/mcp&lt;/code&gt;; in a non-interactive run, a later run or tool call provides the next opportunity to start it again.&lt;/p&gt;

&lt;p&gt;A remote connection has a different failure model. A server may be healthy while a network request times out, a proxy returns a transient error, or a connection drops mid-session. Claude Code therefore retries transient remote failures. For a dropped remote server, it first makes up to five reconnection attempts with exponential backoff beginning at one second. For an initial HTTP or SSE connection that fails transiently, it retries up to three times.&lt;/p&gt;

&lt;p&gt;These rules are not a claim that local failures are never transient or that network failures always are. They encode a useful operational default:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a local process failure often needs configuration or environment diagnosis;&lt;/li&gt;
&lt;li&gt;a remote interruption is more likely to benefit from a bounded retry; and&lt;/li&gt;
&lt;li&gt;authentication and not-found errors should normally be fixed rather than blindly retried.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are details by runtime and server type. In particular, the documented initial-connection retries apply to HTTP and SSE, not &lt;code&gt;stdio&lt;/code&gt; or WebSocket. Treat the transport as part of the diagnosis, not just a field in configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boundary to carry forward
&lt;/h2&gt;

&lt;p&gt;The useful mental model is simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The MCP specification&lt;/strong&gt; provides the interoperable baseline: &lt;code&gt;stdio&lt;/code&gt; and Streamable HTTP.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; can support additional compatibility and product-specific paths, including legacy SSE and WebSocket in its public configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher layers&lt;/strong&gt; should work with the capabilities discovered through the connection, rather than hard-coding assumptions about the channel underneath.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once the server is connected, initialized, and queried, it may declare a tool such as &lt;code&gt;create_issue&lt;/code&gt;. How does that server-side name become an entry the model can call? How are collisions avoided, and how does the tool reach the model's tool list?&lt;/p&gt;

&lt;p&gt;That is the subject of the next article: &lt;strong&gt;from &lt;code&gt;tools/list&lt;/code&gt; to one entry in the Tool list&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/basic/transports" rel="noopener noreferrer"&gt;MCP specification: Transports&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code: Connect to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;Part 0: The Connection Lifecycle and Tool Exposure Map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1: From Built-In Tools to Extensible Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35"&gt;Part 2: From a Configuration Entry to a Handshake&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (2): From a Configuration Entry to a Handshake</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Fri, 23 Oct 2026 02:04:16 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-2-from-a-configuration-entry-to-a-handshake-3f35</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Claude Code cannot connect to an MCP server until that server appears in configuration. A definition may be private to one project, shared with a team, available to one user everywhere, or managed by an organization. When the same server name appears in more than one scope, precedence determines which complete definition wins. After configuration comes a separate job: connecting, handshaking, and negotiating the capabilities that server actually supports.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the previous article, we used an internal Jira server as the motivating example. Where should that server be declared so Claude Code knows it exists?&lt;/p&gt;

&lt;p&gt;There is no single answer. It depends on who should use the server and which parts of its configuration are safe to share.&lt;/p&gt;

&lt;h2&gt;
  
  
  One server name, several kinds of ownership
&lt;/h2&gt;

&lt;p&gt;Suppose a company provides an MCP server for its internal Jira instance. Everyone on a team should be able to use it, but nobody’s API token should be copied into a shared repository.&lt;/p&gt;

&lt;p&gt;That is the first configuration problem MCP needs to solve: the connection details for a shared capability should be declared once, while each person can retain control of their private credentials.&lt;/p&gt;

&lt;p&gt;Claude Code’s current public documentation describes three regular installation scopes, plus organization-managed configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project scope&lt;/strong&gt; lives in a &lt;code&gt;.mcp.json&lt;/code&gt; file at the project root. It can be committed to version control, so a team can share the server name, endpoint, and launch method without committing personal credentials.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User scope&lt;/strong&gt; lives in the user’s &lt;code&gt;~/.claude.json&lt;/code&gt; and applies across that user’s projects. It fits personal utility servers that are unrelated to one repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local scope&lt;/strong&gt; is also stored in &lt;code&gt;~/.claude.json&lt;/code&gt;, but keyed to one project only. It stays private and does not appear when the user opens other projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed configuration&lt;/strong&gt; lets an administrator provide servers centrally for an organization. Individual users do not edit that managed source themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code MCP reference&lt;/a&gt; documents the storage locations and intended use of these scopes.&lt;/p&gt;

&lt;p&gt;The local scope is particularly useful in the shared-Jira scenario. The project’s &lt;code&gt;.mcp.json&lt;/code&gt; can declare “this repository uses the Jira server,” while each developer supplies their own credential-bearing configuration privately. The shared repository establishes the integration; the local configuration completes it for one person.&lt;/p&gt;

&lt;p&gt;There are also server sources outside this regular scope hierarchy. A session can receive temporary configuration through a command-line option, and connectors configured through Claude.ai can reach Claude Code. Those are separate paths, not substitutes for the ordinary project/user/local choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  A collision is resolved by precedence, not by field-by-field merging
&lt;/h2&gt;

&lt;p&gt;What if the same server name appears in project, user, and local configuration?&lt;/p&gt;

&lt;p&gt;Claude Code resolves that conflict predictably. The public precedence order is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Local scope&lt;/li&gt;
&lt;li&gt;Project scope&lt;/li&gt;
&lt;li&gt;User scope&lt;/li&gt;
&lt;li&gt;Plugin-provided servers&lt;/li&gt;
&lt;li&gt;Claude.ai connectors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Organization-managed server definitions take precedence over all of those when they duplicate a server.&lt;/p&gt;

&lt;p&gt;The important detail is easy to miss: Claude Code uses the &lt;strong&gt;entire server entry&lt;/strong&gt; from the winning source. It does not merge individual fields from several scopes into one composite record. That distinction makes debugging less mysterious. If a local definition has the same server name as a project definition, the local definition is the one that Claude Code will use; it is not merely a place to append one extra header to the project record.&lt;/p&gt;

&lt;p&gt;This precedence is practical rather than arbitrary. A team can establish a shared baseline in &lt;code&gt;.mcp.json&lt;/code&gt;, while an individual retains an explicit way to substitute a private or project-specific definition. If a managed definition exists for the same server, the organization’s definition wins instead.&lt;/p&gt;

&lt;p&gt;One more safeguard applies specifically to project-scoped servers. A &lt;code&gt;.mcp.json&lt;/code&gt; file usually travels with a repository, so Claude Code asks for approval in interactive sessions before using its project-scoped servers. That makes the connection command and arguments visible before a cloned repository gets to run them. User and local scopes are already the user’s own private configuration, so they do not need the same first-use approval step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration says “try this,” not “it is usable”
&lt;/h2&gt;

&lt;p&gt;A configuration record is only a declaration that a server should exist. The actual connection still has to be established.&lt;/p&gt;

&lt;p&gt;Claude Code tracks a server’s connection state rather than reducing everything to a single yes-or-no flag. States distinguish a connected server from one that failed to connect, is still connecting, is disabled, or needs authentication.&lt;/p&gt;

&lt;p&gt;That separation matters because “unreachable” and “reachable but unauthorized” lead to different remedies. A bad URL, missing process, or crashed child process is a connection problem. An expired OAuth session or missing permission is an authentication problem. Treating both as the same generic failure would hide the next useful action.&lt;/p&gt;

&lt;p&gt;The connection phase and a later tool call also deserve different timeout expectations. A connection that never responds within a short window is often misconfigured or not running at all. A tool call, by contrast, may ask the server to perform a long-running operation. A client should avoid treating those two waits as if they had the same failure meaning.&lt;/p&gt;

&lt;h2&gt;
  
  
  The handshake asks what is actually available
&lt;/h2&gt;

&lt;p&gt;A successful transport connection is not yet the end of the setup path. Claude Code still needs to learn what the server supports.&lt;/p&gt;

&lt;p&gt;This is capability negotiation. Client and server declare their supported features, and the client enables only the capabilities the server actually advertises. A server might offer tools but no resources; another might expose readable resources while offering no callable tools at all.&lt;/p&gt;

&lt;p&gt;That is why MCP should not be described simply as “a way to add tools.” Tools, resources, and prompts are distinct capability families. The &lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;Model Context Protocol introduction&lt;/a&gt; frames MCP as a standard connection between AI applications and external systems, including data sources, tools, and workflows.&lt;/p&gt;

&lt;p&gt;Negotiation keeps that flexibility from becoming guesswork:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a server does not advertise tools, Claude Code does not ask it for a tool list.&lt;/li&gt;
&lt;li&gt;If it does not support resources, resource-reading behavior stays unavailable for that server.&lt;/li&gt;
&lt;li&gt;If a feature is supported by both sides, Claude Code can enable the relevant downstream behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is an intentionally modest rule: use what the server says it supports, rather than assuming every server implements every part of the protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connected is not the same as useful
&lt;/h2&gt;

&lt;p&gt;After the handshake and capability negotiation complete, the server is connected. But that still does not mean the model can use a new action yet.&lt;/p&gt;

&lt;p&gt;The connection only establishes a working channel and an agreed feature set. The next questions are how bytes move across that channel, and how a declared server tool becomes a normal entry in Claude Code’s own tool list.&lt;/p&gt;

&lt;p&gt;Those are separate transformations, and separating them is what makes the system manageable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configuration chooses a candidate server.&lt;/li&gt;
&lt;li&gt;Connection and handshake establish a usable relationship.&lt;/li&gt;
&lt;li&gt;Capability negotiation limits what the relationship can do.&lt;/li&gt;
&lt;li&gt;Later layers expose the allowed capabilities to the agent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;series map&lt;/a&gt; provides the broader pipeline, while &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1&lt;/a&gt; explains why MCP exists at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next: local processes and remote services
&lt;/h2&gt;

&lt;p&gt;A handshake assumes Claude Code already knows how to speak to the server. That may mean launching a local child process and communicating over standard input/output, or making requests to a remote service over a network transport.&lt;/p&gt;

&lt;p&gt;The next article examines that transport choice: which connection paths the protocol standardizes, which paths Claude Code supports in practice, and why a local process and a remote service should not be retried or diagnosed in exactly the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Connect Claude Code to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;What is the Model Context Protocol?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;Part 0: The Connection Lifecycle and Tool Exposure Map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04"&gt;Part 1: From Built-In Tools to Extensible Capabilities&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (1): From Built-In Tools to Extensible Capabilities</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Thu, 22 Oct 2026 02:06:46 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-1-from-built-in-tools-to-extensible-capabilities-2n04</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Claude Code ships with a fixed set of built-in tools such as Read, Write, and Bash. MCP—the Model Context Protocol—lets it connect to an external process at runtime and use that process’s declared capabilities as new tools. MCP does not solve “how should I reuse a procedure?” That is the job of a Skill. MCP solves “how can the model perform an action it did not ship with?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine that, before changing code, you want Claude to check the current state of an issue in your company’s internal Jira instance.&lt;/p&gt;

&lt;p&gt;Claude Code does not come with a tool named &lt;code&gt;Jira&lt;/code&gt;. It could use Bash to assemble a &lt;code&gt;curl&lt;/code&gt; command, add an API token, organization domain, and issue ID, build a JSON request, then sift the useful fields from a large response. That can work. But every time, the agent has to reconstruct where the token lives, what the endpoint looks like, and how to interpret the returned fields.&lt;/p&gt;

&lt;p&gt;That is a familiar kind of friction. An earlier Skill-focused discussion described it as repeatedly pasting a release checklist. Here, the repeated context is not a checklist but the mechanics of talking to an external system.&lt;/p&gt;

&lt;p&gt;A natural reaction is: why not turn those &lt;code&gt;curl&lt;/code&gt; steps into a Skill?&lt;/p&gt;

&lt;p&gt;You can—but the Skill would package &lt;strong&gt;operational knowledge&lt;/strong&gt; about how to talk to Jira. The actions available to Claude would still end at Bash. A Skill can organize the use of existing tools; it does not add a new executor. If the Jira integration needs to maintain session state, deal with pagination, or interpret schemas that differ by permission level, repeatedly composing requests and parsing them in Bash is less dependable than calling a purpose-built action that already understands Jira.&lt;/p&gt;

&lt;p&gt;What is missing is not another set of instructions. It is a &lt;strong&gt;new action&lt;/strong&gt;: something with a name, parameters, and a result, which the model can invoke directly like Read or Bash. Built-in tools are part of Claude Code itself. You cannot edit the product’s code just to make it recognize Jira.&lt;/p&gt;

&lt;p&gt;That is the layer MCP addresses: &lt;strong&gt;how can a model gain a new action at runtime without changing Claude Code itself?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A connectable process, not a text file to read
&lt;/h2&gt;

&lt;p&gt;A Skill is a folder containing Markdown and supporting files. Claude reads and expands it. An MCP server is different: it is an &lt;strong&gt;independently running process or service&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It might be a local program that can access a filesystem, or a long-running server inside a company network. It declares that it offers particular tools, readable data, and reusable prompt templates. The protocol gives that declaration a common shape regardless of the language used to build the server or the machine on which it runs.&lt;/p&gt;

&lt;p&gt;This series will call that process an &lt;strong&gt;MCP server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the other side, Claude Code acts as an &lt;strong&gt;MCP client&lt;/strong&gt;. It connects to a server, asks what that server can do, and adapts the answer into a form Claude Code can use. From the user’s perspective, the larger application is the &lt;strong&gt;host&lt;/strong&gt;: it can manage several MCP clients and several servers at once.&lt;/p&gt;

&lt;p&gt;Those names—host, client, and server—are general Model Context Protocol terminology, not concepts invented solely for Claude Code. The same vocabulary applies when an IDE or another desktop assistant supports MCP. The &lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;MCP introduction&lt;/a&gt; describes the protocol as an open standard for connecting AI applications with external systems.&lt;/p&gt;

&lt;p&gt;An MCP server can declare more than one kind of capability. Three categories matter for this series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; are callable actions that may have side effects, such as creating a Jira issue. They are the real answer to the opening scenario and the main thread of the series.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; are readable data exposed by a server, such as a current issue list. They are not the same as the supporting resources inside a Skill folder: these are externally supplied, potentially live data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt; are reusable conversation templates provided by a server. They are useful, though less central here than tools and resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connecting one server does not imply that all three categories exist. A server may expose only tools, only resources, or some combination. The client first needs to learn what the server supports. For a practical overview of the kinds of external systems Claude Code can connect to, see the official &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code MCP documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The important point for now is simple: &lt;strong&gt;tools, resources, and prompts are three different things.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Once connected, it looks like an ordinary tool
&lt;/h2&gt;

&lt;p&gt;Suppose an MCP server declares a &lt;code&gt;create_issue&lt;/code&gt; tool. Claude does not see it as a special “external capability.” Claude Code names and wraps it so it becomes another entry in the normal tool list, alongside Read and Bash.&lt;/p&gt;

&lt;p&gt;That uniformity is the design decision that makes MCP useful. The model need not switch into a separate “MCP mode” before deciding whether to call a tool. The source may be external, but the agent-facing shape remains a tool name, description, input schema, and result.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;previous article in this series&lt;/a&gt; maps the full route from server configuration to a callable tool. The rest of the series will unpack the main questions along that route:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Where does a server come from?&lt;/strong&gt; A server can be configured at several scopes. How does Claude Code discover the configuration and resolve conflicts?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How do bytes move?&lt;/strong&gt; A local child process and a server inside a private network cannot use exactly the same connection path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How does naming work?&lt;/strong&gt; Why does a connected tool such as &lt;code&gt;create_issue&lt;/code&gt; not collide with a built-in tool, and how does it reach the list the model can see?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who approves an action?&lt;/strong&gt; If a server can reach an internal network or create issues, who authorizes it? Can approval apply to the whole server rather than require a separate decision for every tool?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where is the boundary with Skills?&lt;/strong&gt; Both extend what Claude can accomplish, but they do so at different layers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Draw the line with Skills early
&lt;/h2&gt;

&lt;p&gt;The detour through “should this be a Skill?” is not a distraction. It is worth establishing the boundary at the start because every later article relies on it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;What it solves&lt;/th&gt;
&lt;th&gt;Where it ends&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reusable operating knowledge: what to do first, and what to do after each result&lt;/td&gt;
&lt;td&gt;It invokes &lt;strong&gt;existing&lt;/strong&gt; tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An action the model did not ship with&lt;/td&gt;
&lt;td&gt;It adds a &lt;strong&gt;new&lt;/strong&gt; tool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two mechanisms are complementary. Once an MCP server adds a useful tool, a Skill can absolutely include that tool in a repeatable workflow. One layer defines &lt;em&gt;how to proceed&lt;/em&gt;; the other changes &lt;em&gt;what actions are available at all&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A compact way to remember the distinction is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Skills answer “how do I do this?” MCP answers “what can I do?”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That framing also clarifies why MCP should not be treated as a bag of prompt snippets or shell recipes. It is a protocol boundary that lets independently built capabilities enter an agent without turning the agent itself into a collection of special cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next: configuration becomes a connection
&lt;/h2&gt;

&lt;p&gt;Before Claude Code can connect to an MCP server, that server must appear in configuration. The same name might be defined in a project, a user-level configuration, or centrally managed settings. What happens when those sources disagree?&lt;/p&gt;

&lt;p&gt;The next article follows that path: from the first configuration entry, through scope and precedence, to a completed handshake and a client that knows which capabilities the server supports.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://modelcontextprotocol.io/introduction" rel="noopener noreferrer"&gt;What is the Model Context Protocol?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Connect Claude Code to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g"&gt;Part 0: The Connection Lifecycle and Tool Exposure Map&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
      <category>programming</category>
    </item>
    <item>
      <title>Claude Code MCP Deep Dive (0): The Connection Lifecycle and Tool Exposure Map</title>
      <dc:creator>Zhengxin</dc:creator>
      <pubDate>Wed, 21 Oct 2026 04:53:15 +0000</pubDate>
      <link>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g</link>
      <guid>https://dev.to/_94be737e156beb4d74df2/claude-code-mcp-deep-dive-0-the-connection-lifecycle-and-tool-exposure-map-84g</guid>
      <description>&lt;p&gt;MCP gives Claude Code a second source of capabilities. Built-in tools are not the whole story: once a server is connected, its tools, resources, and prompts become available to the client. The interesting part is that Claude Code does &lt;strong&gt;not&lt;/strong&gt; build a separate agent runtime for those tools. It translates an external tool into the same general tool surface used by the agent loop.&lt;/p&gt;

&lt;p&gt;That design choice is the thread for this series:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The more extensible the system becomes, the more important a single, uniform interface becomes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This opening article is a map of the territory. Later articles will follow each section of the pipeline in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The path from configuration to a callable tool
&lt;/h2&gt;

&lt;p&gt;A server entry in &lt;code&gt;.mcp.json&lt;/code&gt; or user settings does not immediately become something the model can call. It crosses several gates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Merge configuration scopes.&lt;/strong&gt; Claude Code combines the relevant configuration sources and resolves overrides.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply policy.&lt;/strong&gt; Allowlists, denylists, and enterprise rules may remove a server before connection is attempted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Obtain approval.&lt;/strong&gt; A project-level server can require the user's approval before first use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect through the selected transport.&lt;/strong&gt; A local child process and a remote HTTP service have different connection paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Negotiate capabilities.&lt;/strong&gt; Client and server establish which MCP features are supported.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discover capabilities.&lt;/strong&gt; The client fetches the server's tools, resources, and prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapt tools.&lt;/strong&gt; Each server tool becomes an &lt;code&gt;MCPTool&lt;/code&gt; with a Claude Code-compatible name and schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add it to the agent's tool list.&lt;/strong&gt; At that point, the LLM can select it as if it were an ordinary tool.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each stage can fail differently. A failed connection becomes a connection failure. An expired authorization becomes an authentication problem. A policy rejection is quieter: the server can disappear before the user ever sees a connection state.&lt;/p&gt;

&lt;p&gt;That distinction matters when debugging MCP. “The tool is missing” can mean a configuration merge issue, a policy decision, an approval requirement, an authentication failure, or a transport failure—not merely that &lt;code&gt;tools/list&lt;/code&gt; failed.&lt;/p&gt;

&lt;p&gt;For the user-facing setup model and supported scopes, see the official &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;Claude Code MCP documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connection is a lifecycle, not a one-time request
&lt;/h2&gt;

&lt;p&gt;Internally, a server is not simply connected or disconnected. The connection layer distinguishes states such as connected, failed, pending, disabled, and needing authentication. That state model prevents a transient transport error from being confused with an OAuth flow that still needs a browser-based decision.&lt;/p&gt;

&lt;p&gt;The implementation also treats a connection as a cacheable resource. A connection is memoized by server name and configuration, then its derived data—such as discovered tools and resources—is cached alongside it. When the transport closes, those caches are cleared so the next request takes the reconnection path instead of continuing to use stale discovery results.&lt;/p&gt;

&lt;p&gt;This is especially important for remote MCP servers. A session can expire even when the endpoint remains reachable. Claude Code recognizes the relevant JSON-RPC session-expiry failure, clears its cached connection state, reconnects, and retries once. It is a small recovery rule with a large practical effect: “the server is up” is not the same as “this session is valid.”&lt;/p&gt;

&lt;p&gt;There is also an intentional split in retry behavior. Remote transports can receive bounded automatic reconnect attempts with exponential backoff. Local &lt;code&gt;stdio&lt;/code&gt; and SDK-backed processes are excluded. A network connection may recover after a short interruption; a local process that exited is more likely to have a bad command, missing environment variable, or a real crash. Retrying blindly would obscure that diagnosis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Standard transports and product transports
&lt;/h2&gt;

&lt;p&gt;The MCP specification defines the standard &lt;code&gt;stdio&lt;/code&gt; and Streamable HTTP transports; the older HTTP-plus-SSE approach is deprecated. The protocol's transport specification is deliberately narrow: it standardizes interoperable ways to exchange JSON-RPC messages rather than every integration a product might need. See &lt;a href="https://modelcontextprotocol.io/specification/2025-03-26/basic/transports" rel="noopener noreferrer"&gt;MCP's transport specification&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Claude Code's client has a broader set of branches in practice. In addition to standard local and remote paths, the codebase contains support for compatibility SSE paths, WebSocket-based paths, IDE-oriented variants, SDK bridges, a Claude.ai proxy, and an in-process transport.&lt;/p&gt;

&lt;p&gt;This is not a contradiction. It is the boundary between a protocol and a product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The protocol&lt;/strong&gt; defines the portable contract that independent clients and servers can share.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The product&lt;/strong&gt; still needs integrations for its IDE, browser, SDK, and internal process boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The in-process transport makes this visible. It passes messages through in-memory queues rather than a network connection or child process. The SDK bridge similarly carries MCP JSON-RPC messages across Claude Code's own control channel. Neither changes the model-facing idea of a tool; both solve deployment-specific plumbing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How an external tool becomes a Claude Code tool
&lt;/h2&gt;

&lt;p&gt;The key adapter is naming. A discovered MCP tool is exposed as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__&amp;lt;server&amp;gt;__&amp;lt;tool&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That prefix gives tools from different servers a stable namespace and lets the rest of Claude Code treat them like entries in a common list. The tool's &lt;code&gt;inputSchema&lt;/code&gt; is passed through as JSON Schema rather than translated into a separate handwritten validation model.&lt;/p&gt;

&lt;p&gt;The result is deliberately mundane: a model sees a tool name, a description, and a schema. It does not need a separate mental model for “MCP mode.”&lt;/p&gt;

&lt;p&gt;The adapter also exposes one limitation of every string-based namespace: server names containing the separator can be ambiguous. Names are convenient as human-facing identifiers, but they are a brittle serialization format when later parsing needs to recover structural boundaries.&lt;/p&gt;

&lt;p&gt;Claude Code also registers resource-listing and resource-reading functionality globally rather than once per server. That avoids presenting the model with a growing cluster of nearly identical resource tools as more servers are connected. Large or binary resource results can be stored as files and replaced with a path reference, and MCP output has a configurable size limit. Both measures keep a capable external server from consuming the entire working context.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP permissions: special matching, ordinary decisions
&lt;/h2&gt;

&lt;p&gt;MCP has one notable extension in Claude Code's permission grammar. A rule can match an entire server, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mcp__calendar
mcp__calendar__*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is more useful than approving every tool individually when a server offers a coherent, trusted capability. It also allows a user or administrator to deny an entire integration at the same level of abstraction at which it was installed.&lt;/p&gt;

&lt;p&gt;But the MCP tool itself does not carry a private permission engine. Its local permission check returns &lt;code&gt;passthrough&lt;/code&gt;; the shared permission system performs the actual rule matching. If no rule resolves the request, the general engine falls back to asking the user.&lt;/p&gt;

&lt;p&gt;This is a useful division of responsibility. A tool such as Bash may need command-specific safety analysis. An MCP tool is too varied for one universal semantic rule. Claude Code instead centralizes the decision in the policy layer, where the server namespace provides the necessary grouping mechanism.&lt;/p&gt;

&lt;h2&gt;
  
  
  Beyond tools: resources, prompts, and elicitation
&lt;/h2&gt;

&lt;p&gt;MCP is often described as “a way to add tools,” but that is only one of its three major capability families:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; let the model perform an action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; let a server provide readable, addressable information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt; let a server provide reusable prompt templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude Code gates each downstream feature independently after capability negotiation. A server may be useful as a tool provider without offering resources, or vice versa.&lt;/p&gt;

&lt;p&gt;Elicitation is the more interactive extension. It lets a server request structured input while an interaction is in progress. Claude Code supports form and URL modes, and places hooks in front of the UI so an installation can handle certain requests programmatically. This is a good example of the difference between adopting an MCP feature and shipping it in a real product: protocol support establishes the message exchange; a client still decides how a person sees, approves, or automates that exchange.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication is part of the tool experience
&lt;/h2&gt;

&lt;p&gt;For HTTP servers, authorization is not a detached setup screen. An authorization failure can surface to the model as a synthetic authentication tool result containing the URL needed to continue the flow. Under the hood, the client uses authorization-code OAuth with PKCE, a local loopback callback, a timeout, and secure credential storage.&lt;/p&gt;

&lt;p&gt;This makes authentication another state transition in the lifecycle rather than an unstructured fatal error. Enterprise environments add another layer: a token-exchange flow can reuse an existing identity-provider session across eligible servers, reducing repeated logins without changing the core tool interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code can reverse roles
&lt;/h2&gt;

&lt;p&gt;The architecture becomes clearer when the direction is reversed. Claude Code can also start an MCP server and expose its own internal tools through &lt;code&gt;tools/list&lt;/code&gt;, using &lt;code&gt;stdio&lt;/code&gt; for another MCP client to consume.&lt;/p&gt;

&lt;p&gt;That works because tool definitions are not fundamentally tied to one transport. The same internal schema can be used directly by the agent loop or converted to JSON Schema and advertised over MCP. Claude Code is therefore not permanently “an MCP client”; MCP is one of the ways its tool model can cross a process boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the rest of the series will explain
&lt;/h2&gt;

&lt;p&gt;This map suggests the chapters ahead:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connection setup, scopes, and the handshake.&lt;/li&gt;
&lt;li&gt;Local and remote transports.&lt;/li&gt;
&lt;li&gt;Tool discovery, naming, schemas, and output control.&lt;/li&gt;
&lt;li&gt;Server-level permission rules.&lt;/li&gt;
&lt;li&gt;OAuth and enterprise authentication.&lt;/li&gt;
&lt;li&gt;Resources and elicitation.&lt;/li&gt;
&lt;li&gt;Claude Code acting as an MCP server.&lt;/li&gt;
&lt;li&gt;Where MCP stops—and where Skills, built-in Tools, and Plugins begin.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The central question is not “How do I add another tool?” It is: &lt;strong&gt;how can an agent accept many independently built capabilities without becoming a pile of special cases?&lt;/strong&gt; Claude Code's answer is to make the boundary adaptable, then keep the agent-facing interface uniform.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>claude</category>
      <category>ai</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
