MCP server testing and orchestration tool
Project description
๐ต Orchestra
Production-Ready MCP Server Testing and Orchestration Tool
Orchestra is a powerful CLI tool for testing MCP (Model Context Protocol) servers with declarative YAML test collections. Discover server capabilities, write comprehensive tests, and validate your MCP implementations with ease.
โจ Key Features
- ๐ฏ Interactive Builder โ
newcommand walks you through creating collections (no YAML knowledge required!) - ๐ Server Discovery โ
inspectcommand reveals all available tools and their schemas - ๐ Declarative YAML โ Define test collections in easy-to-read YAML files
- ๐ Multiple Transports โ STDIO (local), HTTP (remote), and SSE support
- ๐ Authentication โ Built-in support for Bearer, API Key, and Basic auth
- โ Powerful Assertions โ JSONPath queries, error detection, and content validation
- โก Rate Limit Handling โ Configurable delays between steps
- ๐ Detailed Reports โ JSON reports with run IDs, timestamps, and step-by-step results
- ๐ CI/CD Ready โ Exit codes for pass/fail, quiet mode for automation
- ๐ Secure โ Environment variable support for secrets and API keys
๐ฆ Installation
# From source
pip install -e .
# Or with uv
uv pip install -e .
๐ Quick Start
0. Create Your First Collection (Interactive!)
New to Orchestra? Use the interactive builder:
orchestra new schemas/my_test.yaml
The wizard will guide you through:
- Choosing your transport type (local/remote)
- Configuring your server
- Setting up authentication (if needed)
- Adding example test steps
Example session:
๐ต Orchestra Collection Builder
What would you like to name this collection? My MCP Test
โ Collection name: My MCP Test
How does your MCP server run?
1. Local (STDIO) - Runs as a subprocess
2. Remote (HTTP) - Cloud-hosted server
3. SSE - Server-Sent Events
Choose transport type [2]: 2
Enter server URL: https://mcp.deepwiki.com/mcp
โ URL: https://mcp.deepwiki.com/mcp
โ
Collection saved to schemas/my_test.yaml
Next steps:
1. Run orchestra inspect schemas/my_test.yaml to discover tools
2. Edit schemas/my_test.yaml to add your test steps
3. Run orchestra run schemas/my_test.yaml to execute tests
1. Discover Server Capabilities
Use the inspect command to discover what tools a server offers:
orchestra inspect schemas/my_server.yaml
Example output:
๐ก Connecting to MCP server...
โ
Connected to DeepWiki v2.14.3
๐ Discovering tools...
Found 3 tool(s):
1. read_wiki_structure
Get a list of documentation topics for a GitHub repository.
Parameters:
* repoName (string)
GitHub repository in owner/repo format (e.g. "facebook/react")
Example YAML:
- id: call_read_wiki_structure
type: tool_call
tool: "read_wiki_structure"
input:
repoName: "facebook/react"
save: "$"
๐ก Pro tip: The generated YAML from orchestra new works perfectly with inspect!
For inspection, you only need server config:
# schemas/my_server.yaml
version: 1
name: "My MCP Server"
server:
transport: "http"
url: "https://api.example.com/mcp"
2. Create a Test Collection (Manual Method)
If you prefer writing YAML directly:
# schemas/my_test.yaml
version: 1
name: "My MCP Test"
server:
transport: "stdio"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-memory"]
steps:
- id: create_entity
type: tool_call
tool: "create_entities"
input:
entities:
- name: "TestUser"
entityType: "person"
observations: ["Loves testing"]
save: "$"
delay_ms: 1000 # Wait 1 second before next step
- id: verify_no_error
type: assert
from: "create_entity"
check:
op: "no_error"
- id: verify_created
type: assert
from: "create_entity"
check:
op: "jsonpath_exists"
path: "$.content[0].text"
3. Run the Collection
# Standard run
orchestra run schemas/my_test.yaml
# Show full JSON responses (great for debugging)
orchestra run schemas/my_test.yaml --show-responses
# Quiet mode (errors only)
orchestra run schemas/my_test.yaml --quiet
4. View the Results
๐ Loading collection: schemas/my_test.yaml
โ
Valid collection: My MCP Test
============================================================
Running: My MCP Test
Server: stdio
Steps: 3
============================================================
๐ก Connecting to MCP server...
โ
Connected to memory-server v0.6.3
โถ Step: create_entity (tool_call)
Tool: create_entities
Input: {"entities": [{"name": "TestUser", ...}]}...
โ
Success
โฑ๏ธ Waiting 1000ms...
โถ Step: verify_no_error (assert)
Asserting on: create_entity
Check: no_error at $
โ
Passed
โถ Step: verify_created (assert)
Asserting on: create_entity
Check: jsonpath_exists at $.content[0].text
โ
Passed
๐ Disconnecting...
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Run Report: My MCP Test
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Run ID: abc123-def456
Status: โ
PASSED
Duration: 1234ms
Started: 2026-02-14T12:00:00Z
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Steps: 3 passed, 0 failed, 0 errors, 0 skipped
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
tool_call - 150ms
โ
assert - 2ms
โ
assert - 5ms
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Report saved: reports/abc123-def456.json
๐ CLI Reference
orchestra new
Create a new test collection with an interactive wizard (perfect for beginners!).
orchestra new [output_file]
# Examples:
orchestra new schemas/my_test.yaml
orchestra new # Defaults to schemas/my_collection.yaml
What it does:
- Guides you through choosing transport type
- Helps configure server connection
- Sets up authentication if needed
- Generates valid YAML automatically
- Provides next steps after creation
Time to first test: ~3 minutes (75% faster than manual YAML)
See Interactive Builder Guide for detailed walkthrough.
orchestra inspect
Discover available tools and their schemas from any MCP server.
orchestra inspect <server.yaml> [OPTIONS]
Options:
-v, --verbose Show detailed connection info and raw schemas
Use cases:
- Explore new MCP servers before writing tests
- Verify correct parameter names
- Generate example YAML snippets for tool calls
orchestra run
Run a test collection.
orchestra run <collection.yaml> [OPTIONS]
Options:
-V, --verbose / --no-verbose Show detailed step output (default: on)
-q, --quiet Only show errors and final status
-r, --show-responses Show full JSON responses from tool calls
-o, --output [text|json] Output format (default: text)
-R, --report-dir PATH Directory for JSON reports (default: reports/)
--no-report Don't save a JSON report
orchestra validate
Validate a collection schema without running it.
orchestra validate <collection.yaml>
orchestra info
Show Orchestra information and version.
orchestra info
๐ Collection Schema Reference
Server Configuration
STDIO Transport (Local Servers)
For local MCP servers that run as subprocesses:
server:
transport: "stdio"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-memory"]
# Optional: Pass environment variables to subprocess
env:
API_KEY: "{{env.MY_API_KEY}}"
DEBUG: "true"
Environment Variables for STDIO:
- Orchestra can pass environment variables from the collection schema to the subprocess
- Useful for servers that need API keys (e.g., Brave Search, Kaggle)
# Collection-level env vars (accessible via {{env.VAR}})
env:
BRAVE_API_KEY: "your-key-here"
server:
transport: "stdio"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-brave-search"]
# Pass to subprocess
env:
BRAVE_API_KEY: "{{env.BRAVE_API_KEY}}"
HTTP Transport (Remote Servers)
For remote MCP servers over HTTP (Streamable HTTP):
server:
transport: "http"
url: "https://mcp.deepwiki.com/mcp"
SSE Transport
For servers using Server-Sent Events:
server:
transport: "sse"
url: "http://localhost:3001"
With Authentication
Orchestra supports three authentication types:
Bearer Token:
server:
transport: "http"
url: "https://api.example.com/mcp"
auth:
type: "bearer"
token: "{{env.API_TOKEN}}"
API Key:
server:
transport: "http"
url: "https://api.example.com/mcp"
auth:
type: "api_key"
key: "{{env.API_KEY}}"
Basic Auth:
server:
transport: "http"
url: "https://api.example.com/mcp"
auth:
type: "basic"
username: "{{env.USERNAME}}"
password: "{{env.PASSWORD}}"
Steps
Tool Call Step
Invoke an MCP tool and optionally save the result for assertions:
- id: my_step
type: tool_call
tool: "tool_name"
input:
param1: "value"
param2: 123
nested:
key: "value"
save: "$" # Save full response
delay_ms: 2000 # Wait 2 seconds after this step (for rate limiting)
Rate Limiting:
Use delay_ms to prevent hitting rate limits on public APIs:
steps:
- id: search_1
type: tool_call
tool: "brave_web_search"
input:
query: "Python"
save: "$"
delay_ms: 2000 # Wait 2 seconds
- id: search_2
type: tool_call
tool: "brave_web_search"
input:
query: "JavaScript"
save: "$"
delay_ms: 2000 # Wait 2 seconds
Assertion Step
Validate tool call results with powerful assertions:
- id: check_result
type: assert
from: "my_step" # Reference a previous step
check:
op: "jsonpath_eq"
path: "$.field"
value: "expected"
delay_ms: 0 # Optional delay after assertion
Assertion Operators
| Operator | Description | Requires Path | Requires Value | Example |
|---|---|---|---|---|
jsonpath_exists |
Check if path exists in response | โ | โ | Path $.content[0].text exists |
jsonpath_eq |
Check if value equals expected | โ | โ | $.status equals "success" |
jsonpath_contains |
Check if string/array contains value | โ | โ | $.text contains "hello" |
jsonpath_len_eq |
Check array length equals N | โ | โ | $.items has exactly 5 items |
jsonpath_len_gte |
Check array length >= N | โ | โ | $.items has at least 3 items |
jsonpath_len_lte |
Check array length <= N | โ | โ | $.items has at most 10 items |
is_error |
Check if MCP response has isError=true | โ | โ | Response contains an error |
no_error |
Check if MCP response has no error | โ | โ | Response is successful |
Error Detection
MCP servers can return successful JSON-RPC responses that contain tool execution errors (indicated by isError: true). Orchestra automatically detects these and provides specialized assertions:
steps:
# Call a tool that might fail
- id: risky_call
type: tool_call
tool: "some_tool"
input:
param: "value"
save: "$"
# Verify it succeeded
- id: check_success
type: assert
from: "risky_call"
check:
op: "no_error" # Fails if isError=true
# Or test error handling
- id: bad_call
type: tool_call
tool: "nonexistent_tool"
input: {}
save: "$"
- id: expect_error
type: assert
from: "bad_call"
check:
op: "is_error" # Passes if isError=true
Console output with error detection:
โถ Step: bad_call (tool_call)
Tool: nonexistent_tool
โ ๏ธ Tool returned error: Tool not found
Response:
{
"content": [...],
"isError": true
}
โถ Step: expect_error (assert)
Check: is_error at $
โ
Passed
Defaults
Set default values for all steps:
defaults:
timeout_ms: 30000 # 30 seconds (default)
retries: 0 # No retries (default)
Environment Variables
Orchestra supports environment variable interpolation using {{env.VAR_NAME}}:
# Define at collection level
env:
API_KEY: "my-secret-key"
BASE_URL: "https://api.example.com"
server:
transport: "http"
url: "{{env.BASE_URL}}/mcp"
auth:
type: "api_key"
key: "{{env.API_KEY}}"
steps:
- id: call_with_env
type: tool_call
tool: "search"
input:
api_key: "{{env.API_KEY}}"
Environment variables are pulled from:
- Collection-level
envblock - Shell environment (via
os.environ)
๐งช Real-World Examples
Example 1: DeepWiki (Remote HTTP, No Auth)
Test an AI-powered documentation server:
version: 1
name: "DeepWiki Test"
server:
transport: "http"
url: "https://mcp.deepwiki.com/mcp"
steps:
- id: ask_about_react
type: tool_call
tool: "ask_question"
input:
repoName: "facebook/react"
question: "What are React hooks?"
save: "$"
delay_ms: 2000
- id: check_answer
type: assert
from: "ask_about_react"
check:
op: "jsonpath_contains"
path: "$.content[0].text"
value: "hook"
Example 2: Brave Search (STDIO, API Key)
Test a search API with authentication:
version: 1
name: "Brave Search Test"
env:
BRAVE_API_KEY: "your-api-key"
server:
transport: "stdio"
command: "npx"
args: ["-y", "@modelcontextprotocol/server-brave-search"]
env:
BRAVE_API_KEY: "{{env.BRAVE_API_KEY}}"
steps:
- id: search_python
type: tool_call
tool: "brave_web_search"
input:
query: "Python programming"
count: 5
save: "$"
delay_ms: 2000 # Rate limiting
- id: check_results
type: assert
from: "search_python"
check:
op: "jsonpath_len_gte"
path: "$.content"
value: 1
Example 3: MCPCalc (Remote HTTP, Calculator Service)
Test a calculator service:
version: 1
name: "MCPCalc Test"
server:
transport: "http"
url: "https://mcpcalc.com/api/v1/mcp"
steps:
- id: list_calculators
type: tool_call
tool: "list_calculators"
input:
category: "math"
save: "$"
- id: calculate_percentage
type: tool_call
tool: "calculate"
input:
calculator: "percentage"
inputs:
value: 50
percentage: 20
save: "$"
- id: verify_result
type: assert
from: "calculate_percentage"
check:
op: "no_error"
๐ Reports
Orchestra generates detailed JSON reports for every test run:
{
"run_id": "abc123-def456",
"collection_name": "My Test",
"status": "passed",
"started_at": "2026-02-14T12:00:00Z",
"completed_at": "2026-02-14T12:00:01Z",
"duration_ms": 1234,
"server": {
"name": "memory-server",
"version": "0.6.3"
},
"steps": [
{
"id": "create_entity",
"type": "tool_call",
"status": "success",
"duration_ms": 150,
"tool": "create_entities",
"result": { ... }
},
{
"id": "verify_created",
"type": "assert",
"status": "passed",
"duration_ms": 5,
"assertion": {
"op": "jsonpath_exists",
"path": "$.content[0].text"
}
}
]
}
โ Tested MCP Servers
Orchestra has been validated against multiple production MCP servers:
- โ DeepWiki - AI-powered codebase documentation (HTTP, remote)
- โ MCPCalc - Calculator service (HTTP, remote)
- โ Puppeteer - Browser automation (STDIO, local)
- โ Brave Search - Web search API (STDIO, API key auth)
- โ Kaggle - Dataset management (STDIO, local)
- โ Memory Server - Knowledge graph storage (STDIO, local)
- โ Everything Server - Demo server with all MCP features (STDIO/HTTP/SSE)
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
MIT
๐ Acknowledgments
Built on the Model Context Protocol (MCP) by Anthropic.
Made with โค๏ธ for the MCP community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file orchestra_mcp-0.1.0.tar.gz.
File metadata
- Download URL: orchestra_mcp-0.1.0.tar.gz
- Upload date:
- Size: 123.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9daf5c0d0ef8064c6d8a8f9c5dbe38a448bd8ca21846a8133274c9e3cd918e9
|
|
| MD5 |
7919374828363586e8b13831640d8592
|
|
| BLAKE2b-256 |
55eabf4abaaf096dbb07fe38810c01a85f6ff695584574ed5d645a392529616b
|
File details
Details for the file orchestra_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: orchestra_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 51.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e73891bec8c3b751e28baa5f9aeb91aa21c2abba0aceadd76508830f9d9642e5
|
|
| MD5 |
ab8237bda8e2d5c316428f754878e984
|
|
| BLAKE2b-256 |
b064a0723cc6b74c51d1a81feccb0f13651b105f299c9626c23c5357197ad52e
|