LLMs Technical Reviews

How can it be extended and customised?

MCP; plugins or custom tools; rules/instruction files (AGENTS.md etc.); hooks; headless/SDK use.

Verdict

Codex, Qwen Code and Cline have the fullest extension surfaces, with MCP, hooks, plugins, skills and an embeddable API. Aider and Open Lovable have no MCP client and no plugins.

Full stack: MCP, hooks, plugins, skills and SDKs.

  • Codex: twelve hook events from config.toml or hooks.json, and skills and plugins as separate mechanisms. codex app-server exposes the full JSON-RPC protocol.
  • Open Interpreter: the same surface, plus new harnesses (a prompt, tool JSON and routing entry each).
  • Qwen Code: one extension, installed from git, npm or a GitHub release, can ship MCP servers, skills, sub-agents, hooks and workflows. SDKs exist for TypeScript, Python and Java.
  • Cline: JS/TS plugins run in a subprocess sandbox. @cline/core embeds the agent in your own code.
  • OpenCode: plugins from npm, plus custom tools you add by dropping files into a tool/ directory. Every UI is a client of one server API.

Host-mediated extensions.

  • DeepSeek-Reasonix: Extension Protocol v2 sidecars can intercept tool calls and host provider streams. sdk/go helps you write them.
  • PI-Desktop: .piplug packages whose tools pass the same Rust permission gate as built-ins.
  • Codewhale: project hooks run only after /hooks approve <digest> for those exact bytes. The TypeScript extension host is experimental and behind a feature flag.

Configuration and scripting. Aider offers --lint-cmd, --test-cmd, --watch-files comments and the Python Coder.create() API, but no hooks.

App builders.

  • bolt.diy: MCP over stdio, SSE or HTTP, with per-call approval. It does not read instruction files such as AGENTS.md.
  • VibeSDK: a TypeScript client SDK and four built-in SKILL.md skills. Its MCP manager ships with an empty server list, and the cli/tui scripts point to a directory that does not exist.
  • Open Lovable: extension stops at the sandbox-provider class and config files.

Pick: Codex or Qwen Code for a hook-and-plugin ecosystem with SDKs. Pick: Cline or OpenCode to embed an agent in your own product. Pick: bolt.diy for an app builder you can wire to MCP tools.

More projects in this category are being researched.

Per-project answers

anomalyco/opencode

answered

Extensibility

MCP (Model Context Protocol) is fully integrated via packages/opencode/src/mcp/. The MCP.Service manages MCP client connections supporting stdio, SSE, and Streamable HTTP transports (mcp/index.ts lines 1-80). MCP servers are configured in the user config and launched as child processes or connected via URL. MCP tools are automatically discovered and exposed to the LLM alongside built-in tools. The SessionTools.resolve function (session/tools.ts lines 390-491) wraps each MCP tool with permission checking, truncation, and event publishing. MCP resources can be listed and read via dedicated LLM tools (list_mcp_resources, read_mcp_resource, etc., lines 139-386).

Plugin system (plugin/index.ts): OpenCode loads plugins via two mechanisms: 1) Internal plugins — provider-specific auth plugins directly imported (Codex, Copilot, GitLab, Poe, Cloudflare, Azure, DigitalOcean, xAI, Cerebras, Snowflake Cortex, Modal) — see internalPlugins() (lines 67-86). 2) External plugins from npm or local files via the PluginLoader. Plugins can provide custom tools (registered via tool: hooks in the plugin module), extend system prompts, transform messages, modify tool executions, and hook into session lifecycle events. The Plugin.trigger() function fires hooks at named points like experimental.chat.system.transform, tool.execute.before, tool.execute.after, experimental.session.compacting, and experimental.text.complete (examples throughout processor.ts and prompt.ts).

Custom tools can be defined by placing {js,ts} files in {tool,tools}/ directories within config directories (tool/registry.ts lines 183-197). Each file exports tool definitions with args, description, and execute fields, which are automatically loaded and registered.

