---
title: "MCP Servers vs Agent Skills: What Each Is For, and Why Tools Need Both"
excerpt: "An MCP server gives an agent capability: typed tools it can call at runtime. A skill gives it procedure: an instruction file, invoked as a command, that teaches the agent how to do a job properly. They solve different problems, they fail in different ways alone, and a serious agent integration ships both."
metaDescription: "MCP servers vs agent skills: MCP exposes callable tools over a protocol, skills are instruction files that teach a workflow. When to use each, how they compose, and how each is versioned."
publishedAt: 2026-08-10
updatedAt: 2026-08-10
author: Will
categories:
 - Engineering
 - Guides
 - AI Testing
tags:
 - mcp
 - agent-skills
 - model-context-protocol
 - skill-md
 - ai-coding-agents
 - claude-code
 - developer-tools
 - agent-native
metaTitle: "MCP Servers vs Agent Skills: Capability vs Procedure (2026)"
featuredImage: ./cover.png
featuredImageAlt: "Illustrated Shiplight blog cover: a glossy protocol connector port labeled by shape on one side and an open instruction card on the other, the two clicking together into one complete agent capability."
related:
  - '[What is MCP?](/blog/what-is-mcp): the protocol explained from scratch'
  - '[Agent Skills](/blog/agent-skills): the open SKILL.md standard and what portability buys'
  - '[How to build an MCP server](/blog/build-mcp-server): implementing the capability half'
---

Teams shipping an agent integration in 2026 hit the same fork within about an hour: do we build an MCP server, or do we write skills? The question gets asked as if the two were competing formats, in the way JSON competes with YAML. They are not. They answer different questions, and the answer to one is useless without the other.

The short version, which the rest of this page unpacks:

**An MCP server gives an agent capability. A skill gives it procedure.** The server defines what the agent is physically able to do. The skill defines how to do a particular job well, in what order, with what checks. Capability without procedure produces an agent with hands and no method. Procedure without capability produces an agent that knows exactly what it would do if it could do anything.

## What an MCP server actually is

The [Model Context Protocol](/blog/what-is-mcp) is an open standard for exposing tools to a model. Concretely, an MCP server is a running process. It advertises a list of tools, each with a name, a description, and a JSON Schema for its parameters. The agent's client connects (over stdio for a local process, or HTTP for a remote one), reads the tool list, and from then on can emit a typed call. The server executes it and returns a result that goes back into the model's context.

Three properties matter for the comparison.

**It executes code.** A tool call runs real logic in a real process: opening a browser, querying a database, hitting an API. That is the only way an agent touches anything outside its own context window.

**It is typed and validated.** Parameters have a schema. The client can reject a malformed call before it reaches you, and a well-designed schema makes a whole class of mistakes impossible rather than merely discouraged.

**It is discovered at runtime.** The agent does not need integration code written in advance. It reads the tool list when it connects, which is the main thing MCP adds over publishing a plain HTTP API. (That distinction is worth its own treatment: see [MCP vs API](/blog/mcp-vs-api).)

What an MCP server does not do is decide anything. It has no opinion about which tool to call, in what order, or whether the result was good. A tool description can say "use this to inspect the page", but it cannot say "before you inspect anything, check whether the app requires login, and if it does, set up storage state first, and if that fails, stop and ask rather than testing a logged-out page." That is a paragraph of judgment, and it does not belong in a parameter schema.

## What a skill actually is

A skill is an instruction file. Under the [Agent Skills standard](/blog/agent-skills) it is a folder containing a `SKILL.md`: a name, a description of when the skill applies, and a body of instructions in plain markdown, optionally with supporting files the agent can open as it needs them.

The agent loads a skill on demand. Either the user invokes it explicitly as a command (`/shiplight fix`, `/deploy staging`), or the agent matches the current task against the skill's description and pulls it in itself. Until then the body sits on disk and costs nothing, which is the point of the format: a long procedure that would blow the context budget if it were always present becomes affordable when it loads only for the tasks it applies to.

