How Ponytail Handles Host-Specific Adapters for Different AI Platforms

Ponytail uses a thin-adapter architecture that keeps core logic in shared skill files while providing host-specific glue code for Claude Code, Codex, OpenCode, Hermes, MCP servers, and others.

The Ponytail project—available at DietrichGebert/ponytail—implements a "lazy senior developer" coding assistant that runs across dozens of AI platforms. Rather than duplicating logic for every host, the codebase separates core behavior from platform-specific adapters, enabling consistent behavior with minimal per-host code.

The Three-Layer Adapter Architecture

Ponytail organizes its host support into three conceptual layers. Understanding this structure explains why adding a new platform requires only thin wiring code.

Core Skills Layer

The six Ponytail skills live under skills/ as markdown rule files:

  • ponytail — main coding assistant
  • ponytail-review — code review mode
  • ponytail-audit — security audit mode
  • ponytail-debt — technical debt analysis
  • ponytail-gain — optimization suggestions
  • ponytail-help — documentation mode

Each skill's SKILL.md contains the complete rule set injected into the model's prompt. Adapters never re-implement this logic—they only point the host at the correct file path.

Always-On Rule Files

For hosts without skill or hook support, Ponytail provides static rule copies:

These files contain identical logic reformatted for each host's expected structure.

Plugin Manifests and Hook Wiring

Full-featured adapters use JSON/YAML manifests and JavaScript hook files:

Component Purpose Example Path
Plugin manifest Declares version, entry points, skill paths .qoder-plugin/plugin.json
Hook configuration Maps lifecycle events to handler files hooks/qoder-hooks.json
Mode tracker Parses /ponytail commands, persists state hooks/ponytail-mode-tracker.js
Activation script Runs on sessionStart hooks/ponytail-activate.js

The shared ponytail-mcp/instructions.js builds the actual instruction payload, ensuring all adapters inject identical context regardless of host platform.

How Host-Specific Adapters Work

The adapter lifecycle follows four standard phases across all supported platforms.

1. Discovery via Manifest

When a host initializes, it reads a platform-specific manifest file. The Qoder manifest at .qoder-plugin/plugin.json demonstrates the pattern:

{
  "name": "ponytail",
  "version": "1.0.0",
  "skillsDir": "skills/",
  "hooks": "hooks/qoder-hooks.json",
  "commands": ["/ponytail", "/ponytail-review"]
}

The skillsDir field enables skill registration; the hooks field enables lifecycle integration.

2. Hook Registration and Execution

The hook configuration file maps host events to handler scripts. From hooks/qoder-hooks.json:

{
  "sessionStart": "hooks/ponytail-activate.js",
  "userPromptSubmitted": "hooks/ponytail-mode-tracker.js"
}

These hooks execute at precise moments in the conversation lifecycle, enabling stateful mode management without host-native code.

3. Skill Registration

For hosts supporting callable skills (Claude Code, Codex, Hermes, OpenCode, pi), the manifest registers each skills/<name>/SKILL.md as an invocable tool. Users trigger skills via:

  • ponytail:review (Claude Code style)
  • @ponytail-review (Codex style)
  • /ponytail-review (Discord-like slash commands)

4. Mode-Specific Injection

The critical function build_injected_context (Hermes __init__.py) or buildInstructions (MCP server) filters the skill markdown by current mode before each LLM call. This ensures the model receives only relevant instructions—ultra mode for exhaustive analysis, lite for quick tasks, review for focused critique.

Supported Host Adapters

Ponytail ships working adapters for 12+ AI platforms, organized by capability level.

Claude Code — .claude-plugin/plugin.json, commands/, hooks/claude-codex-hooks.json

Complete implementation with session activation, mode tracking, and status-line integration.

Codex — .codex-plugin/plugin.json, hooks/claude-codex-hooks.json

Identical feature set to Claude Code, sharing the same hook file.

Hermes Agent — plugin.yaml, __init__.py

Native Python plugin using Hermes's pre_llm_call hook for context injection. The __init__.py implements slash-command rewriting and skill registration:


# Hermes skill registration

ctx.register_skill('ponytail', Path('skills/ponytail/SKILL.md'))

# Pre-LLM injection hook

async def pre_llm_call(self, context):
    mode = self.get_mode()
    context.system_prompt += build_injected_context(mode)

OpenCode — .opencode/plugins/ponytail.mjs

Server plugin using experimental.chat.system.transform to modify prompts each turn.

Qoder — .qoder-plugin/plugin.json, hooks/qoder-hooks.json

Auto-loads AGENTS.md and provides all six skills with full hook support.

Always-On Rule Adapters (Static Files Only)

These hosts read rules but don't support dynamic hooks:

