How to Make an Agent Extension Portable Across Harnesses

Put the capability behind an MCP server, because tool access is the layer with a cross-vendor standard. Keep instructions, packaging, and invocation in thin per-harness wrappers, since those formats are vendor-specific and change. The portable core should hold the logic and none of the harness assumptions.

One layer is standardized and the rest is not

Extending an agent means adding one of three things: knowledge of how to do something, access to a system it cannot reach, or a package that distributes either.

The portability of each differs sharply, and this is the fact the phrase build once run everywhere tends to obscure.

Tool access is standardized. MCP defines how an agent discovers and calls tools, so a server exposing a capability works with any harness that speaks the protocol. This is the layer where write once actually holds, and it is why the protocol mattered.

Instructions are not standardized. How a harness loads procedural knowledge, where that content sits in the request, how it is scoped or triggered, and what format the file takes all differ by vendor and change between versions. There is no portable format for telling an agent how your team does something.

Packaging is not standardized. Plugin manifests, marketplaces, installation paths, and permission models are per vendor by construction.

So the portable design follows directly. Put the capability, including as much of the logic and judgement as you can express in code, inside an MCP server. Keep the per-harness surface to a thin wrapper containing the instructions and the packaging, and accept that this wrapper gets rewritten for each target.

That inverts what many teams do, which is to write an elaborate skill for one product and then discover that the elaborate part is exactly the part that does not move.

Push logic down into the server

The practical version of the rule: every decision you can make in the server is a decision you do not have to re-express in each harness's instruction format.

Validate and constrain in the server. If a parameter has valid values, enforce it in the tool rather than describing it in a prompt. Instructions are advisory to a model; server-side validation is not.

Return structured, self-describing results. A response that states what it is, what was excluded, and what to do next needs less accompanying instruction, which shrinks the wrapper. A response that requires three paragraphs of explanation to interpret has pushed work into the non-portable layer.

Make tool descriptions carry their own usage. The description a server publishes travels with the protocol. Whatever you can say there does not need repeating in a vendor-specific instruction file.

Keep the tool surface small and composable. Many narrowly scoped tools with clear names are easier for any harness to use well than one tool with a mode parameter and a long explanation.

Do not assume a filesystem. The most common portability failure is a server that assumes it runs alongside the agent with the same working directory and the same file access. Harnesses differ on where the server runs, whether the paths agree, and whether the process is even on the same machine. Take paths and content as parameters rather than reading ambient state.

Do not assume approval behaviour. Some harnesses prompt before a tool call, some do not, and some vary by tool. A server that relies on a human seeing a confirmation is relying on something not guaranteed. If an operation is destructive, require an explicit parameter that a caller must set deliberately.

The instruction budget is spent per request

Whatever the wrapper writes into the system prompt is paid for on every request, in every harness that loads it. That cost is a reason to keep the wrapper thin beyond portability alone: a long skill file loaded into every session is a recurring charge, and the version of it that survives contact with a second harness is usually the short one that pointed at good tools rather than explaining how to use bad ones.

Testing the claim

Portability is a property you verify, not one you design in and assume.

Bring up a second harness before you finish the first. The initial target hides every assumption you made, and the assumptions are cheap to remove early and expensive later. This is the single highest value step and it is routinely deferred until a user reports the problem.

Run the same task through both and compare. Not just whether the tool call succeeded, but whether the agent chose it at the right moment, supplied sensible parameters, and interpreted the result correctly. A tool that works and is never selected is not portable, it is just present.

Watch for the failure that only appears under a different invocation model. Servers started per session behave differently from long-lived ones: cached state, connection reuse, and anything holding a lock are the usual casualties.

Version the protocol surface deliberately. Tool names and parameter shapes are your public interface across every harness at once. Renaming a tool breaks all of them simultaneously, so treat additions as cheap and changes as expensive.

One closing note on where the effort belongs. A portable extension gives an agent access to a system. It does not give the agent the grounding to use that access well, and a tool called with confident wrong parameters is not an improvement over no tool. Retrieval that supplies the agent with the relevant context, such as RDK's stacked retrieval resolving most queries before the model is involved, is what makes the capability useful once it is reachable. Portability solves distribution. Grounding solves whether the thing works.

Frequently asked questions

Can you write an agent extension once and run it in any harness?
Partly. Tool access is standardized through MCP, so a server exposing a capability works with any harness speaking the protocol. Instructions and packaging are vendor-specific and change between versions, so those wrappers get rewritten per target. Put the logic in the standardized layer and keep the wrappers thin.
What is the most common portability failure?
A server that assumes it runs alongside the agent with the same working directory and file access. Harnesses differ on where the server runs, whether paths agree, and whether it is on the same machine at all. Take paths and content as explicit parameters rather than reading ambient state.
Should logic live in the skill or the server?
The server. Every decision made in the server is one you do not re-express in each harness's instruction format, and server-side validation is enforced while instructions are advisory to a model. It also keeps the wrapper short, which matters because prompt content is paid for on every request.
How do you verify an extension is actually portable?
Bring up a second harness before finishing the first, then run the same task through both. Compare whether the agent selected the tool at the right moment and interpreted the result, not just whether the call succeeded. A tool that works but is never chosen is present rather than portable.