cd /news/ai-agents/your-claude-skill-is-invisible-to-co… · home topics ai-agents article
[ARTICLE · art-58163] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Your Claude Skill Is Invisible to Codex. Here's How to Fix It.

A developer proposes a standardized format for agent skill files to solve interoperability issues between AI coding agents like Claude Code and Codex. The current fragmented landscape forces developers to manually rewrite the same skill for each agent, incurring an 'interop tax'. The solution involves splitting capabilities into contracts and implementations, analogous to ERC-20 tokens, enabling any agent to load any skill.

read10 min views1 publishedJul 14, 2026

Disclosure up front: I build

[agentproto], whose spec

registry (the AIPs) is the last third of this piece. The problem in the first

half stands on its own, and the walkthrough uses real, checkable commands.

Corrections welcome — file an issue.

You spent an afternoon writing a good skill. A SKILL.md

, a couple of scripts,

a crisp description so the model knows when to reach for it. Claude Code picks it

up and uses it perfectly.

Now open Codex in the same repo. Nothing. The skill is invisible — wrong folder,

wrong format, wrong dialect. Point a cheap local model at the task and you get

the same blank stare. You wrote the capability once, and exactly one agent can

see it.

The one idea, if you remember nothing else:

Everyone converged on folders of markdown with zero interop. It's Ethereum

before ERC-20 — the primitive is proven, and nothing can hold anyone else's.

Open any serious agent-driven repo in 2026 and you find the same sediment: a

CLAUDE.md

, an AGENTS.md

, maybe a GEMINI.md

saying mostly the same thing; a

.claude/skills/

folder full of SKILL.md

; Codex agents in TOML; a .mcp.json

;

somebody's OPERATOR.md

. Every tool independently discovered the same primitive

agent behavior configured as files in the repo — and every tool speaks its

own dialect of it.

This is a genuinely good primitive, and the convergence is evidence it's right.

Files are diffable, reviewable, versionable; they ride along in git; agents can

read and write them, which is what lets an agent improve its own tooling.

Anthropic's harness team, describing their long-running app builder (March

2026), put it plainly: "communication was handled via files."

Repository as constitution.Here's why this shape won: each new agent

session arrives like a new contributor with shell access but no knowledge of

your team's norms, so a shortAGENTS.md

acts as the repo's constitution for

agents. The pattern is settled. The interop is what's missing.

The dialects are the whole problem. They don't even agree on names: it's

skill.title

in one flavor, skill.name

in another, three incompatible spins on

AGENTS.md

. A capability you wire into one product's config is invisible to the

other four agents in your fleet — so you re-wire it, by hand, every time you add

a brand.

That manual re-wiring, with your name on it, is the interop tax — and it's the part of "orchestration" nobody sells you a fix for. Before we build one, do the

Where are you?0 duplicated declarations— you're single-agent, not

your problem yet.2–3(aCLAUDE.md

here, anAGENTS.md

there) — you're

paying the tax quietly, once per new brand.4+— youarethe interop

layer, by hand, and it costs an afternoon per new agent.

Watch where the platform layer is heading, because it validates the whole idea.

Anthropic's Managed Agents (April 2026) virtualizes the runtime: the session is

an append-only log, the harness is disposable, the sandbox sits behind one

generic execute

interface. Stable contracts between layers, so each layer swaps

freely.

Design it like an OS.The Managed Agents write-up is explicit about the

principle: to build infrastructure that accommodates "programs as yet unthought

of," you"decouple the brain from the hands via a uniform tool interface"and

put stable interfaces over swappable implementations.

That's exactly the right instinct — and it's hosted, and it's Claude-only. The

same layering, done in the open, is just as valuable one floor below the

runtime: stable contracts for the files. What a tool promises, how a driver

implements it, what a skill declares. Make those contracts public and versioned,

and any host can load any capability — the way any wallet holds any ERC-20.

So let's actually build one and watch it reach three different agents.

The trick is to split what most formats fuse. A capability is two things: a

