Scope & vantage. Assessed mid-2026. Target use case: an agent in a production system with a security boundary and an audit requirement — internal tools, customer data, and a compliance team who will ask what the model was allowed to touch. Axes are integration-specific and not comparable with any other assessment here; two are inverted (Low Latency Overhead, Light Ops) so higher is always better.
1. Executive summary
The question is not "which protocol wins" — it is "is there a boundary to cross?" Get that right and the choice makes itself.
If the tool lives in your own process, written by your team, deployed in your repo: native function calling is correct. Not a compromise, not the legacy option — correct. It has the lowest latency, the lightest operations, and the most mature client support on this page, and wrapping it in a protocol adds a hop and a daemon to buy a boundary you do not need.
If the tool is genuinely external — another team's service, a vendor, something with its own auth and its own blast radius — that is what MCP is for. It scores highest here on Security Boundary and Governance for a reason: it makes the seam explicit, which is what lets you audit it.
Agent Skills are solving a third problem people keep conflating with the first two. They are not about calling code; they are about procedural knowledge — how we do releases, what our escalation policy is — loaded progressively so it does not sit in context permanently. That is why Skills score 4.7 on token efficiency and 3.2 on security boundary: they are documentation with a loading strategy, not a sandbox.
Verdict
MCP — Adopt where the tool boundary is genuinely external and needs a real security seam. Best-in-class on the security and governance axes, broadest client support, and a daemon plus a protocol hop to pay for it.
Native function calling — Adopt for in-process tools. Highest maturity and lowest overhead on this page. Choosing it is not settling.
Agent Skills — Trial for packaging procedural knowledge. Excellent token economics via progressive disclosure; a weak security story, because that was never the problem it solves.
Hand-rolled API layer — Narrow Use. Sometimes right for a hard compliance constraint, and you are rebuilding MCP badly with no ecosystem.
Main risk: adopting MCP for tools that never leave your process, and paying protocol overhead for a boundary that does not exist.
2. Positioning
These four are usually presented as a progression — hand-rolled, then function calling, then MCP, then Skills — which is misleading. They answer different questions.
| Dimension | MCP | Agent Skills | Native function calling | Hand-rolled API |
|---|---|---|---|---|
| Answers | How do I cross a boundary? | How do I load knowledge? | How do I call my own code? | How do I satisfy an unusual constraint? |
| Unit | A server exposing tools | A folder of instructions | A function signature | Whatever you built |
| Boundary | Explicit, process-level | None — it is text | None — same process | Whatever you enforced |
| Context cost | Tool schemas, always loaded | Progressive — loaded on demand | Schemas, always loaded | Yours to manage |
| Ops | A server to run and version | Files in a repo | Nothing extra | All of it |
| Ecosystem | Broad and growing | Narrower, client-specific | Universal | None |
The progressive disclosure idea inside Agent Skills is the genuinely novel bit and worth understanding on its own terms. Instead of putting every procedure in the system prompt, a Skill exposes a short description; the agent pulls the full body only when the description matches what it is doing. That turns a linear context cost into a conditional one — which is why the token efficiency score is the highest on this page, and why Skills scale to knowledge volumes that would make a system prompt unusable.
The mirror-image trap is treating that as a security mechanism. A Skill is instructions the model reads. It has no sandbox, no capability model, and no enforcement — an agent that has been prompt-injected will read your Skill exactly as happily as your own instructions. If the requirement is containment, that is MCP's job, and I have written at length about why in prompt injection and guardrails.
3. Radar criteria — the reasoning
Interface clarity
MCP 4.4 — a typed, discoverable contract with a specification behind it. Agent Skills 4.2: markdown with frontmatter, which is clearer to a human and looser to a machine. Native function calling 4.0, entirely dependent on how good your docstrings are. Hand-rolled 3.4, as clear as the last engineer made it.
Security boundary
The axis that should decide most of this. MCP 4.6 — a separate process with its own auth, its own permissions, and a seam you can put a policy at. Hand-rolled 4.0: you can build a real boundary, and you will maintain it forever. Native function calling 3.4 and Agent Skills 3.2 — neither has a boundary at all, and it is important not to pretend otherwise. Skills in particular are text the model reads.
Discoverability
MCP 4.3 — servers advertise their tools, so a client can enumerate capability at runtime. Agent Skills 4.0, discoverable by description. Function calling 3.6, whatever you registered. Hand-rolled 2.6: discoverable by reading the source, which is to say not.
Versioning & evolution
Hand-rolled 4.2 wins here almost by accident — you own the whole surface, so you can version it however you like. Agent Skills 3.9 (files in git, which is a decent versioning story). MCP 3.8: the protocol is stabilising and tool-schema evolution across clients is still awkward. Function calling 3.4.
Token efficiency
Agent Skills 4.7 and this is their entire argument — progressive disclosure means a large body of procedural knowledge costs almost nothing until it is relevant. Function calling 4.2. Hand-rolled 3.4. MCP 3.6: every connected server's tool schemas sit in context, and with several servers connected that is a real and often unnoticed tax.
Low latency overhead (inverted — higher means less)
Native function calling 4.6 — an in-process call. Agent Skills 4.4, a file read. Hand-rolled 4.2. MCP 3.6: a real IPC or network hop per call, which is invisible in a chat interface and very visible in a voice agent's latency budget.
Client & ecosystem support
Native function calling 4.4 — every model provider supports it, and has for years. MCP 4.5 has overtaken it on breadth of tooling: clients, servers, registries, inspectors. Agent Skills 3.4, more client-specific. Hand-rolled 2.4, by definition none.
Light ops (inverted — higher means less to run)
Native function calling 4.6 — nothing to deploy. Agent Skills 4.3, files in a repo. MCP 3.6: a server per integration, each needing deployment, monitoring and a version. Hand-rolled 3.0.
Governance & audit
MCP 4.2 — a process boundary is where you can actually log, rate-limit and authorise, which is what auditors want to see. Hand-rolled 4.0. Function calling 3.4 and Skills 3.4: both auditable in principle, with nothing structural helping you.
Maturity
Native function calling 4.6 — years of production use across every provider. Hand-rolled 4.4, mature in the sense that it is just software. MCP 4.0: young, moving fast, and already the de facto standard for external tools. Agent Skills 3.4, the newest idea here and the least settled.
4. Radar scorecard
How these scores are arrived at — the rings, the 0–5 scale, and the evidence rules — is written up in the radar methodology. This table and the chart below are generated from one file, scorecards.json: the source of truth, machine-readable, and kept separate so two copies of the same numbers cannot drift apart between editions. Last reviewed 2026-Q3.
| Criterion | MCP | Evidence | Risk → mitigation |
|---|---|---|---|
| Interface Clarity | 4.4 | Typed, discoverable contract with a published spec | Schema evolution across clients is still awkward |
| Security Boundary | 4.6 | Separate process, own auth, a real policy seam | — |
| Discoverability | 4.3 | Servers advertise tools; runtime capability enumeration | — |
| Versioning & Evolution | 3.8 | Protocol stabilising; tool-schema evolution in flux | Breaking changes → pin server versions |
| Token Efficiency | 3.6 | Every connected server's schemas sit in context | Several servers → measure the always-on token cost |
| Low Latency Overhead (inverted) | 3.6 | A real IPC/network hop per call | Latency-critical paths → native calls, not MCP |
| Client & Ecosystem Support | 4.5 | Broad client, server, registry and inspector tooling | — |
| Light Ops (inverted) | 3.6 | A server per integration to deploy, monitor and version | Server sprawl → consolidate; one server, many tools |
| Governance & Audit | 4.2 | Process boundary is where logging and authz can live | — |
| Maturity | 4.0 | Young, fast-moving, already the de facto external standard | — |
Comparator scores (same axis order) — Agent Skills: 4.2 / 3.2 / 4 / 3.9 / 4.7 / 4.4 / 3.4 / 4.3 / 3.4 / 3.4. Native function calling: 4 / 3.4 / 3.6 / 3.4 / 4.2 / 4.6 / 4.4 / 4.6 / 3.4 / 4.6. Hand-rolled API layer: 3.4 / 4 / 2.6 / 4.2 / 3.4 / 4.2 / 2.4 / 3 / 4 / 4.4.
5. The radar
Ten integration axes, two inverted so higher is always better. The shapes are the argument: MCP peaks on Security and Governance and dips on latency and ops; native function calling is its mirror image; and Agent Skills spike alone on Token Efficiency while sitting lowest on Security — because they were never a containment mechanism. Click any name in the legend to toggle it on or off — comparing two shapes at a time is far more legible than comparing four.
6. Workload-specific analysis
| Situation | Best fit | Notes |
|---|---|---|
| Your own functions, your own process | Function calling | No boundary to cross. Adding a protocol adds a hop and buys nothing. |
| Another team's service, or a vendor's | MCP | A real seam, with auth and audit at it. This is the case it was designed for. |
| "How we do X here" — procedures, policies | Agent Skills | Progressive disclosure keeps it out of context until it matters. |
| Large body of knowledge, rarely all relevant | Agent Skills | 4.7 on tokens. This is the whole point. |
| Tool the agent must not be able to misuse | MCP | Containment needs a process boundary, not instructions. |
| Latency-critical path (voice, trading) | Function calling | The MCP hop is invisible in chat and expensive in a voice latency budget. |
| Air-gapped or unusual compliance regime | Hand-rolled | Legitimate — and you are maintaining a protocol nobody else tests. |
| Because it is the newest thing | Stop | The most common reason MCP gets adopted, and the worst one. |
The trap: treating Agent Skills as a security control. A Skill is markdown the model reads. It has no sandbox, no capability model, and no enforcement — so "the Skill says not to touch production" is a suggestion to a system that can be argued with. An agent that has been prompt-injected will read an attacker's instruction with exactly the same weight as yours. Skills are excellent at their actual job, which is loading procedural knowledge cheaply. If the requirement is that something cannot happen, that needs a process boundary with authorisation at it, which is MCP or a hand-rolled equivalent. The second trap is the mirror: paying MCP's hop and daemon for functions that live in your own codebase.
7. Reference architecture
The pattern I would build: native calls inside the trust boundary, MCP across it, Skills for knowledge, and one gateway so the model provider stays swappable.
graph LR U["User / caller"] --> AG["Agent runtime"] AG --> GW["LLM gateway
routing + fallback"] GW --> M["Model"] AG -->|"in-process, no hop"| FN["Native functions
your own code"] FN --> DB[("Your database")] AG -->|"protocol hop"| MCP["MCP servers"] MCP -->|"own auth"| EXT[("External systems
CRM, vendor APIs")] SK["Agent Skills
procedural knowledge"] -.->|"loaded on demand"| AG MCP -.->|"authz + audit log"| AUD[("Audit store")] POL["Policy"] -.->|"enforced at the seam"| MCP
The trust boundary is the vertical the diagram is built around. Everything reached by a solid line from the agent is inside it and called directly; everything past MCP is outside it and pays a hop to gain authorisation and an audit trail. Skills enter dotted because they are context, not capability.
The distinction in code — the same capability, on either side of a boundary:
# INSIDE the boundary: your code, your process. A direct call. No protocol,
# no daemon, no hop. Bind parameters — tool args are model-controlled input.
@tool
def get_order(order_id: str) -> dict:
# Order from our own database.
return db.query("select * from orders where id = ?", [order_id])
# ACROSS the boundary: someone else's system, with its own credentials and
# its own blast radius. The MCP server is where authz and audit live, so the
# agent never holds the vendor credential at all.
#
# mcp.json
# {
# "servers": {
# "billing": {
# "command": "billing-mcp",
# "env": { "BILLING_TOKEN": "${SECRET:billing_token}" }
# }
# }
# }
#
# The seam is the point: the agent asks the server, the server decides.
# Scope the token to the smallest set of operations the agent needs, and
# log every call — a boundary you cannot audit is decoration.
8. POC plan (4 weeks)
- Week 1 — draw the trust boundary before choosing anything. List every tool and mark it inside or outside. That single exercise decides most of this, and teams that skip it end up wrapping their own functions in a protocol.
- Week 2 — measure the context tax. Connect the MCP servers you expect to need and count the tokens their schemas consume before a single user message. Several servers add up faster than anyone expects.
- Week 3 — attack it. Prompt-inject the agent and try to reach a tool it should not. If a Skill is the only thing standing between the model and a destructive action, you have found your answer about what Skills are for.
- Week 4 — decide per tool, not per stack. The right outcome is usually a mix. Re-score this table and write the ADR listing which tools sit on which mechanism and why.
9. Final recommendation
Adopt MCP for external tools, native function calling for internal ones, and Agent Skills for knowledge. This is not a competition, and the right answer is a mix.
The decision rule I would give a team is one question: does this call cross a trust boundary? If the code is yours, in your process, in your repo — call it directly. Native function calling scores highest on maturity and lowest on overhead precisely because there is nothing between the model and the function, and adding MCP there buys a security seam where there is nothing to secure while costing a hop and a daemon to operate.
If the call reaches someone else's system — another team, a vendor, anything with its own credentials — MCP is the right answer and its 4.6 on Security Boundary is why. A separate process is where authorisation, rate limiting and audit logging can actually live, and "the agent asked the server and the server decided" is a sentence an auditor accepts. Watch the context tax as servers accumulate, and consolidate: one server exposing many tools beats many servers exposing few.
Agent Skills deserve a trial on their own merits and should not be measured against the other two. Progressive disclosure is a genuinely good idea — a large corpus of procedural knowledge that costs nothing until relevant is a real advance over stuffing a system prompt. Use them for how-we-do-things. Do not use them for must-not-happen.
I would re-assess when MCP's authorisation story matures further — today the protocol gives you the seam and largely leaves the policy to you, and a standard for capability scoping is the change that would push it from a strong Adopt to an obvious one.
References
MCP is young enough that the specification is the primary source and most commentary is speculation. I have leaned on the spec.
Primary sources
- Model Context Protocol — specification. The transport, the tool contract, and the boundary model that gives MCP its security score.
- modelcontextprotocol on GitHub. SDKs, reference servers, and the inspector — the ecosystem breadth behind the 4.5.
- Agent Skills documentation. Progressive disclosure and the frontmatter contract.
- OpenAI — function calling and Anthropic — tool use. The mature baseline both newer options are measured against.
Background
- OWASP Top 10 for LLM Applications. Prompt injection as LLM01 — the reason the security-boundary axis carries the weight it does here.
Deeper reading (blog)
The internals behind the scores:
- Building MCP Servers — the implementation detail behind these scores.
- MCP vs Agent Skills — the deep-dive on why these solve different problems.
- Prompt Injection & Guardrails — why a Skill is not a security control.
- Agent Harness Design — the scaffolding all of this plugs into.
- Evaluating LLM Agent Systems — how you find out any of it works.
- Radar: Voice Agent Platforms — where the MCP latency hop actually bites.
Scores are my own architect-level judgment for the stated use case, calibrated to mid-2026 — not a vendor ranking. Agent-integration axes, two inverted. NOT comparable with any other assessment here. Re-score against your own POC numbers before you commit.