mcp-marionette
v1.0.1
Published
The MCP Marionette server provides a bridge for AI agents to interact with humans for decision-making, clarification, and session steering. It implements the Model Context Protocol (MCP) to allow agents to pause their execution and wait for human input th
Maintainers
Readme
MCP Marionette
The MCP Marionette server provides a bridge for AI agents to interact with humans for decision-making, clarification, and session steering. It implements the Model Context Protocol (MCP) to allow agents to pause their execution and wait for human input through structured forms.
Purpose
This server enables human-in-the-loop workflows where an agent can:
- Ask clarifying questions with predefined options.
- Request confirmation before performing sensitive actions.
- Allow humans to steer or redirect the session goal.
Why Use This with GitHub Copilot?
Cost Savings: Premium Requests vs. Tokens
GitHub Copilot uses a premium request pricing model, not token-based billing. This has important implications for how you interact with Copilot:
| Plan | Premium Requests/Month | Cost per Extra Request | |------|------------------------|------------------------| | Copilot Free | 50 | $0.04 | | Copilot Pro | 300 | $0.04 | | Copilot Pro+ | 1,500 | $0.04 | | Copilot Business | 300/user | $0.04 | | Copilot Enterprise | 1,000/user | $0.04 |
Key insight: Every chat message, agent mode prompt, and complex interaction consumes premium requests. Once you hit your limit, you pay $0.04 per additional request.
How MCP Marionette Saves You Money
Using this MCP server with GitHub Copilot in VS Code provides significant cost benefits:
1. Structured Responses Reduce Back-and-Forth
Without MCP Marionette:
User: "Should I use React or Vue for this project?"
Copilot: "Great question! Both have pros and cons..."
[Multiple chat turns = Multiple premium requests]With MCP Marionette:
User: "Ask me which framework to use with options React, Vue, Svelte"
Copilot: [Uses askQuestion tool → Single premium request]
Human: [Selects from dropdown: "React - Component-based, large ecosystem"]
Copilot: [Proceeds with React implementation]Result: 1 premium request instead of 3-5 for clarifying questions.
2. Session Steering Prevents Wasted Requests
Without steering:
Copilot: [Works on wrong task for 10 turns]
User: "Wait, that's not what I wanted"
Copilot: "Sorry, let me restart..."
[All previous requests consumed premium quota]With steerSession:
User: "Check if the agent is on track"
Copilot: [Uses steerSession → Human sees current goal]
Human: "Redirect to focus on API layer first"
Copilot: [Pivots immediately]Result: Prevents wasted premium requests on incorrect directions.
3. Agent Mode Efficiency
GitHub Copilot's agent mode is powerful but premium-request intensive. Each autonomous action counts. By adding human checkpoints:
- Agent asks before risky operations
- Human confirms expensive refactors
- Direction changes happen early, not after wasted work
Example: Cost Comparison
Scenario: Implementing a new feature with architecture decisions
| Approach | Premium Requests Used | Cost at $0.04/request | |----------|----------------------|----------------------| | Unstructured chat | 15-25 turns | $0.60 - $1.00 | | With MCP Marionette | 5-8 turns + 2 tool calls | $0.28 - $0.40 | | Savings | ~60-70% fewer requests | $0.30 - $0.60 per task |
For a developer doing 50 complex tasks/month:
- Without MCP: 1,000 premium requests → Exceeds Pro limit, costs $28 extra
- With MCP: 350 premium requests → Well within Pro limit, $0 extra
GitHub Copilot + MCP Setup
GitHub Copilot in VS Code supports MCP servers natively. Here's how to use MCP Marionette:
Step 1: Configure MCP in VS Code
Create or edit .vscode/mcp.json in your project:
{
"servers": {
"marionette": {
"command": "npx",
"args": ["-y", "mcp-marionette"]
}
}
}Or use the full path for local development:
{
"servers": {
"marionette": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/mcp-marionette/dist/index.js"]
}
}
}Step 2: Enable MCP in Copilot
- Open VS Code Settings (
Cmd+,/Ctrl+,) - Search for "copilot mcp"
- Enable
github.copilot.chat.mcp.enabled
Or add to your settings.json:
{
"chat.mcp.discovery.enabled": true
}Step 3: Use in Copilot Chat
- Open Copilot Chat (click the chat icon)
- Select Agent mode from the dropdown
- Click the tools icon (🔧) to see available MCP tools
- Your
askQuestionandsteerSessiontools appear under "MCP"
Step 4: Use Tools in Conversations
You: "I need to implement user authentication. Ask me which auth method to use."
Copilot: [Calls askQuestion tool]
Human sees form: "Which authentication method?"
- OAuth 2.0 - Third-party login (Google, GitHub, etc.)
- Email/Password - Traditional login
- Magic Links - Passwordless email login
[Human selects: "OAuth 2.0 - Third-party login"]
Copilot: "I'll implement OAuth 2.0 authentication..."When to Use MCP Marionette with Copilot
| Use Case | Benefit | |----------|---------| | Architecture decisions | Get human input before committing to an approach | | Ambiguous requirements | Clarify with structured options instead of guessing | | Risky refactors | Ask for confirmation before large changes | | Long-running tasks | Check in periodically with session steering | | Multi-step workflows | Human checkpoints prevent wasted work |
Key Takeaway
MCP tools don't consume extra premium requests - they're part of the agent's tool execution. The human response happens in the VS Code UI, not in the chat. This means:
- 1 chat message + 1 tool call = 1 premium request (not 2)
- Structured answers prevent follow-up questions
- Session steering catches wrong directions early
For Copilot users, this MCP server pays for itself by reducing premium request usage by 50-70% on complex tasks.
Installation
Prerequisites
- Node.js 18+ - Required to run the server
- npm - Comes with Node.js
Installation Methods
Method 1: Clone and Build (Recommended for Development)
git clone <repository-url>
cd mcp-marionette
npm install
npm run buildMethod 2: Global npm Installation
npm install -g mcp-marionette
mcp-marionette # Run directlyMethod 3: Using npx (No Installation Required)
npx -y mcp-marionetteConfiguration
The MCP Marionette server must be configured in your MCP client's configuration file. Below are instructions for different MCP clients.
Configuration File Locations
| Client | Configuration File Location |
|--------|---------------------------|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Claude Desktop (Linux) | ~/.config/Claude/claude_desktop_config.json |
| Claude Code | .claude/settings.json (project) or ~/.claude.json (global) |
| Cursor (Global) | ~/.cursor/mcp.json |
| Cursor (Project) | .cursor/mcp.json |
| Cline (VS Code) | ~/.vscode/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json |
Claude Desktop Configuration
Step 1: Find the Configuration File
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.jsonStep 2: Edit the Configuration
Add the following to your claude_desktop_config.json:
Option A: Direct path (if cloned locally):
{
"mcpServers": {
"marionette": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/mcp-marionette/dist/index.js"
]
}
}
}Option B: Using npx (no local clone needed):
{
"mcpServers": {
"marionette": {
"command": "npx",
"args": ["-y", "mcp-marionette"]
}
}
}Option C: Global installation:
{
"mcpServers": {
"marionette": {
"command": "mcp-marionette"
}
}
}Important Notes:
- Use absolute paths (not relative paths)
- On Windows, use forward slashes
/or double backslashes\\ - Claude Desktop only reads this file at startup
Step 3: Restart Claude Desktop
After saving the configuration file, completely restart Claude Desktop for changes to take effect.
Step 4: Verify Installation
Look for the 🔨 (hammer) icon in Claude Desktop's chat interface. This indicates MCP tools are loaded.
Claude Code Configuration
Option 1: Using CLI Commands
Add the server using Claude Code's CLI:
# For local development
claude mcp add --transport stdio marionette -- node /absolute/path/to/mcp-marionette/dist/index.js
# For global installation
claude mcp add --transport stdio marionette -- mcp-marionette
# For npx
claude mcp add --transport stdio marionette -- npx -y mcp-marionetteOption 2: JSON Configuration
Create or edit .claude/settings.json in your project root:
{
"mcpServers": {
"marionette": {
"command": "node",
"args": [
"/ABSOLUTE/PATH/TO/mcp-marionette/dist/index.js"
]
}
}
}Or for global configuration, edit ~/.claude.json.
Claude Code supports hot-reloading of MCP servers, so you don't need to restart.
Verify in Claude Code
Run /mcp in Claude Code to see loaded MCP servers.
Cursor Configuration
Cursor uses the same mcpServers format as Claude Desktop.
Global (all projects):
~/.cursor/mcp.jsonProject-scoped:
.cursor/mcp.jsonExample:
{
"mcpServers": {
"marionette": {
"command": "npx",
"args": ["-y", "mcp-marionette"]
}
}
}Cline (VS Code) Configuration
File location:
~/.vscode/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.jsonExample:
{
"mcpServers": {
"marionette": {
"command": "npx",
"args": ["-y", "mcp-marionette"]
}
}
}How Agents Discover This Server
Once configured, your MCP client will automatically discover and connect to the server:
Discovery Flow
- Server Spawn: MCP client spawns the server process using the configured
commandandargs - Initialize: Client and server perform capability negotiation via JSON-RPC
- Tool Discovery: Client calls
tools/listto discover available tools - Tool Registration: Client registers
askQuestionandsteerSessionwith the agent
Architecture Diagram
┌─────────────┐ ┌──────────────┐ ┌─────────────────────┐
│ Agent │◄───►│ MCP Client │◄───►│ MCP Marionette │
│ (Claude) │ │ (Desktop/ │ │ Server │
│ │ │ Code/etc) │ │ │
└─────────────┘ └──────────────┘ └─────────────────────┘
│
│ 1. Spawn process
│ 2. Initialize connection
│ 3. Discover tools
│ 4. Register tools
▼
[askQuestion, steerSession]The agent automatically discovers these tools and can invoke them during conversations.
Tool Documentation
askQuestion
Asks a structured question with predefined options and an optional custom response field.
Input Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| sessionId | string | Yes | Unique identifier for the session. |
| question | string | Yes | The question to ask the human. |
| header | string | Yes | Header text for the question form (max 30 characters). |
| options | array | Yes | List of objects with label and description strings. |
| multiple | boolean | No | Allow selecting multiple options. |
| allowCustom | boolean | No | Allow providing a custom text response. Defaults to true. |
Output Format
Returns the selected answer or custom response as text and structured data.
Success Response:
{
"content": [{ "type": "text", "text": "Staging" }],
"structuredContent": {
"sessionId": "deploy-task-456",
"action": "accept",
"answer": "Staging"
}
}Custom Response:
{
"content": [{ "type": "text", "text": "Deploy to canary first" }],
"structuredContent": {
"sessionId": "deploy-task-456",
"action": "accept",
"answer": "Deploy to canary first"
}
}Example Usage
{
"sessionId": "deploy-task-456",
"header": "Deployment Target",
"question": "Which environment should we deploy the latest changes to?",
"options": [
{ "label": "Staging", "description": "Internal testing environment" },
{ "label": "Production", "description": "Live environment for all users" }
],
"multiple": false
}steerSession
Allows humans to provide high-level direction to an active agent session.
Input Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| sessionId | string | Yes | Unique identifier for the session. |
| currentGoal | string | No | The current goal being pursued by the agent. |
Output Format
Returns a structured object containing:
directive: One ofcontinue,pause,modify,redirect,terminate, orcustom.newGoal: The updated goal if the directive ismodifyorredirect.customInstructions: Additional details provided by the human.sessionStatus: The resulting status of the session (e.g.,active,paused,terminated).
Example Response:
{
"content": [{
"type": "text",
"text": "{\"directive\":\"modify\",\"newGoal\":\"Focus on MCP server architecture\",\"customInstructions\":\"Include diagrams\",\"sessionStatus\":\"active\"}"
}],
"structuredContent": {
"sessionId": "research-session-789",
"directive": "modify",
"newGoal": "Focus on MCP server architecture",
"customInstructions": "Include diagrams",
"sessionStatus": "active"
}
}Example Usage
{
"sessionId": "research-session-789",
"currentGoal": "Find all competitors in the MCP ecosystem"
}Quick Start Examples
Example 1: Ask a Simple Question
Agent Request:
{
"sessionId": "planning-session-001",
"header": "Approach",
"question": "Which approach should we take?",
"options": [
{ "label": "Quick", "description": "Fast but basic implementation" },
{ "label": "Thorough", "description": "Comprehensive with tests" }
]
}Human Sees:
- Header: "Approach"
- Question: "Which approach should we take?"
- Options: "Quick - Fast but basic implementation" and "Thorough - Comprehensive with tests"
- Custom text input field
Example 2: Steering a Session
Agent Request:
{
"sessionId": "coding-task-123",
"currentGoal": "Refactor the authentication module"
}Human Sees:
- Session steering form
- Current goal: "Refactor the authentication module"
- Directive options: continue, pause, modify, redirect, terminate, custom
- Fields for new goal and custom instructions
Troubleshooting
Common Issues
Server Not Appearing
Symptoms: The 🔨 icon doesn't show in Claude Desktop.
Solutions:
- Check file paths - Use absolute paths, not relative
- Verify build - Run
npm run buildand ensuredist/index.jsexists - Restart client - Claude Desktop requires a full restart
- Check JSON syntax - Validate your config at https://jsonlint.com/
Permission Denied
Symptoms: EACCES: permission denied
Solution:
# Make the server executable
chmod +x dist/index.jsPATH Issues
Symptoms: command not found or spawn ENOENT
Solutions:
Use the full path to node:
{ "command": "/usr/local/bin/node", "args": ["/path/to/mcp-marionette/dist/index.js"] }Find node path:
which node # macOS/Linux where node # Windows
npx Issues
Symptoms: npx: command not found or slow startups
Solutions:
Clear npx cache:
rm -rf ~/.npm/_npxUse global installation instead:
npm install -g mcp-marionetteUse direct node path instead of npx
"import: command not found"
Symptoms: Server fails with /bin/sh: import: command not found
Cause: Missing shebang in compiled file
Solution: Rebuild with shebang:
npm run build
# Then manually add to top of dist/index.js:
#!/usr/bin/env nodeDebugging Steps
Test the server directly:
node dist/index.jsIf the server starts without errors, it's working correctly.
Check MCP logs:
- Claude Desktop (macOS):
~/Library/Logs/Claude/mcp.log - Cursor: Output panel → MCP server dropdown
- Claude Desktop (macOS):
Verify JSON-RPC communication:
echo '{"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}},"id":1}' | node dist/index.jsCheck for stdout writes: Ensure your server doesn't write to stdout (only stderr). Writing to stdout corrupts JSON-RPC messages.
Client Comparison
| Client | Config File | Hot Reload | Restart Required | Tool Icon |
|--------|-------------|------------|------------------|-----------|
| Claude Desktop | claude_desktop_config.json | No | Yes | 🔨 |
| Claude Code | .claude/settings.json | Yes | No | /mcp command |
| Cursor | ~/.cursor/mcp.json | Yes | No | Settings panel |
| Cline (VS Code) | cline_mcp_settings.json | Yes | No | Sidebar |
Development
Project Structure
mcp-marionette/
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── README.md # This file
├── src/
│ └── index.ts # Server implementation
└── dist/ # Compiled output
├── index.js
├── index.d.ts
└── index.js.mapBuilding
npm run buildTesting
# Test the server directly
node dist/index.js
# Or test with npx
npx -y mcp-marionettePublishing
# Build before publishing
npm run build
# Publish to npm
npm publish
# Or publish as beta
npm publish --tag betaSecurity Considerations
- Local Execution: This server runs locally on your machine
- No External Network: No external network connections are made
- User Approval: All tool executions require explicit user approval in MCP clients
- Data Privacy: No data is sent to external services
- Session Isolation: Each session is identified but not persisted
Environment Variables
The server supports the following environment variables:
| Variable | Description | Default |
|----------|-------------|---------|
| NODE_ENV | Environment mode | production |
Configure in your MCP client config:
{
"mcpServers": {
"marionette": {
"command": "node",
"args": ["/path/to/dist/index.js"],
"env": {
"NODE_ENV": "development"
}
}
}
}License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions:
- GitHub Issues: github.com/yourusername/mcp-marionette/issues
- MCP Documentation: modelcontextprotocol.io