contract (its name, its inputs and outputs, whether it's allowed to mutate

anything) and an implementation (the code that runs). Fuse them and the

capability is welded to one runtime. Separate them and the contract is the part

that ports.

Here's a docs-search tool as a pure contract — agentproto's defineTool

(the AIP-14 TOOL.md

spec). Note what's not here: no execute body.

// tools/docs-search/TOOL.ts — the contract, and nothing else
import { defineTool } from "@agentproto/tool"
import { z } from "zod"

export const docsSearch = defineTool({
  id: "docs.search",
  description: "Search the team's internal docs. Returns titles + URLs.",
  inputSchema: z.object({ query: z.string(), limit: z.number().default(5) }),
  outputSchema: z.object({
    hits: z.array(z.object({ title: z.string(), url: z.string() })),
  }),
  mutates: [],        // read-only → no approval gate needed
  approval: "auto",
})

The contract carries identity, schemas, and a side-effect profilemutates

and approval

are how a supervisor later decides whether this call needs a human

(read-only tools sail through; a tool that writes files gets gated). One file,

one declared promise, zero opinion about how it's fulfilled.

This is the piece that makes a capability portable: a promise any runtime can read without running anyone's code.

Now the code. A DRIVER (AIP-30's defineDriver

) bundles one or more

implementations, each bound to a tool contract by implementTool

. The binding is

type-checked against the contract's schemas.

// drivers/docs-meili.ts — one implementation of the contract above
import { defineDriver, implementTool } from "@agentproto/driver"
import { docsSearch } from "../tools/docs-search/TOOL.js"

export default defineDriver({
  id: "docs.search.meili",
  name: "Docs search via Meilisearch",
  kind: "http",
  implementations: [
    implementTool(docsSearch, async ({ input }) => {
      const res = await fetch(`${process.env.MEILI_URL}/indexes/docs/search`, {
        method: "POST",
        body: JSON.stringify({ q: input.query, limit: input.limit }),
      })
      const { hits } = await res.json()
      return { hits: hits.map((h) => ({ title: h.title, url: h.url })) }
    }),
  ],
  network: { egress: ["MEILI_URL"] }, // declared reach, not ambient
})

The codebase makes the analogy for you. The implementTool

doc comment calls it

"equivalent to Solidity's MyToken is IERC20 pattern" — the compiler enforces

docs.search

keeps working.

Why the split earns its keep.A driver declares its ownnetwork.egress

,

its auth, its install steps — so the samedocs.search

contract can have a

local implementation, a hosted one, and a mock for tests, and the resolver

picks one per call. That's "stable interfaces over swappable implementations,"

but foryourtools, inyourrepo, not behind a vendor's API.

Two files. Now the payoff.

Start the daemon in your repo. It reads your tools/

and drivers/

and exposes

them over MCP:

npm i -g @agentproto/cli
agentproto install claude-code          # also installs the adapter package
agentproto serve                        # long-lived daemon, serves the /mcp gateway

Now spawn agents. Each adapter is pointed at the daemon's /mcp

gateway as it

starts, so all of them see the same served tools — including your docs.search

:

agentproto sessions start claude-code --cwd . \
  --prompt "Use docs.search to find our retry-policy page, then summarize it."

agentproto sessions start codex --cwd . \
  --prompt "Use docs.search to check whether we document the queue timeout."

agentproto sessions start hermes --cwd . \
  --prompt "Use docs.search for 'deploy rollback' and list the top 3 hits."

One contract, one driver, three vendors — Claude Code, Codex, and a local model via Hermes all call docs.search with no per-agent wiring. The daemon is

This is the answer to the question the hub piece

left open — when you give one agent a new capability, how many of the others get it? Here the answer is "all of them, for free," and that's the difference between

The same "one place, every agent" trick works for tools you didn't write. MCP

servers are the industry's one real interop win — but each agent brand configures

them separately, so a server wired into Claude Code is still invisible to Codex.

agentproto imports an MCP server once into the daemon's curated set, and then

every session can reach it. The flow is three real tool calls:

mcp_discovered_list      → find MCPs already configured in claude/cursor/etc.
mcp_import               → snapshot one into the daemon (survives the source
                           config being deleted later)
mcp_imported_tool_list   → search-then-call: list the imported server's tools…
mcp_imported_call        → …and invoke one

The import captures a snapshot at import time, so the tool stays usable even if

you later remove the original config. You wire an MCP server up once, in one daemon, and Claude Code, Codex, and your local model all inherit it — instead of

.mcp.json

block into four different agent configs and keepingThat's the whole interop tax, refunded: author-once for tools you write, import-

once for tools you borrow.

Here's the honest edge, because that's what makes the rest trust me. You could do

all of this with a bespoke framework. The bet agentproto makes is not a

framework — it's a registry of numbered specs, modeled deliberately on ERCs, BIPs,

and PEPs. TOOL.md

is AIP-14. DRIVER.md

is AIP-30. Skills, operators,

workflows, policies, sandbox definitions each get a number.

The reason to prefer numbers over a framework is projection. A contract that's a

public spec, not a class in someone's SDK, can be adapted to any host:

toMastraTool(impl)

for a Mastra agent, or toAiSdkTool(impl)

for the Vercel AI SDK,TOOL.md

(AIP-16 declares the IO as JSON Schema, no compiled module required).

Aligned-with, not forked-from.A Claude Code skill is already most of an

AIP skill; the specs are meant to standardize the format people converged on,

not replace it. And they'reours, plural: Apache-2.0, open to amendment by

issue — the entire point of a numbered public registry is that no single vendor

owns the meaning ofdocs.search

.

The honest caveats, stated plainly: agentproto is 0.5.0-alpha. The daemon, the

MCP surface, the driver doctype, and MCP import are live and hands-on today; the

in-process Mastra / AI-SDK adapters and the wider ~52-spec family are earlier-stage

— the repo publishes a live-vs-roadmap split precisely so you can check. Betting on

a young registry is a real cost. So is re-wiring the same tool by hand forever.

Pick your poison with open eyes.

Once a capability is files with a contract, the loop closes in a way no config

format allows. An agent can write a new TOOL.md

, bind a driver, or scaffold

a skill — and because those are file writes, they're diffs you can gate exactly

like any other code.

This is where this piece hands off to the supervision ladder:

stage the agent-authored tool behind a check and a human ack, and your fleet's

capabilities grow the way your codebase grows — incrementally, reviewed, in git —

instead of the way config sprawl grows. The daemon even exposes the doctype verbs

(create_tool

, create_driver

, list_driver

, self_inspect

) as MCP tools, so

an agent authors its own next capability through the same interface it uses to

call the last one.

That's the actual endgame of files-with-contracts: not tidier config, but agents that safely extend themselves, under the same review discipline as a human PR.

You don't need my daemon to start paying down the tax:

Count your capability re-declarations one more time. Every number above one is a

place a dialect can drift, an agent that's blind to a tool it should have, and an

afternoon of your life spent being human glue. The pattern is settled; the

plumbing is the only thing left to build — and it's a couple of files, not a

platform migration.

We had folders of markdown and called it interoperability. It never was. The fix

isn't another framework that everyone reinvents next quarter — it's a contract

anyone can read and no one owns.

If I've mis-described how your agent stack handles this, or you've solved the

interop tax a cleaner way, tell me where — I'll fix the piece.

Ten pieces, one argument. Start anywhere; each one cross-links the rest.

Piece The one idea
1

Written by the maintainer of agentproto (Apache-2.0, source). Same contract as our /compare page — dated facts, named strengths, corrections by issue. Got something wrong? File an issue.

Building agentproto in the open — follow @theagentproto and @agentik_ai on X.

── more in #ai-agents 4 stories · sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/your-claude-skill-is…] indexed:0 read:10min 2026-07-14 ·