Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Research-to-implement pipeline chaining 5 MCP tools with graceful degradation
.claude/skills/mcp-chaining/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-13 | ✗→✓ | ▲ Improved | 72% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 65% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -2% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 30% | 0% |
A research-to-implement pipeline that chains 5 MCP tools for end-to-end workflows.
A pipeline that chains these tools:
| Step | Server | Tool ID | Purpose | |------|--------|---------|---------| | 1 | nia | nia__search | Search library documentation | | 2 | ast-grep | ast-grep__find_code | Find AST code patterns | | 3 | morph | morph__warpgrep_codebase_search | Fast codebase search | | 4 | qlty | qlty__qlty_check | Code quality validation | | 5 | git | git__git_status | Git operations |
scripts/research_implement_pipeline.py - Main pipeline implementationscripts/test_research_pipeline.py - Test harness with isolated sandboxworkspace/pipeline-test/sample_code.py - Test sample codebash# Dry-run pipeline (preview plan without changes) uv run python -m runtime.harness scripts/research_implement_pipeline.py \ --topic "async error handling python" \ --target-dir "./workspace/pipeline-test" \ --dry-run --verbose # Run tests uv run python -m runtime.harness scripts/test_research_pipeline.py --test all # View the pipeline script cat scripts/research_implement_pipeline.py
The MCP SDK's get_default_environment() only includes basic vars (PATH, HOME, etc.), NOT os.environ. We fixed src/runtime/mcp_client.py to pass full environment:
python# In _connect_stdio method: full_env = {**os.environ, **(resolved_env or {})}
This ensures API keys from ~/.claude/.env reach subprocesses.
Each tool is optional. If unavailable (disabled, no API key, etc.), the pipeline continues:
pythonasync def check_tool_available(tool_id: str) -> bool: """Check if an MCP tool is available.""" server_name = tool_id.split("__")[0] server_config = manager._config.get_server(server_name) if not server_config or server_config.disabled: return False return True # In step function: if not await check_tool_available("nia__search"): return StepResult(status=StepStatus.SKIPPED, message="Nia not available")
nia__search - Universal documentation search
nia__nia_research - Research with sources
nia__nia_grep - Grep-style doc search
nia__nia_explore - Explore package structureast-grep__find_code - Find code by AST pattern
ast-grep__find_code_by_rule - Find by YAML rule
ast-grep__scan_code - Scan with multiple patternsmorph__warpgrep_codebase_search - 20x faster grep
morph__edit_file - Smart file editingqlty__qlty_check - Run quality checks
qlty__qlty_fmt - Auto-format code
qlty__qlty_metrics - Get code metrics
qlty__smells - Detect code smellsgit__git_status - Get repo status
git__git_diff - Show differences
git__git_log - View commit history
git__git_add - Stage files +----------------+
| CLI Args |
| (topic, dir) |
+-------+--------+
|
+-------v--------+
| PipelineContext|
| (shared state) |
+-------+--------+
|
+-------+-------+-------+-------+-------+
| | | | | |
+---v---+---v---+---v---+---v---+---v---+
| nia |ast-grp| morph | qlty | git |
|search |pattern|search |check |status |
+---+---+---+---+---+---+---+---+---+---+
| | | | |
+-------v-------v-------v-------+
|
+-------v--------+
| StepResult[] |
| (aggregated) |
+----------------+The pipeline captures errors without failing the entire run:
pythontry: result = await call_mcp_tool("nia__search", {"query": topic}) return StepResult(status=StepStatus.SUCCESS, data=result) except Exception as e: ctx.errors.append(f"nia: {e}") return StepResult(status=StepStatus.FAILED, error=str(e))
scripts/research_implement_pipeline.pycheck_tool_available() for graceful degradationPipelineContextprint_summary()| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-13 | fail→pass | 5,657 | 1,453 | -74% | 1 | 1 | 0% | 876 | 1,509 | +72% | 0 | 0 | — |
case-01 | fail→pass | 6,715 | 3,001 | -55% | 1 | 1 | 0% | 1,140 | 1,878 | +65% | 0 | 0 | — |
case-02 | fail→pass | 6,009 | 2,067 | -66% | 1 | 1 | 0% | 985 | 1,671 | +70% | 0 | 0 | — |
case-03 | fail→pass | 19,370 | 11,586 | -40% | 1 | 1 | 0% | 3,831 | 3,761 | -2% | 0 | 0 | — |
case-14 | fail→pass | 5,929 | 1,270 | -79% | 1 | 1 | 0% | 1,138 | 1,478 | +30% | 0 | 0 | — |
case-04 | fail→pass | 12,004 | 7,236 | -40% | 1 | 1 | 0% | 2,077 | 2,749 | +32% | 0 | 0 | — |
case-05 | fail→pass | 10,511 | 5,640 | -46% | 1 | 1 | 0% | 1,692 | 2,279 | +35% | 0 | 0 | — |
case-06 | fail→pass | 7,157 | 1,758 | -75% | 1 | 1 | 0% | 1,107 | 1,559 | +41% | 0 | 0 | — |
case-07 | fail→pass | 8,421 | 9,546 | +13% | 1 | 1 | 0% | 1,304 | 2,961 | +127% | 0 | 0 | — |
case-08 | fail→pass | 2,076 | 1,497 | -28% | 1 | 1 | 0% | 292 | 1,547 | +430% | 0 | 0 | — |
case-09 | fail→pass | 7,818 | 1,419 | -82% | 1 | 1 | 0% | 1,194 | 1,523 | +28% | 0 | 0 | — |
case-10 | pass→pass | 9,982 | 3,250 | -67% | 1 | 1 | 0% | 2,018 | 1,961 | -3% | 0 | 0 | — |
case-11 | fail→pass | 13,520 | 4,005 | -70% | 1 | 1 | 0% | 2,415 | 2,041 | -15% | 0 | 0 | — |
case-12 | fail→pass | 7,666 | 1,611 | -79% | 1 | 1 | 0% | 1,289 | 1,503 | +17% | 0 | 0 | — |
case-15 | fail→pass | 10,173 | 2,224 | -78% | 1 | 1 | 0% | 1,789 | 1,741 | -3% | 0 | 0 | — |
case-16 | fail→pass | 6,913 | 1,966 | -72% | 1 | 1 | 0% | 1,221 | 1,654 | +35% | 0 | 0 | — |
case-17 | fail→pass | 7,437 | 1,436 | -81% | 1 | 1 | 0% | 1,278 | 1,486 | +16% | 0 | 0 | — |
case-18 | fail→pass | 7,652 | 1,643 | -79% | 1 | 1 | 0% | 1,044 | 1,509 | +45% | 0 | 0 | — |
case-19 | fail→pass | 4,942 | 1,363 | -72% | 1 | 1 | 0% | 806 | 1,486 | +84% | 0 | 0 | — |
case-20 | fail→pass | 4,879 | 2,970 | -39% | 1 | 1 | 0% | 835 | 1,574 | +89% | 0 | 0 | — |
case-21 | pass→pass | 21,258 | 18,657 | -12% | 1 | 1 | 0% | 4,345 | 5,300 | +22% | 0 | 0 | — |
case-22 | pass→pass | 16,578 | 11,919 | -28% | 1 | 1 | 0% | 3,128 | 3,589 | +15% | 0 | 0 | — |
case-23 | pass→pass | 10,330 | 10,513 | +2% | 1 | 1 | 0% | 2,074 | 3,259 | +57% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +83 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/29/2026 | +77% |
Other measured skills in the registry, with their headline benchmark lift.