A skill contains no executable code path of its own. It is text the model reads. What it carries is everything a schema cannot:

- **Order.** Do this, then this. Never that before this.
- **Preconditions and refusals.** If the test project has not been set up, stop and set it up. If the app itself is broken, report the bug rather than editing the test to pass.
- **Judgment.** What counts as adequate coverage of a signup flow. When to keep going and when to hand back.
- **House style.** Naming, file layout, the conventions your team argues about in review.
- **Recovery.** What to do when a step returns nothing, which is the part most integrations skip and most real runs need.

Because a skill is prose, it can be wrong without breaking anything. Because a tool schema is a contract, it cannot.

## The test for which one you need

Ask what is failing.

**Reach for an MCP server when the agent cannot do the thing at all.** No browser to drive, no way to query the warehouse, no path to your deployment API. Missing capability. Writing more instructions will not help, and an agent handed a procedure it cannot execute will improvise something adjacent, which is worse than refusing.

**Reach for a skill when the agent can do the thing but does it badly, or differently each time.** It gets there eventually after eleven turns of exploration. It gets there on Tuesday and not on Wednesday. Two engineers on the same team get two different file layouts. That is missing procedure, and adding tools makes it worse by widening the search space.

A useful smell test on any single piece of knowledge: if getting it wrong produces an error, it belongs in the schema. If getting it wrong produces a bad but valid result, it belongs in the skill.

## What goes wrong with only an MCP server

This is the common case, because a server is the part that feels like engineering. The failure is quiet, so it gets misread as the model being weak.

The agent has to reconstruct the workflow from tool descriptions on every run. That costs turns, and turns cost money and context. Worse, the reconstruction is different each time, so results are not reproducible across runs or across teammates. Any convention you care about, where files go, how things are named, what "done" means, has to be restated by the user in every prompt, and half the time it will not be.

The sharpest version of the problem is preconditions. A browser server with a clean tool surface still lets an agent cheerfully inspect a logged-out page and report that the dashboard has no data. Nothing in the schema was violated. Every call succeeded. The output is useless, and there was no place to put the sentence that would have prevented it.

## What goes wrong with only skills

The opposite failure is louder and easier to diagnose. A skill that says "open the app in a browser and check the layout" given to an agent with no browser tool produces one of two outcomes: an honest refusal, or, more often, a plausible substitute. The agent reads the JSX, reasons about what the page probably renders, and reports that the layout looks correct. It has answered a question about the source code and presented it as a question about the running application.

This is the specific reason instructions-only integrations disappoint. The procedure was fine. The agent had no way to observe reality, so it simulated it.

A softer version: the skill drives a generic tool badly. Told to use a general-purpose automation tool for a job that needs domain-specific behaviour, the agent produces something that runs and is subtly wrong, and nobody notices until the result is trusted.

## How they compose

In a working integration the skill references the server's tools by name and supplies everything the schema cannot express.

The division of labour that holds up: **anything that must be exact goes in the server, anything that requires judgment goes in the skill.** Element resolution, session lifecycle, log capture, file writes: exact, deterministic, in the server, and ideally deterministic enough to need no model call at all. Deciding what is worth testing, when a run is good enough, whether a failure is the app's fault or the test's: judgment, in the skill.

Two practical rules for the seam between them.

**The skill should name tools explicitly.** "Use `inspect_page` to get element indices, then `act` with the index" removes an entire class of tool-selection error. It also creates a coupling you must maintain, which is the versioning problem below.

**Policy lives in exactly one place.** If both the tool description and the skill state a rule, they will drift, and the model will get contradictory guidance in the same context. Put behavioural policy in the skill and keep tool descriptions to what the tool does and what it returns.

## Versioning and distribution

The two halves have genuinely different lifecycles, and treating them the same is a common source of breakage.