Rules/instruction files: The Instruction service loads instructions from AGENTS.md files in the project (the repo's AGENTS.md at root works as a per-repo instruction file). Skills are defined in .claude/sk.json or similar config.

Hooks are implemented via the Plugin system — the Hooks interface includes lifecycle callbacks for chat system transforms, message transforms, tool definitions, compaction, and more. Plugins can also act as Workspace Adapters via registerAdapter (control-plane/adapters/).

Headless/SDK use: OpenCode exports the @opencode-ai/sdk package (packages/sdk/) and @opencode-ai/plugin for programmatic use and plugin development. The opencode-ai npm package is designed for headless/CI use (curl -fsSL https://opencode.ai/install). The architecture separates core services (schema, protocol, core) from UI (TUI, web, desktop), enabling headless/server-mode operation.

Editor's note. Correction: skills are not defined in .claude/sk.json; they are directories with a SKILL.md, discovered by packages/opencode/src/skill/discovery.ts.

openai/codex

answered

Codex CLI is extensible through multiple mechanisms. MCP (Model Context Protocol) is the primary extension system: the codex-mcp crate in codex-rs/codex-mcp/src/lib.rs:1 implements MCP server management, tool catalog caching, and resource access. MCP servers are declared in config via McpServerConfig entries and discovered through the configured_mcp_servers() function, with their tools surfaced to the model through McpHandler (core/src/tools/handlers/mcp.rs). Skills (a plugin system) let users install task-focused packages — sample skills in codex-rs/skills/src/assets/samples/ include skill-installer, skill-creator, and imagegen — each with scripts and configurations. AGENTS.md files (core/src/agents_md.rs:42) provide per-project instructions: Codex discovers AGENTS.md (and AGENTS.override.md) by walking up from the project root to the current directory, concatenating their contents as system instructions. A fallback project_doc_fallback_filenames config option supports additional filenames. Hooks (core/src/hook_runtime.rs:1) support lifecycle callbacks at session start, user prompt submit, pre/post tool use, compact, and stop events. Hooks can inject context, block/allow actions, and request user permission. Plugins extend tool availability: core/src/plugins/ manages plugin discovery and installation, with tools like RequestPluginInstallHandler for runtime plugin requests. The config system (TOML-based with layered config in core/src/config/) allows full customization of model selection, permissions, approval policies, sandboxing levels, MCP server configuration, and environment definitions. Headless/SDK mode is supported via the exec crate which exposes Codex as an app-server with JSON-RPC (ClientRequest/ServerNotification in exec/src/lib.rs) — consumable by IDE extensions and automated tooling. The codex-cli/bin/package.json enables npm distribution as @openai/codex.

Editor's note. Correction: the JSON-RPC server for IDEs and other clients is the app-server crate (codex app-server); the exec crate is the non-interactive codex exec CLI, which itself talks to an in-process app-server.

cline/cline

answered

Cline is extensible through six mechanisms. (1) MCP (Model Context Protocol) — servers can be registered via JSON config files (mcp/config-loader.ts) over stdio, SSE, or streamable HTTP transports. Tools from MCP servers are wrapped as AgentTool instances and exposed to the model (mcp/tools.ts). (2) Agent Plugins — directory-based packages with a cline-plugin.json manifest declaring capabilities, tools, MCP servers, and skills; loaded and validated against the agent-plugins.org schema (agent-plugin/loader.ts). (3) Hook files — user-customizable shell scripts that fire on lifecycle events (run start, tool call start/end, run end), defined by CLINE_HOOK_FILE config (hook-file-hooks.ts). (4) Agent Extensions — runtime hooks registered via the AgentExtension interface with beforeTool, afterTool, beforeRun, afterRun callbacks, packaged as plugins or built-in features (plugin-loader.ts). (5) Skills and workflows — markdown files with frontmatter that define reusable agent instructions or multi-agent orchestration scripts. (6) SDK/headless use — @cline/core exports ClineCore.create() and ClineCore.start() for programmatic integration (ClineCore.ts:99), while @cline/agents provides the lower-level AgentRuntime that can be embedded directly. User instruction files (user-instruction-config-loader.ts) let projects add custom rules, and the unified config file watcher picks up changes dynamically.

Editor's note. Correction: agent plugins use plugin.json (agent-plugins.org schema) under .agents/plugins; Cline plugins are JS/TS modules in .cline/plugins that run in a subprocess sandbox. Hook files are discovered in hooks config directories; there is no CLINE_HOOK_FILE setting.

openinterpreter/openinterpreter

answered

MCP (Model Context Protocol) is the primary extension mechanism: McpHandler (core/src/tools/handlers/mcp.rs:51-60) wraps MCP tools into ToolSpec for the ToolRouter. codex-mcp module (codex-rs/codex-mcp/src/) manages connections, bindings, catalogs, and discovery. mcp-server/ provides MCP server runtime with tool config and exec approval. Plugins: PluginsManager with build_plugin_injections() (turn.rs:1099), PluginDeclaration (hooks/src/declarations.rs). Hooks: hooks/src/lib.rs:23-36 supports 12 events (PreToolUse, PostToolUse, PreCompact, PostCompact, SessionStart, SessionEnd, UserPromptSubmit, SubagentStart, SubagentStop, Stop, Interrupt, PermissionRequest). Hooks run as subprocesses and can block or modify state. AGENTS.md files (core/src/agents_md.rs:42-49): per-project instructions searched from project root to cwd. Default: AGENTS.md, override: AGENTS.override.md. SDK/headless mode via Python (sdk/python/) and TypeScript (sdk/typescript/) SDKs. Multiple SessionTask types (Regular, Review, UserShell). ExtensionData and TurnInputContributor allow runtime extension injection.

Aider-AI/aider

answered

No MCP or plugin system. The project has no MCP (Model Context Protocol) support and no plugin architecture. Extension is done through configuration, coders, and the custom model registry rather than a formal plugin API.

Custom coders. New edit formats can be added by subclassing Coder (aider/coders/base_coder.py) and registering the class in aider/coders/__init__.py's __all__ list. The dispatcher Coder.create() iterates coders.__all__ and matches by edit_format string (base_coder.py:190-194). This is how all 12+ coder types (diff, whole, udiff, architect, editor variants, etc.) are registered.

Custom models and settings. Users can add .aider.model.settings.yml and .aider.model-metadata.json files that override model parameters. register_models() (main.py:335-358) searches in the standard git-root search path. The YAML file defines ModelSettings entries; the JSON file adds cost/context-window metadata.

Conventions files. A file like CONVENTIONS.md can be loaded read-only with --read CONVENTIONS.md or configured in .aider.conf.yml as read: [CONVENTIONS.md]. This is highlighted in the project docs as the recommended way to inject standing instructions like coding conventions.

Headless / SDK use. The main() function in aider/main.py:451 is callable programmatically with return_coder=True to get a Coder instance back instead of running the interactive loop. The Coder.create() factory plus calling coder.run(with_message=...) allows non-interactive use. Environment variables serve as the config API (all CLI flags have corresponding AIDER_* env vars).

Slash commands. Over 30 built-in commands in aider/commands.py (Commands class) handle file management (/add, /drop, /read-only), git (/commit, /diff, /undo), model switching (/model, /chat-mode), execution (/run, /test, /lint), and session management (/clear, /reset, /save, /load).

--load for automation. The --load flag (args.py:773) reads and executes a file of slash commands on startup, providing a limited scripting mechanism.

codewhale-hq/Codewhale

answered

Codewhale is extensible through multiple mechanisms, ranked by integration depth:

MCP (Model Context Protocol) — crates/tui/src/mcp/: Multiple transport backends — stdio (stdio.rs, newline-framed JSON-RPC over child process), SSE (sse.rs for server-sent events), Streamable HTTP (streamable_http.rs), and raw HTTP (http.rs). OAuth support (oauth.rs) for authenticating MCP servers. Server configuration via McpServerConfig/McpPool, with per-turn catalog refresh. The MCP Registry (tools/mcp_registry.rs) provides a registry_sync tool for deferred discovery — the model queries for a capability and gets scored matches from a local snapshot.

Extension Host (extension_host/mod.rs:1) — A Bun/Node process running TypeScript plugins. Each plugin can contribute: tools (become ToolSpec entries behind the same permission gate as built-in tools), slash commands (user-invocable /commands), and additive prompt sections (injected into the system prompt). Plugin lifecycle: activation via extension_host:reconcile_in_background, defers tool registration to next catalog rebuild. core/call gate allows extension tools to invoke core tools through the same planning/approval pipeline. The extension host runs OS-sandboxed (Seatbelt on macOS, bubblewrap on Linux) with no direct network and restricted filesystem access.

Hooks (hooks/config.rs:25) — Executable subprocess hooks fired on lifecycle events: SessionStart, SessionEnd, MessageSubmit, ToolCallBefore (can deny with exit code 2), ToolCallAfter, ModeChange, OnError, TurnEnd, SubagentSpawn, SubagentComplete, ShellEnv (injects env vars), SessionIdle. Hooks are defined in .codewhale/hooks.toml, require a two-step approval process (review + approve with SHA-256 digest), and symlink paths are rejected.

Instruction files — AGENTS.md (project-scoped per directory), CLAUDE.md (repository instructions), .codewhale/hooks.toml, and configurable instructions sources. The load_skill tool dynamically loads skill prompts.

Skills — Discoverable from local filesystem directories (skills_dir), loaded on demand. The default active native tools include load_skill so models can call skills mid-session.

Headless/SDK — The engine is a library (EngineConfig with all state) embeddable in other processes. CLI codewhale exec runs headless tasks from scripts/CI. npm and Cargo packages wrap the same binary. The codewhale-protocol crate defines shared request types for programmatic use. AppServer (crates/app-server) provides an ACP (Agent Communication Protocol) server for remote agent orchestration.

Workflow tool — The model-visible workflow tool (tools/workflow/) allows the model to define and run multi-step workflows with sub-agents, similar to the human-facing Workflow orchestration tool.

Editor's note. Correction: the TypeScript extension host is experimental and only active behind [features] extension_host (phase 1); it should not be presented as a stable plugin mechanism.

esengine/DeepSeek-Reasonix

answered

Reasonix provides two extension systems. MCP (Model Context Protocol) servers (internal/ext/plugin/plugin.go): configured via [mcp_servers] in reasonix.toml, supports stdio and SSE transports, OAuth, URI handlers, prompt templates, and resource listing. MCP servers are launched and managed by mcplaunch/plugin packages, with per-server sandbox specs (write roots, network, egress). The MCP registry client (internal/ext/mcpregistry/registry.go:33) provides browse/install from the official registry. MCP tool results can include images (toolresult_image.go). Extension packages (internal/ext/extension/): a protocol for runtime-loadable packages that can register new providers, tools, themes, skills, and frontend hooks through a JSON-wire RPC mechanism (packages like internal/ext/extension/protocol, dispatch, providerext). The extensioncontract package defines the contract between host and extension. Skills (internal/ext/skill/): slash-command invocable workflows registered from filesystem or built-in content; resolved by the skill package and routed by slash.go/slash_catalog.go. Hooks (internal/ext/hook/): lifecycle hooks that fire on session events (start, turn begin/end). Instruction/rule files: multi-file loading from REASONIX.md, AGENTS.md, CLAUDE.md, personal *.local.md variants, and ancestor-directory search. @path imports and #<note> quick-add are supported. Plugin packaging (internal/ext/pluginpkg/): package/unpackage MCP servers into redistributable archives with declared metadata. There is no SDK or headless-agent library exposed to external Go consumers — the sdk/ directory at the repo root contains stubs only. The desktop frontend (desktop/) is a separate Electron app that drives the same Controller.

Editor's note. Correction: sdk/go is not a stub; it is a dependency-free Go SDK for writing Extension Protocol v2 sidecars that intercept tool calls, observe events, host provider streams and add UI surfaces.

firecrawl/open-lovable

answered

Extensibility is limited — there are no MCP servers, no plugin system, no custom tool API, no webhook system, and no headless/SDK mode. The primary extension mechanism is the Sandbox provider abstraction: the SandboxProvider abstract class (lib/sandbox/types.ts:35-65) defines a contract (createSandbox, runCommand, writeFile, readFile, etc.) and SandboxFactory (lib/sandbox/factory.ts:6-21) registers new providers by adding a case. This is how E2B and Vercel are swapped. Environment variable configuration (.env.example) lets users change AI providers, sandbox backends, API keys, and internal endpoints without code changes. config/app.config.ts:1-184 centralizes all tunable parameters: model lists, timeouts, UI toggles, file exclusion patterns, etc. Morph Fast Apply (lib/morph-fast-apply.ts) is an optional external integration enabled via MORPH_API_KEY, adding a surgical edit capability. .cursor/rules/ — four Markdown files in .cursor/rules/ directories provide IDE-level guidance for components, effects, and styles but are Cursor-specific and not consumed by the app at runtime. There are no instruction files like AGENTS.md or CLAUDE.md, no hooks system for pre/post-apply actions, no API that external tools can call to drive the agent programmatically. The architecture is a monolith with global variables for all mutable state (declare global var sandboxState, conversationState, existingFiles, activeSandbox across multiple route files).

QwenLM/qwen-code

answered

Extensibility has multiple dimensions. MCP (Model Context Protocol): a full client implementation (packages/core/src/tools/mcp-client.ts, mcp-client-manager.ts) connects to stdio, SSE, and streamable HTTP MCP servers. MCP tools are discovered at runtime and registered into the tool surface as mcp__<server>__<tool> entries (with tool call bridging via tool_search/tool_call).

Plugin system: ExtensionManager (packages/core/src/extension/extensionManager.ts) loads extensions from git repos, npm packages, GitHub releases, and archive URLs. Extensions can contribute MCP servers, skills, subagents, hooks, workflows, context files, settings, channel integrations, and commands. The agent-plugins-v1 subsystem provides manifest-based plugin discovery.

Skills and Hooks: SkillManager (packages/core/src/skills/skill-manager.ts) loads .claude/skills/ markdown-defined skills. The HookSystem (packages/core/src/hooks/hookSystem.ts) orchestrates lifecycle hooks (pre/post tool use, session start/end, stop failure, etc.) with function, command, and HTTP hook runners (lines 60–100).

Headless/SDK use: ACP (Agent Communication Protocol) enables host-controlled agent sessions; SDK packages exist for TypeScript, Python, and Java. Workspace agents (agents/workspace-agents/) support A2A (agent-to-agent) contracts for multi-agent collaboration. Custom tools register via ToolRegistry. Per-project rules files (CLAUDE.md, AGENTS.md) are discovered by rulesDiscovery.ts.

Editor's note. Correction: skills are loaded from .qwen/skills/ and ~/.qwen/skills/ (plus extension and bundled skills), not .claude/skills/.

stackblitz-labs/bolt.diy

answered

The primary extension mechanism is MCP (Model Context Protocol) via MCPService (app/lib/services/mcpService.ts). Users configure MCP servers in the UI (stored in localStorage), supporting three transport types: stdio (local subprocess), sse (Server-Sent Events), and streamable-http. The MCPService validates configs with Zod schemas, creates clients via experimental_createMCPClient from the AI SDK, registers tools into a shared ToolSet, and handles tool call execution with user approval. Tools are exposed to the LLM through the streaming options as tools: mcpService.toolsWithoutExecute (with execute functions stripped), and actual execution happens via processToolInvocations (mcpService.ts:377). New LLM providers can be added by extending BaseProvider in app/lib/modules/llm/providers/ and registering in registry.ts — the LLMManager dynamically discovers them. The system prompt is customizable via PromptLibrary (app/lib/common/prompt-library.ts) which provides a plugin-like registry of prompt templates — users can select between default, original, or optimized prompts. The contextOptimization feature is toggleable per-chat. For rules/instructions files, Bolt does not support AGENTS.md or similar — the system prompt is hardcoded. The app runs as both a web app (Remix/Cloudflare) and an Electron desktop app (electron/ directory). The headless/SDK path is through Cloudflare Workers actions: the api.chat.ts route accepts POST requests with messages, files, and settings as JSON. WebContainer provides the sandboxed execution environment. Settings and provider configurations are stored in cookies (API keys) and localStorage (MCP config, provider settings). No plugin system or custom-tool registration API beyond MCP is provided.

vastsa/PI-Desktop

answered

PI-Desktop has four extension systems.

1. Plugins — Full plugin system with a PluginManifest (packages/plugin-sdk/src/index.ts:48-78+) declaring id, version, renderer entry, agentTools (tools the model can call), skills, fsPolicy, netPolicy, and mcpServers. Plugins are installed via the marketplace or local .piplug files. Host-core manages plugin lifecycle — install, resolve, validate, permission derivation, provider reconciliation — in crates/host-core/src/plugins.rs. Plugin tools are prefixed plugin_<id>_ and go through the same host-core permission path. The examples/plugins/ directory contains sample plugins. Plugin development CLI is in packages/plugin-devkit/.

2. MCP (Model Context Protocol) — User-configured MCP servers (apps/desktop/electron/main/user-mcp.ts) connect to external services via stdio or HTTP. Their tools are exposed as mcp_<serverId>_<tool> names. The runtime supports OAuth-based auth, connection caching per workspace, and timeout configuration. The McpCallRegistry tracks active calls. MCP tool selection can be per-prompt via mcpServerIds/mcpToolNames (mcp-tool-selection.ts:20-48). Plugins can also declare MCP servers in their manifest, which are resolved via the plugin-MCP bridge.

3. Trusted Extensions — Full-featured extension API (packages/agent-runtime/src/extensions/runner.ts) exposing lifecycle hooks (before_agent_start, before_provider_request, after_provider_response, agent_settled, etc.), custom tools, commands, UI requests, diagnostics, and model configuration. The ExtensionAPI object is built per session over a TrustedExtensionBridge (agent-sidecar.ts:82-89). Currently supported events are listed in event-capabilities.ts.

4. Instruction files — Per-project AGENTS.md and CLAUDE.md files (the repo itself is a showcase). The session runtime resolves path-scoped instructions from these files (project-instructions.ts), creates prompt sections from them, and includes them in the system prompt. Project memory is also supported via projectMemoryPrompt (project-memory-prompt.ts).

cloudflare/vibesdk

answered

VibeSDK can be extended and customized through several mechanisms:

Skills (Think agent): The Think agent supports a skill catalog via worker/agents/think/skills.ts. Skills are SKILL.md files in worker/agents/think/skills/ with frontmatter (name, description, compatibility, allowedTools, metadata). Currently four skills: app-file-structure, frontend-design, frontend-design-landing-page, frontend-design-saas. Each skill is loaded at build time via ?raw import, parsed with agents/skills frontmatter parser, and exposed as a SkillSource via fromManifest(). Think automatically injects the skill catalog into the system prompt and registers a skill-loading tool.

Custom tools (Think): Adding a Think tool requires: (1) creating the tool under worker/agents/think/, (2) adding SpaceDO RPC typing to space-workspace-ops.ts, (3) registering it in ThinkAgent.getTools(), and (4) updating the relevant prompt or skill. Existing custom tools include ask-questions-tool.ts, browser-logs-tool.ts, commit-tool.ts, deploy-tool.ts, set-title-tool.ts.

Toolkit system (Agentic): The Agentic/Phasic behaviors use a different tool registration in worker/agents/tools/toolkit/ (e.g., exec-commands.ts, generate-files.ts, read-files.ts, deploy-preview.ts) with a buildTools()/buildDebugTools() pattern in worker/agents/tools/ registered via customTools.ts.

MCP (Model Context Protocol): VibeSDK includes an MCPManager class in worker/agents/tools/mcpManager.ts that uses @modelcontextprotocol/sdk/client with SSEClientTransport to connect to MCP servers. It connects via SSE, lists tools, and integrates them into the agent's toolset. The MCP_SERVERS array in mcpManager.ts is currently empty (just a commented-out cloudflare-docs example), but the full connection infrastructure is in place.

Rules/instruction files: The project has CLAUDE.md (project instructions for Claude Code) and AGENTS.md (detailed guidance for AI agents covering tooling, verification, frontend UI, boundaries, change paths, and constraints). These are checked into the repository.

SDK/headless use: The sdk/ directory is an independent Bun package providing a programmatic client. VibeClient (sdk/src/client.ts) offers HTTP methods, AgenticClient and PhasicClient extend it with preset behavior types, and BuildSession (sdk/src/session.ts) manages a live agent session with WebSocket streaming, file watching, and phase tracking. Applications can install the SDK as a dependency and script agent interactions.

CLI/TUI: bun run cli and bun run tui in package.json point to cli/index.ts and cli/tui.tsx for command-line and terminal-UI interaction modes.

Configuration: Model configs, agent action configs, per-action constraints (allowedModels, enabled), rate limit settings, and user-configurable settings are all adjustable without code changes through environment variables and AI Gateway configuration.

Editor's note. Correction: package.json still has cli and tui scripts, but the cli/ directory they reference does not exist at this commit, so there is no CLI or TUI mode.

← Which models are supported and how are they called?