MCP profile management for GitHub Copilot CLI. Controls which MCP servers are active per task domain, reducing token usage by ~50% per turn.
Each MCP server registers 5β35 tools into the system prompt. Those tool schemas (name + description + JSON parameters) cost ~150β300 tokens each and are re-sent on every turn. With 10+ MCP servers loaded, the system prompt alone can consume 30,000+ tokens per turn.
Constellation lets you define profiles β named configurations that enable only the MCP servers you need for the current task. Switching from a full loadout to a minimal profile removes tens of thousands of tokens per turn, roughly halving your per-turn input cost.
A secondary benefit: smaller system prompts delay context compaction, reducing summarization overhead across longer sessions.
If you use multiple MCP servers with Copilot CLI, you're paying a hidden tax on every single turn. Here's what we measured:
A real-world profile switch removed ~109 tools across 6 MCP servers. Each tool definition is ~150β300 tokens of schema. That's ~16,000β33,000 tokens removed from the system prompt β and the system prompt is re-sent on every turn.
Over a 30-turn session, that's 480,000β990,000 tokens saved on input alone.
Tool schemas are typically the heaviest component of the system prompt β often 50%+ of your per-turn input. Removing unused tools via a profile switch roughly halves your per-turn cost. With a full-to-minimal switch, the reduction can be 2x or better.
This makes profile switching the single most impactful token optimization available in Copilot CLI today.
A smaller system prompt means more context window is available for your actual conversation. This means:
- Compaction triggers less frequently β the system doesn't need to summarize your conversation history as often
- Fewer summarization calls = fewer tokens spent on overhead
- This compounds β the longer your session runs, the more you save
When the LLM sees 100+ tool definitions, it has to evaluate all of them on every turn. Reducing to just the 5β10 tools you actually need means:
- Faster tool selection β less noise, more signal
- Fewer hallucinated tool calls β the model won't try to use tools from an unrelated domain
- More context for your work β tokens not spent on tool schemas are available for code, conversation, and reasoning
| Tool | What it does |
|---|---|
profile_switch |
Switch to a named profile β enables its MCPs, disables everything else |
profile_list |
List all profiles with descriptions |
profile_current |
Show active profile, detect drift from Γ la carte changes |
profile_create |
Create a new profile |
profile_update |
Delta update β add/remove MCPs, change description/hint/working_dir |
profile_delete |
Delete a profile |
svr_load |
Load a single MCP server (Γ la carte, additive) |
svr_unload |
Unload a single MCP server (Γ la carte, subtractive) |
svr_register |
Register a new MCP in the profile registry + capability manifest |
svr_deregister |
Remove an MCP from all files and profiles |
svr_status |
Show which MCPs are loaded, unloaded, and registered |
When you load MCPs Γ la carte (e.g., svr_load kusto then svr_load azure-devops), Constellation automatically detects if your current MCP state matches a named profile and updates accordingly. No manual profile_switch needed.
- GitHub Copilot CLI β₯ 1.0.48
- Windows (Mac/Linux support planned)
- No additional dependencies β the extension SDK (
@github/copilot-sdk/extension) is bundled with the CLI runtime
git clone https://github.com/lowdrag84/constellation.git
cd constellation
.\setup.ps1The script will:
- Check your CLI version
- Copy
extension.mjsto~/.copilot/extensions/constellation/ - Scan your
mcp-config.jsonfor existing MCP servers - Ask if you want to register them all (creates
profiles.yaml+mcp-manifest.yaml)
Use .\setup.ps1 -SkipScan to skip the MCP scan and start with just a minimal lean profile.
Use .\setup.ps1 -Force to overwrite an existing extension installation.
# 1. Copy the extension
mkdir ~\.copilot\extensions\constellation -Force
copy extension.mjs ~\.copilot\extensions\constellation\extension.mjs
# 2. Copy example configs (if you don't have them yet)
copy profiles.yaml.example ~\.copilot\profiles.yaml
copy mcp-manifest.yaml.example ~\.copilot\mcp-manifest.yamlIn a Copilot CLI session, ask:
"Clone
lowdrag84/constellationand run the setup script"
Or for fully hands-off setup:
"Install the Constellation extension from
lowdrag84/constellation. Scan my MCP config and register all servers."
The LLM can run setup.ps1 or perform the manual steps directly.
If you install only extension.mjs without creating profiles.yaml, Constellation will auto-bootstrap on the next session start:
- Creates
profiles.yamlwith a defaultleanprofile - Scans
mcp-config.jsonand registers all found servers - Creates
mcp-manifest.yamlwith placeholder entries
> profile_create { name: "data", description: "Data engineering", mcp_servers: ["kusto", "azure-devops"] }
β
Created profile: `data`
> profile_switch { profile: "data" }
π Profile shift β `data`
MCPs enabled: kusto, azure-devops
MCPs disabled: teams, m365-user, ...
> svr_load { server: "teams" }
β
Loaded: teams
> profile_current
π§ Base Profile: `data` (modified)
Γ la carte added: teams
> svr_register { server: "my-tool", description: "My custom tool", capabilities: ["Do things"], use_when: "User asks about my tool" }
β
Registered server: my-tool
| File | Location | Purpose |
|---|---|---|
extension.mjs |
~/.copilot/extensions/constellation/ |
The extension code (11 tools + bootstrap hook) |
profiles.yaml |
~/.copilot/ |
Profile definitions + MCP server registry |
mcp-manifest.yaml |
~/.copilot/ |
MCP capability catalog for autonomous loading |
settings.json |
~/.copilot/ |
Runtime state (read/written by extension, not user-edited) |
mcp-config.json |
~/.copilot/ |
CLI MCP server configurations (read-only by extension) |
The extension uses a hand-rolled YAML parser optimized for the specific structure of profiles.yaml and mcp-manifest.yaml. If you edit these files manually, follow these rules:
- All string values must be double-quoted:
description: "my value" - Backslashes in paths are JSON-escaped:
working_dir: "C:\\Users\\me\\project" - Empty arrays use inline syntax:
mcp_servers: [] - Null values use bare keyword:
working_dir: null - Profile names are 2-space indented under
profiles: - List items use
-syntax under their parent key - Comments (
#) and blank lines are preserved on read but regenerated on write
See docs/yaml-format.md for complete format documentation.
Constellation is a Copilot CLI extension β a Node.js ES module that communicates with the CLI via JSON-RPC over stdio.
The key SDK capability is session.rpc.mcp.enable/disable, which toggles MCP servers at runtime without restarting the session. Profile switching simply computes which servers to enable/disable and calls these methods.
Note: The GitHub Copilot SDK is currently in Public Preview (
1.0.0-beta.4). Thesession.rpc.mcp.enable/disableAPI is a low-level RPC method that exists in the public SDK but does not yet have dedicated documentation β it may change between beta versions.
The extension has zero external dependencies. The @github/copilot-sdk/extension import is automatically resolved by the CLI runtime β no npm install needed.
profiles.yaml and mcp-manifest.yaml define your profile configurations and are safe to sync across machines (e.g., via a dotfiles repo). settings.json contains runtime state (disabledMcpServers, activeProfile) and should not be synced β it's machine-specific.
| Platform | Status |
|---|---|
| Windows (PowerShell) | β Supported |
| macOS | π Planned |
| Linux | π Planned |
The extension itself (extension.mjs) is cross-platform. Only the setup script (setup.ps1) is Windows-specific. Mac/Linux users can follow the manual installation steps.
Contributions welcome! Please open an issue first to discuss proposed changes.
Built with GitHub Copilot CLI and the Copilot Extension SDK.