**The server is a wire contract.** Renaming a tool or tightening a parameter breaks every caller immediately and visibly. It is versioned like a package. Shipping it through a registry so clients resolve the current version on launch means users get fixes without an update step, at the cost of a moving target under them. Pinning is the other trade: reproducible, and stale until someone remembers.

**A skill is prose, and it degrades rather than breaks.** An out-of-date instruction produces a worse run, not a stack trace, which makes staleness harder to notice. Skills are usually installed as files into each agent's own configuration directory, per agent and per machine, which means a team can quietly end up running five different versions of the same procedure. If your skills matter, either commit them to the repository they apply to, so a clone gets the current copy, or give people a one-command refresh and remind them it exists.

**The coupling between them is the thing that actually bites.** A skill that names a tool the server no longer exposes fails in the least helpful way possible: the agent reads a confident instruction, finds no such tool, and improvises. Ship the pair together, test the pair together, and when you rename a tool, grep the skills.

One more distribution note that surprises people: not every client runs both halves. Several popular MCP clients consume tools but have no skills mechanism at all. If your product depends on procedure to be usable, those clients get the capability and none of the method, and you should know which of your users are in that position rather than finding out from a support ticket.

## A worked example: how Shiplight splits the two

Shiplight installs into a coding agent as two pieces, and the split is a clean illustration.

**The MCP server is the capability half.** It gives the agent a real browser: open a session, inspect the page (returning a DOM tree plus a marked screenshot with element indices), act on an element by index, pull console and network logs, extract locators, close the session and collect the video and trace. Every one of those browser actions is deterministic, which is why the server itself needs no model key. The agent supplies the reasoning; the server executes exactly what it was asked to.

**The skills are the procedure half.** They are invoked as `/shiplight <subcommand>`, and each one encodes a workflow rather than a capability. `/shiplight verify` visually confirms a UI change you just made. `/shiplight create-yaml-tests` walks the app and writes end-to-end tests as YAML files in your repository. `/shiplight fix` reproduces a failing test, diagnoses the root cause, repairs the test, and reports an application bug instead of editing the test to pass when the app is the thing that broke. `/shiplight review` runs a broader quality pass across areas like security, accessibility and performance. `/shiplight cloud` reads back results from hosted runs.

Notice which decisions sit where. "Click element 7" is a tool call. "The app is broken, so do not make this test pass" is a skill instruction, and there is no schema in which it could have lived. The refusal is the valuable part, and it is prose.

## What neither of them fixes

Both are plumbing. Neither supplies context about your specific application: what a valid test account is, which flows are load-bearing, what your staging environment is called. That knowledge has to be written down somewhere the agent reads, and if you do not write it down the agent will infer it, sometimes correctly.

Neither one makes an agent's output trustworthy either. A tool call that succeeds says the call succeeded. Whether the work was right is a separate question, and it needs a check the agent did not also author, which is a different problem from the one this page is about.

## FAQ

### Are MCP servers and agent skills competing standards?

No. They operate at different layers and a full integration ships both. MCP exposes typed tools an agent can call at runtime; a skill is an instruction file that tells the agent which tools to use, in what order, and what counts as a good result.

### Can a skill work without an MCP server?

Yes, when the procedure only needs capabilities the agent already has, such as reading and editing files or running shell commands. A skill that assumes a capability the agent lacks is the dangerous case, because agents often substitute a plausible alternative rather than refusing.

### Should I build the server or the skill first?

Build the server first if the agent literally cannot do the job today. Write skills first if it can do the job but does it inconsistently. Most products need the server first and discover the skill gap once real users start getting different results from the same request.

### How do I keep skills and tools from drifting apart?

Ship them as a pair from one repository, and treat a tool rename as a change that requires grepping every skill that names it. Keep behavioural policy in the skill only, so the tool description and the instructions cannot contradict each other in the same context.

### Do all coding agents support both?

Most major coding agents support both, but not all. Several MCP clients consume tools without any skills mechanism, so a procedure-dependent product behaves differently there. Check which half each agent your users run actually supports before assuming parity.
