How to Build an Agent Plugin for Any Harness
Build an Agent Plugin for Microsoft 365 Copilot Cowork, Codex, Claude Cowork, Claude Code, OpenClaw, Hermes Agent, and SKILL.md-based harnesses: define the product, package Skills and components, adapt it per harness, and measure it.
This guide shows how to build an Agent Plugin for XYZ - any domain-specific capability you want users to install in Microsoft 365 Copilot Cowork, Codex, Claude Cowork, Claude Code, OpenClaw, Hermes Agent, or a harness that supports SKILL.md.
Start with the plugin, not the harness. The plugin is the installed product users choose, version, and trust. A Skill is one task-specific capability inside that plugin. A useful plugin may also contain MCP config, connectors, hooks, agents, commands, assets, or app integrations.
The goal is to build the plugin once, then deploy it through harness-specific adapters. Codex wants a .codex-plugin/ package. Microsoft 365 Copilot Cowork wants a Microsoft 365 app package. Claude wants a .claude-plugin/ package. OpenClaw and Hermes Agent expose richer plugin extension points for tools, Skills, providers, hooks, commands, integrations, and runtime components. Other tools may only expose SKILL.md directories. Telvine should be the source-of-truth workspace that keeps the product, components, versions, and telemetry consistent across all of them.
1. Pick the plugin product
Define the plugin as a product before writing harness files:
- User: who installs it?
- Job: what work should the plugin make possible?
- Surfaces: which harnesses should it run in?
- Capabilities: which Skills, connectors, hooks, MCP config, or agents belong inside it?
- Telemetry: what package-level and capability-level events should prove it works?
For example, an invoice-ops plugin might include:
| Component | Purpose |
|---|---|
| Plugin | The installable invoice operations product |
Skill: reconcile-invoices | Match payments to invoices and report exceptions |
Skill: draft-collection-emails | Draft follow-up emails for overdue invoices |
| Connector or MCP config | Read invoices from the accounting system |
| Hook | Emit a completion or failure event after each run |
2. Create the source plugin workspace
Keep one canonical plugin workspace before generating platform-specific packages:
invoice-ops/
├── telvine.plugin.json
├── skills/
│ └── reconcile-invoices/
│ └── SKILL.md
├── connectors/
│ └── accounting-api/
├── hooks/
│ └── after-run/
├── assets/
│ └── logo.png
└── adapters/
├── codex/
├── copilot-cowork/
├── claude/
├── openclaw/
└── hermes/
Think of telvine.plugin.json as the product record: name, owner, version, component inventory, target harnesses, and telemetry policy. The adapters/ folders are generated or maintained outputs for each platform.
3. Build the first Skill capability
Most plugins should start with one excellent SKILL.md. Keep it narrow and measurable:
---
name: reconcile-invoices
description: >
Use this skill when the user asks to "reconcile invoices",
"match payments to invoices", or "find unmatched payments".
Reconciles payments against open invoices and reports exceptions.
---
# Reconcile invoices
## Steps
1. Confirm the accounting period and locate the invoice and payment data.
2. Match payments to invoices by customer, reference, date, and amount.
3. List unmatched payments, partial matches, and suspected duplicates.
4. Produce a review table. Never modify source records.
See the SKILL.md template for a fuller scaffold.
4. Package it for each harness
The portable core is your plugin source: the Skills, scripts, references, connectors, assets, and telemetry conventions. Each harness then gets an adapter.
| Harness | Plugin/package shape | What to ship |
|---|---|---|
| Microsoft 365 Copilot Cowork | Microsoft 365 app package | Skills, connectors, or both, with telemetry from backend and connector surfaces |
| OpenAI Codex | .codex-plugin/plugin.json at the plugin root | skills/, hooks/, .app.json, .mcp.json, and assets/ as needed |
| Anthropic Claude Cowork / Claude Code | .claude-plugin/plugin.json at the plugin root | Skills, connectors, agents or sub-agents, hooks, MCP config, commands, and assets as supported |
| OpenClaw | OpenClaw plugin package | Tools, Skills, channels, model providers, agent harness integrations, speech, media, web, generation, and runtime components as needed |
| Hermes Agent | Hermes plugin package | Tools, hooks, slash commands, CLI commands, integrations, bundled Skills, memory providers, context engines, and model providers |
| GitHub Copilot | Skill capability package | Place Skills where Copilot loads SKILL.md; keep plugin identity and version in your release process |
| Cursor, Windsurf, Gemini CLI, Antigravity | Skill capability package | Place the same SKILL.md in the harness-specific Skills directory and preserve plugin-level versioning outside the harness |
The important rule: do not let a harness adapter become the product model. Your plugin id, version, component inventory, release history, and telemetry contract should stay stable even when the folder layout changes per harness.
5. Microsoft 365 Copilot Cowork layout
For Microsoft 365 Copilot Cowork, package the plugin as a Microsoft 365 app. Cowork plugins can contain Skills, connectors, or both, and Microsoft currently documents the feature as Frontier functionality.
invoice-ops/
├── manifest.json
├── skills/
│ └── reconcile-invoices/
│ └── instructions.md
├── connectors/
│ └── accounting-api/
└── telemetry/
└── telvine-events.md
Use Telvine to keep a stable plugin id, component inventory, and version history even if Microsoft changes preview-era packaging details. See How to Build a Microsoft 365 Copilot Cowork Plugin for the dedicated guide.
6. Codex plugin layout
For Codex, create a plugin folder with a required .codex-plugin/plugin.json manifest:
invoice-ops/
├── .codex-plugin/
│ └── plugin.json
├── skills/
│ └── reconcile-invoices/
│ └── SKILL.md
├── hooks/
│ └── hooks.json
├── .mcp.json
└── assets/
└── logo.png
Keep plugin.json inside .codex-plugin/. Keep skills/, hooks/, .mcp.json, .app.json, and assets/ at the plugin root.
7. Anthropic Claude Cowork and Claude Code layout
For Anthropic Claude, package the same plugin product with a .claude-plugin/plugin.json manifest:
invoice-ops/
├── .claude-plugin/
│ └── plugin.json
├── skills/
│ └── reconcile-invoices/
│ └── SKILL.md
├── hooks/
│ └── hooks.json
└── .mcp.json
Claude Cowork is the knowledge-work surface; Claude Code is the developer surface. Treat them as different install targets for the same plugin product when the underlying capability is shared.
8. OpenClaw plugin layout
For OpenClaw, package the same plugin product with an OpenClaw adapter:
invoice-ops/
├── adapters/
│ └── openclaw/
│ ├── openclaw.plugin.json
│ ├── package.json
│ ├── src/
│ │ └── tools/
│ │ └── accounting-lookup.ts
│ └── skills/
│ └── reconcile-invoices/
│ └── SKILL.md
├── connectors/
│ └── accounting-api/
└── telemetry/
└── events.md
OpenClaw plugins can cover more than Skills. Treat tools, channels, providers, agent harness adapters, speech, media, web, and generation components as plugin components with their own telemetry. See How to Build an OpenClaw Plugin for the dedicated guide.
9. Hermes Agent plugin layout
For Hermes Agent, package the plugin product with a Hermes adapter:
invoice-ops/
├── adapters/
│ └── hermes/
│ ├── plugin.yaml
│ ├── __init__.py
│ ├── schemas.py
│ ├── tools.py
│ ├── hooks.py
│ └── skills/
│ └── reconcile-invoices/
│ └── SKILL.md
├── connectors/
│ └── accounting-api/
└── telemetry/
└── events.md
Hermes plugins can include tools, hooks, commands, integrations, bundled Skills, memory providers, context engines, and model providers. Keep each one in the Telvine component inventory so the product can be compared against Codex, Claude, OpenClaw, and Copilot Cowork. See How to Build a Hermes Agent Plugin for the dedicated guide.
10. Harnesses that expose Skills directly
Some harnesses expose SKILL.md before they expose a full plugin manifest. Still think in plugins:
- Keep a source plugin folder with the plugin name, owner, version, changelog, Skills, scripts, references, and telemetry plan.
- Generate or copy the Skill capability into the harness-specific directory.
- Keep the plugin id and version in your telemetry events.
- Measure the capability as part of the plugin, not as a detached file.
That lets the same reconcile-invoices Skill run in Cursor, Windsurf, Gemini CLI, Copilot, or Antigravity without losing the plugin-level product view.
11. Measure plugin and capability behavior
Measure both layers:
- Plugin events: installed, updated, enabled, disabled, component inventory registered.
- Skill events: invoked, completed, errored, rated, version compared.
- Component events: connector invoked, hook executed, MCP operation wrapped, app action completed.
With Telvine, publish the plugin:
npm i -g @telvine/cli
telvine login
telvine publish ./my-plugin
Use plugin components to register non-Skill components and decide whether each component emits runtime events or is inventory-only.
12. Release through adapters
When a plugin version is ready, release the same source plugin through each target adapter:
- Generate or update the Codex package.
- Generate or update the Microsoft 365 Copilot Cowork app package.
- Generate or update the Claude plugin package.
- Generate or update the OpenClaw plugin package.
- Generate or update the Hermes Agent plugin package.
- Export direct
SKILL.mdpackages for harnesses that do not yet expose full plugin manifests. - Register the plugin version and component inventory in Telvine.
- Compare telemetry across harnesses after rollout.
The cross-harness question is not "did this Skill run?" It is "does this plugin product work across the surfaces where our customers use agents?"
Checklist
- The plugin has a stable name, owner, version, and install target.
- The source plugin workspace exists before any harness-specific adapter.
- The first Skill has a precise trigger description.
- Deterministic work lives in scripts, not prose.
- Each harness has an adapter, but the plugin identity stays stable.
- Telemetry records plugin version and capability version.
- Events use typed metadata only: no prompts, file contents, connector payloads, or tool arguments.