Host Adapter Location Mechanism
Cursor .cursor/rules/ponytail.md Rules file in project root
Windsurf .windsurf/rules/ponytail.md IDE-specific rules directory
Cline .cline/rules/ponytail.md Same pattern
Antigravity .antigravity/rules/ponytail.md Same pattern
Gemini CLI gemini-extension.json contextFileName → AGENTS.md
GitHub Copilot .github/copilot-instructions.md Repository-level instructions

MCP Server Adapter

ponytail-mcp/index.js — Platform-agnostic entry point for any MCP-capable host.

The MCP server exposes Ponytail as both a prompt (for direct injection) and a tool (for on-demand retrieval):


# Start the MCP server

node ponytail-mcp/index.js --mode ultra

Tool invocation from any MCP client:

{
  "tool": "ponytail_instructions",
  "input": { "mode": "lite" }
}

Response includes structured instructions and plain-text version. This adapter does not replace always-on adapters—it provides an optional, clean integration path for tool-aware hosts.

Marketplace/Distribution Adapters

Grok Build — .grok-plugin/marketplace.json, plugin.json

Installable via grok plugin install ponytail. Uses always-on rules without lifecycle hooks.

Practical Adapter Usage Examples

Switching Modes in Claude Code

// In an active Claude Code session
/ponytail full

The userPromptSubmitted hook in hooks/ponytail-mode-tracker.js detects this command, writes "full" to a temporary state file, and returns the complete instruction set for the new mode.

Using OpenCode with Plugin

opencode chat --plugin ponytail.mjs --prompt "Refactor this React component"

The experimental.chat.system.transform hook calls buildInstructions(currentMode) before every turn, ensuring consistent behavior across the conversation.

Hermes Agent Script Integration


# In a Hermes agent workflow

await ctx.run_skill('ponytail-audit')  # Triggers security audit rules

await ctx.run_skill('ponytail')        # Returns to default coding mode

The pre_llm_call hook in __init__.py automatically injects the correct SKILL.md content based on the active skill and mode.

Direct MCP Tool Call


# From any MCP-compatible client

echo '{"tool": "ponytail_instructions", "input": {"mode": "debt"}}' \
  | node ponytail-mcp/index.js

Returns technical debt analysis rules formatted for immediate use.

Key Design Principles

The Ponytail adapter system follows strict architectural constraints visible throughout the source:

  • Adapters stay thin — No logic duplication; all instruction building flows through ponytail-mcp/instructions.js
  • Single source of truth — skills/*/SKILL.md files are the authoritative rules
  • Host capability detection — Adapters degrade gracefully: full hooks where supported, static files where not
  • Stateless where possible — Mode state lives in environment variables or temp files, not host-specific storage

These principles appear in the docs/agent-portability.md documentation and are enforced by the shared buildInstructions implementation.

Summary

  • Ponytail separates core skills (skills/*/SKILL.md) from host-specific adapters that wire those skills to platform APIs
  • Full-featured adapters (Claude Code, Codex, Hermes, OpenCode, Qoder, pi) use manifests, hooks, and mode-tracking scripts to enable dynamic skill switching
  • Always-on adapters (Cursor, Windsurf, Gemini, Copilot) copy static rule files to host-expected locations
  • The MCP server adapter (ponytail-mcp/index.js) provides a clean, protocol-based integration for any tool-capable host
  • All adapters share ponytail-mcp/instructions.js for instruction building, ensuring identical behavior across platforms
  • Mode-specific injection happens via build_injected_context (Hermes) or buildInstructions (MCP), filtering skill content before each LLM call

Frequently Asked Questions

What makes a Ponytail adapter "thin"?

A thin adapter contains only platform-specific glue code—manifest parsing, hook registration, and event forwarding—while delegating all instruction building to shared scripts like ponytail-mcp/instructions.js. The "no logic in adapters" rule ensures that fixing a bug in skill behavior requires changing only the core SKILL.md files, not every adapter.

Can I use Ponytail with a host not in the supported list?

Yes. Copy AGENTS.md or any skills/*/SKILL.md file to your host's rules/instructions location. For hosts supporting custom tools or MCP, run node ponytail-mcp/index.js and configure the host to connect to this server. The docs/agent-portability.md file provides guidance for building new adapters.

How does mode switching work across different adapters?

Mode state persists in environment variables or temporary flag files (e.g., .ponytail_mode), readable by all hook scripts. When you type /ponytail review in Claude Code or Codex, hooks/ponytail-mode-tracker.js writes this state; the next pre_llm_call or userPromptSubmitted hook reads it and calls buildInstructions(mode) with the new value.

What's the difference between a skill and a mode in Ponytail?

A skill is a complete rule set in skills/<name>/SKILL.md (e.g., ponytail-review). A mode is a filtering parameter (lite, full, ultra) passed to build_instructions that selects how much of the active skill's content to inject. Skills switch behavior categories; modes adjust depth within a category.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →