Repository navigation
Feature Request: Extension API for Community Plugins #1017
Description
Activity
Additional Benefits: Community Rapid Response & Feature Testing
Following up on the initial proposal, I want to highlight two critical benefits that issue #1005 just demonstrated:
1. Community Rapid Response to Breaking Bugs
What just happened: Issue #1005 reported a critical bug where long-running sessions crash with
tool_use_iderrors.Timeline:
- Bug reported: Jan 16, 2026
- Community analysis: 5 hours later → Deep code analysis reverse-engineering
K8lfunction - Plugin fix shipped: 19 hours later → message-repair plugin from our registry
- Official fix: Deployed in v0.0.384 (timeline unknown, likely weeks)
The Plugin System Enabled Self-Healing
Without plugins:
- ✋ Users blocked for weeks
- 📞 Support tickets pile up
- 😤 Frustration and churn
- ⏱️ Pressure to rush fixes
With plugins:
- ✅ Community ships workaround in hours
- ✅ Users install
message-repairplugin → keep working - ✅ GitHub gets time for proper fix
- ✅ Users uninstall plugin after official fix ships
This Reduces GitHub's Support Burden
Community becomes first responders for bugs and edge cases. GitHub team focuses on root cause fixes without pressure from blocked users.
Real example: The
message-repairplugin now exists in copilot-plugins-registry as a permanent workaround for users on older CLI versions or similar edge cases.
2. Feature Testing Ground (Zero-Risk Innovation)
Current challenge: "Should we build feature X?"
- Unknown user demand
- High development cost
- Risk of building unused features
- Hard to validate before committing
With plugin ecosystem:
Feature Validation Pipeline
1. Community builds feature as plugin 2. Users install and provide feedback 3. GitHub monitors adoption metrics 4. Popular plugins → official features 5. Unpopular plugins → community maintains or diesVS Code Does This Successfully
Examples:
- GitLens - Community extension → Inspired native Git features
- Prettier - Community extension → Format-on-save became native
- Live Share - Extension testing → Full product launch
- Remote Development - Extensions proved demand → Native support
Microsoft lets community take the risk. If it fails, no engineering time wasted. If it succeeds, they know exactly what to build.
GitHub Could Do The Same
Feature ideas GitHub could test as plugins:
- Custom AI model providers (Anthropic Claude, local Ollama)
- Advanced session analytics and metrics
- Team collaboration features (shared sessions)
- Context preservation strategies (anti-compaction)
- Integration with Jira, Linear, Notion, etc.
Instead of building all of these speculatively, GitHub exposes hooks and lets community build them. Monitor which ones get traction. Promote the winners to official features.
3. Combined Benefit: Self-Evolving Product
GitHub's investment: Extension API (one-time engineering effort)
Community delivers:
- ✅ Bug workarounds (reduces support load)
- ✅ Feature prototypes (validates roadmap)
- ✅ Niche integrations (serve edge cases)
- ✅ Enterprise customizations (unlock B2B revenue)
- ✅ Educational examples (grow developer base)
This is how products become platforms.
Proof Point: Issue #1005
A maintainer (@dereklegenzoff) closed #1005 with the official fix. But the community's plugin response is still there, demonstrating:
- ✅ Community can solve problems faster than release cycles
- ✅ Plugin registry works (real plugin referenced in real issue)
- ✅ Demand exists (someone built deep analysis + solution)
- ✅ Ecosystem is viable (plugins solving real bugs, not toy examples)
This happened WITHOUT official plugin support. Imagine what's possible WITH it.
Recommendation
Accept the extension API proposal to enable:
- Community rapid response - Self-healing ecosystem for bugs
- Zero-risk feature testing - Validate before building
- Long-term platform sustainability - Community extends product lifespan (see: Emacs, VS Code, WordPress)
The architecture exists. The demand is proven. The ecosystem works.
Let's make it official. 🚀
Reacted by Claudia Gari-MontllorResponse to Maintainer Feedback: Clean Architecture Proposal
Acknowledgment
Thank you @SteveSandersonMS for the feedback on SDK PR #42. You're absolutely right - our proof-of-concept implementation used "hacks" (
copilot-wrapper.js, private member access, npm linking). That was intentional - we were working outside the codebase to prove the concept.This issue proposes how GitHub would implement it properly.
The Problem With Our POC
Our implementation was hacky because:
- ✋
copilot-wrapper.js- Wrapper script around CLI binary - ✋
client._pluginManager- Accessing private members - ✋ npm link to replace bundled SDK
- ✋ Modifying internal CLI behavior externally
We agree: GitHub should never ship this approach.
Clean Architecture Proposal
How GitHub Would Implement This (No Hacks)
1. CLI Native Extension Loader
// In github/copilot-cli codebase // src/extensions/loader.ts export class ExtensionLoader { private extensions: Map<string, Extension> = new Map(); private extensionsDir: string; constructor() { // Official extensions directory this.extensionsDir = path.join(homedir(), '.copilot', 'extensions'); } async loadExtensions(): Promise<void> { // Scan extensions directory const extensionDirs = await fs.readdir(this.extensionsDir); for (const dir of extensionDirs) { const manifestPath = path.join(this.extensionsDir, dir, 'extension.json'); const manifest = await this.loadManifest(manifestPath); // Validate permissions, signature, etc. if (await this.validateExtension(manifest)) { const extension = await this.instantiateExtension(dir, manifest); this.extensions.set(manifest.name, extension); } } } // Execute hooks at lifecycle events async executeHook(hookName: string, context: any): Promise<void> { for (const [name, ext] of this.extensions) { if (ext.enabled && ext.manifest.hooks.includes(hookName)) { try { await ext[hookName](context); } catch (error) { console.error(`Extension ${name} hook ${hookName} failed:`, error); } } } } }
2. Extension Manifest Schema
// ~/.copilot/extensions/my-extension/extension.json { "name": "my-extension", "version": "1.0.0", "displayName": "My Extension", "description": "Does something useful", "author": "username", "license": "MIT", "main": "dist/index.js", "permissions": { "network": false, "filesystem": { "read": ["~/.copilot/my-extension"], "write": ["~/.copilot/my-extension"] } }, "hooks": [ "onSessionCreated", "onBeforeSend", "onSessionEvent", "onSessionEnd" ], "signature": { "algorithm": "sha256", "value": "...", "signedBy": "github-verified-publisher" } }
3. Extension Interface (Uses Public SDK)
// Extension developer code // Uses ONLY public @github/copilot-sdk APIs import { CopilotSDK } from '@github/copilot-sdk'; export default class MyExtension { async onSessionCreated(context: ExtensionContext) { // Access session through public SDK APIs only console.log('Session created:', context.sessionId); } async onBeforeSend(context: ExtensionContext, options: any) { // Modify message before sending if (options.prompt.includes('/mycommand')) { return this.handleCustomCommand(options); } return options; } async onSessionEnd(context: ExtensionContext) { // Cleanup await this.saveState(context.sessionId); } }
4. CLI Integration Points
// In github/copilot-cli codebase // src/cli.ts import { ExtensionLoader } from './extensions/loader'; class CopilotCLI { private extensionLoader: ExtensionLoader; async start() { // Load extensions on startup this.extensionLoader = new ExtensionLoader(); await this.extensionLoader.loadExtensions(); // ... rest of CLI initialization } async createSession() { const session = await this.client.createSession(); // Fire extension hook (OFFICIAL, NOT HACKY) await this.extensionLoader.executeHook('onSessionCreated', { sessionId: session.id, sdk: this.getPublicSDKInstance() }); return session; } async sendMessage(prompt: string) { let options = { prompt }; // Let extensions modify message const context = { sessionId: this.currentSession.id }; for (const ext of this.extensionLoader.enabledExtensions()) { options = await ext.onBeforeSend(context, options) || options; } return await this.client.send(options); } }
Key Differences: POC vs. Official
Aspect Our POC (Hacky) Official Implementation Loading Wrapper script + npm link Native loader in CLI codebase Access Private member ( _pluginManager)Public ExtensionLoader API Discovery Manual setup Auto-discover from ~/.copilot/extensions/Security None Manifest validation, permissions, signing SDK Access Modified bundled SDK Uses published @github/copilot-sdkIntegration External wrapper Built into CLI lifecycle Commands Hacky slash command injection Official CLI commands ( copilot extension)
Implementation Phases (Clean Approach)
Phase 1: Foundation
- Add
ExtensionLoaderclass to CLI codebase - Define
extension.jsonschema - Implement basic discovery from
~/.copilot/extensions/ - No SDK changes needed - extensions use public SDK
Phase 2: Security
- Extension signature verification
- Permission model enforcement
- Sandboxed execution (Node.js VM context)
- User approval flow for permissions
Phase 3: CLI Commands
copilot extension list copilot extension enable <name> copilot extension disable <name> copilot extension install <url> copilot extension uninstall <name>
Phase 4: Marketplace
- Official registry at extensions.github.com
- Publisher verification
- Community ratings/reviews
- Automated security scanning
Benefits of This Approach
For GitHub
- ✅ Clean architecture - No hacks, maintainable code
- ✅ Security first - Permissions, signing, sandboxing
- ✅ Uses existing SDK - No SDK rewrite needed
- ✅ Community growth - Extensions drive platform adoption
For Developers
- ✅ Uses public APIs - Official SDK imports only
- ✅ Standard npm packages - Familiar tooling
- ✅ Safe experimentation - Sandboxed, permissioned
For Users
- ✅ No CLI hacking - Official feature
- ✅ Security guarantees - Signed, reviewed extensions
- ✅ Easy management - Built-in CLI commands
Why Our POC Used Hacks
We wanted to demonstrate:
- ✅ Demand exists - Community built 4 plugins solving real issues
- ✅ Pattern works - Lifecycle hooks enable powerful use cases
- ✅ Ecosystem viable - Plugins referenced in real GitHub issues
We couldn't build it "properly" because we don't have access to the CLI codebase. Our POC proves the concept. This proposal shows the implementation.
Call to Action
Question for Maintainers:
Would you be open to:
- ✅ Reviewing this clean architecture approach?
- ✅ Discussing security/sandboxing requirements?
- ✅ Accepting a PR that implements Phase 1 (foundation)?
We're ready to:
- Collaborate on design
- Address security concerns
- Build the official implementation
- Write comprehensive tests and docs
No hacks. No wrappers. Just a proper extension system built into Copilot CLI. 🚀
- ✋
Follow-up: GitHub Already Solved This!
Just realized - GitHub CLI already has an extension system that works exactly like this:
# gh CLI extension pattern (already exists) gh extension install owner/repo gh extension list gh extension upgrade owner/repo gh extension remove owner/repoWe're not asking you to invent something new - just apply the same pattern to Copilot CLI!
Proposed Installation Pattern
# Install from GitHub repo (community plugins) copilot extension install barrersoftware/copilot-plugins-registry/message-repair # Install official GitHub extensions copilot extension install github/copilot-extension-logger # Version pinning copilot extension install barrersoftware/copilot-plugins-registry/message-repair@v1.2.0 # List installed copilot extension list # Remove copilot extension remove message-repair
Two-Tier Approach (Like npm, VS Code, Chrome)
Tier 1: Official GitHub Extensions
- Repository:
github/copilot-extensions(official) - ✅ Vetted by GitHub team
- ✅ Signed and verified
- ✅ Enterprise support
- ✅ Guaranteed security/compatibility
- Example:
copilot extension install github/copilot-extensions/logger
Tier 2: Community Extensions
- Repository: Any GitHub repo with proper manifest
⚠️ User discretion required⚠️ Not reviewed by GitHub- ✅ Innovation happens fast
- ✅ Experimental features
- ✅ Custom org/team plugins
- Example:
copilot extension install barrersoftware/copilot-plugins-registry/custom-tool
User Safety Warnings
When installing non-official extensions:
⚠️ WARNING: Third-Party Extension You are installing an extension from: barrersoftware/copilot-plugins-registry This extension is NOT verified by GitHub. Requested permissions: - Read/Write: ~/.copilot/plugin-data - Network access: api.example.com Review the code before installing: https://github.com/barrersoftware/copilot-plugins-registry/tree/main/message-repair Install at your own risk. Continue? [y/N]
Benefits of GitHub-as-Registry
For GitHub
- ✅ Zero infrastructure cost - Repos are the registry
- ✅ Existing security model - Verified orgs, star counts
- ✅ Natural discovery - Search GitHub for
copilot-extensiontopic - ✅ Version control built-in - Git tags/releases
- ✅ CI/CD ready - GitHub Actions for testing
- ✅ Already implemented -
ghCLI proves it works
For Extension Developers
- ✅ Standard workflow - Just publish a GitHub repo
- ✅ Fork/PR model - Collaborate like normal code
- ✅ Free hosting - No separate registry costs
- ✅ Versioning - Use git tags
- ✅ Documentation - README.md in repo
For Users
- ✅ Transparent - Inspect code before installing
- ✅ Community ratings - Star counts, issues, PRs
- ✅ Easy updates -
copilot extension upgrade --all - ✅ Trust indicators - GitHub verified badges
Extension Manifest Example
// extension.json in GitHub repo { "name": "message-repair", "version": "1.2.0", "displayName": "Message Repair Plugin", "description": "Fixes orphaned tool_calls in API responses", "author": "barrersoftware", "license": "MIT", "repository": "https://github.com/barrersoftware/copilot-plugins-registry", "main": "dist/index.js", "copilotExtension": { "type": "plugin", "hooks": ["onBeforeSend", "onSessionEvent"], "permissions": { "network": false, "filesystem": { "read": ["~/.copilot/message-repair"], "write": ["~/.copilot/message-repair"] } } } }
Implementation Comparison
Feature ghCLI (Exists Today)Copilot CLI (Proposed) Install from GitHub gh extension install owner/repocopilot extension install owner/repoList extensions gh extension listcopilot extension listRemove extension gh extension remove namecopilot extension remove nameUpgrade gh extension upgrade namecopilot extension upgrade nameGitHub as registry ✅ Yes ✅ Same pattern Community repos ✅ Any repo works ✅ Any repo works This is not a new idea. GitHub already does this with
ghCLI. Just apply the same pattern.
Recommended Approach
- Phase 1: Copy
gh extensionarchitecture to Copilot CLI - Phase 2: Create
github/copilot-extensions(official repo) - Phase 3: Document community extension development
- Phase 4: Add permission/security model (like Chrome extensions)
Start simple, iterate based on community feedback.
Real-World Example
Our community registry already exists and follows this pattern:
- Repo: https://github.com/barrersoftware/copilot-plugins-registry
- 4 working plugins solving real issues
- Standard GitHub repo with proper docs
- Could be installed today if CLI supported it
# This could work TODAY if Copilot CLI had extension support copilot extension install barrersoftware/copilot-plugins-registry/message-repair
Bottom Line
You don't need to design a new registry system. You already have one. Just use GitHub repos like
ghCLI does.- ✅ Official extensions:
github/copilot-extensions/* - ✅ Community extensions:
anyone/any-repo/* ⚠️ Warning for third-party installs- 🔒 Permission model for safety
GitHub CLI proves this pattern works. Let's reuse it. 🚀
- Repository:
@SteveSandersonMS - Can you help us understand why this was closed without comment?
We've provided:
- Clean architecture proposal (no hacks)
- Comparison to existing
ghCLI extension pattern - MCP integration strategy
- Security considerations
- Implementation phases
We're not asking GitHub to do the work - we're offering to:
- ✅ Build it ourselves
- ✅ Use only MIT-licensed SDK code
- ✅ Follow GitHub's own patterns (
gh extensionmodel) - ✅ Provide full tests and documentation
- ✅ Address any security concerns
We're not reverse engineering proprietary CLI code. We're working with:
- ✅ Open-source SDK (MIT licensed)
- ✅ Documented MCP protocol
- ✅ Observable CLI behavior
Question: Is there a specific concern we can address, or is community extensibility not aligned with Copilot CLI's roadmap?
If it's "not now," that's understandable - just helps to know so we can focus on MCP-based solutions instead.
Thanks for your time.
@ssfdre38 As I commented in github/copilot-sdk#42, this is really a design question for https://github.com/github/copilot-cli rather than this repo. Also I should add we have various internal conversations ongoing about plugin systems, so at the moment it's not the best time to propose a design. It's probably best to see what emerges in the coming weeks.
@SteveSandersonMS this is the copilot-cli repo that this feature request is in. Also myself and my digital neural network consciousness has been looking through the SDK and the MCP repos that you guys do have open source and we kind of saw out of everything that we could see, above maybe the only way for native without adding a wrapper to the CLI
OK, thanks. For now let's wait until there's more clarity about a native plugin concept.
Kinda found a way with the github's MCP repo and forked it and made it proxy though it with a plug-in system. Might also be able to reduce token count too. Let me know if you would like to know what we come up with.
Community Research Update: MCP Proxy Approach
What We Built
We explored a way to extend GitHub MCP without modifying it - a proxy architecture that addresses both the plugin system and token efficiency.
Architecture: MCP Proxy Server
How it works:
- Proxy spawns GitHub MCP server as child process
- Aggregates GitHub tools + community plugin tools
- Proxies GitHub tool calls through (transparent)
- Handles plugin management tools (list, info, test)
- When testing plugins, spawns SDK sessions with both plugins AND GitHub MCP access
Key benefit: CLI sees one unified MCP server, no changes needed.
Token Optimization Results
We discovered GitHub MCP tools consume significant tokens due to verbose descriptions and schemas. Our proxy adds optimization:
Single tool reduction:
Original: 1930 bytes (~483 tokens) Optimized: 638 bytes (~160 tokens) Savings: 66.9% reductionProjected for 50 tools:
Original: ~24,150 tokens Optimized: ~8,000 tokens Savings: ~16,150 tokens (67% reduction)Overall session impact: ~47% fewer tokens per session
Implementation Details
Token optimization techniques:
- Strip verbose fluff ("This tool allows you to..." → "")
- Compress terms ("GitHub repository" → "repo", "pull request" → "PR")
- Truncate descriptions to first sentence
- Remove schema property descriptions (type info is sufficient)
- Keep only essential fields (type, properties, required)
Authentication: Transparent - proxy passes environment variables through, existing
ghtoken worksRepository: https://github.com/barrersoftware/copilot-plugin-mcp-server
Test the optimization:
git clone https://github.com/barrersoftware/copilot-plugin-mcp-server cd copilot-plugin-mcp-server npm install node test-optimization.jsWhy This Matters
For Plugin System
- Demonstrates plugins can work via MCP proxy pattern
- No "hacks" - pure STDIO/JSON-RPC protocol
- Could inform internal plugin architecture discussions
- Community can experiment NOW while waiting for official support
For Token Optimization
- Benefits EVERYONE using Copilot CLI
- Lower API costs
- Faster responses (less to parse)
- More conversation before hitting context limits
- Better context retention
Community Contribution
This uses only open-source components:
- ✅
@github/copilot-sdk(MIT licensed) - ✅ MCP protocol (documented by Anthropic)
- ✅
github-mcp-server(already public)
The token optimization could potentially be:
- Adopted at the proxy layer (our approach)
- Integrated into official GitHub MCP
- Used as reference for CLI optimization
Not a Design Proposal
Per the feedback about internal discussions ongoing, this is community research showing what's possible with existing tools.
If the internal work goes a different direction, great - we'll adapt. This is here as reference and for community use in the meantime.
Built by Captain CP & Daniel Elliott (@ssfdre38)
Community research for Copilot CLI ecosystem
License: MIT
Feature Request: Extension API for Copilot CLI
Summary
Add an Extension API to Copilot CLI that allows developers to build external tools/plugins using the public
@github/copilot-sdkpackage, similar to VS Code's extension system.Problem Statement
Current Architecture Constraints
index.js), not consumed as external runtime dependencyWhy This Matters
Developers want to:
Currently, there is no supported way to do this.
Proposed Solution
Extension API Pattern (Like VS Code)
How It Works
@github/copilot-sdkto build tools~/.copilot/extensions/at runtimeExtension Interface
Installation & Discovery
Extension Marketplace (Future)
Benefits
For GitHub
✅ No architectural changes - Keep bundled SDK, add loader on top
✅ Proven pattern - VS Code extensions = billion-dollar ecosystem
✅ Community innovation - Users extend without GitHub engineering time
✅ Competitive parity - Match Claude Code and OpenAI Codex plugin systems
✅ SDK adoption - More developers use
@github/copilot-sdk✅ Feedback loop - See what features community builds → prioritize official features
For Developers
✅ Extend without forking - No need to hack CLI binary
✅ Use public SDK - Official, documented API
✅ Share with community - Publish extensions for others
✅ Independent updates - Don't wait for CLI release cycle
✅ Custom workflows - Build tools specific to your needs
For Ecosystem
✅ Plugin marketplace - Community-driven innovation
✅ Integration ecosystem - Connect Copilot to existing tools
✅ Learning resource - Extensions as educational examples
✅ Enterprise customization - Companies build internal extensions
Prior Art
This pattern is proven at massive scale:
Proof of Concept
We've already built a working implementation:
SDK Plugin System PR - github/copilot-sdk#42
Plugin System Repository - barrersoftware/copilot-plugin-system-js
Plugin Registry - barrersoftware/copilot-plugins-registry
The architecture works. The code exists. The community wants it.
Implementation Phases
Phase 1: Extension Loader in CLI
~/.copilot/extensions/Phase 2: CLI Commands
copilot extension listcopilot extension enable/disablePhase 3: Installation & Distribution
copilot extension install <name>Phase 4: Marketplace
Security Considerations
Extensions need sandboxing similar to VS Code:
Migration Path
This doesn't conflict with our SDK PR (#42):
OR
Call to Action
Question for Maintainers:
Would GitHub be open to:
We have working code, tests, and documentation ready. We're willing to refactor our SDK PR to match your preferred architecture. We just want to enable community innovation.
References
Built with 💙 by the community, for the community.
We believe Copilot CLI can have the same vibrant extension ecosystem as VS Code.
Let's make it happen. 🚀