Hybrid Strategies: Using Skills and MCP Together
Why Hybrid?
Skills and MCP each have strengths the other lacks:
| Capability | Skills (CLI) | MCP |
|---|---|---|
| Token efficiency | Excellent | Poor |
| Semantic page understanding | None (just text/screenshots) | Excellent (accessibility trees) |
| Speed | Fast (130 tokens/step) | Slow (5K+ tokens/step) |
| Discovery | Manual (you need to know selectors) | Automatic (agent reads page structure) |
A hybrid approach uses MCP for understanding and Skills for action.
Strategy 1: MCP for Discovery, Skills for Execution
The Pattern
Phase 1: Discovery (MCP)
Agent: "What's on this page?"
→ browser_snapshot() returns accessibility tree
→ Agent identifies: login form with #email, #password, button.submit
Phase 2: Execution (Skill)
Agent: "Now I know the selectors. Execute the test."
→ vibe-check type "#email" "user@test.com"
→ vibe-check type "#password" "secret"
→ vibe-check click "button.submit"
Token Cost
Discovery phase: ~5,000 tokens (one-time accessibility read)
Execution phase: ~500 tokens (5 CLI commands)
Total: ~5,500 tokens
vs. Pure MCP: ~25,000 tokens (all steps via MCP tools)
vs. Pure Skill: ~500 tokens (but you need to know selectors in advance)
When to Use
- New applications where you don't know the DOM structure
- UI that changes frequently — discovery phase adapts automatically
- First test run of a new feature — subsequent runs use cached selectors
Strategy 2: Skill by Default, MCP as Fallback
The Pattern
# Pseudocode for the agent's behavior
try:
# Primary: use skill (fast, cheap)
vibe-check click "button.submit"
except SelectorNotFound:
# Fallback: use MCP to understand the page
snapshot = browser_snapshot() # MCP tool
# Agent reasons about the accessibility tree
# Agent finds the correct selector
new_selector = agent.reason(snapshot, "find the submit button")
vibe-check click new_selector # Back to skill
Token Cost
Happy path (skill works): ~130 tokens
Fallback path (MCP needed): ~5,130 tokens (one snapshot + retry)
Average (assuming 90% success): ~630 tokens per step
When to Use
- Mature test suites where most selectors are stable
- Self-healing tests that adapt when the UI changes
- Cost optimization — only pay MCP cost when needed
Strategy 3: Different Tools for Different Test Types
The Pattern
| Test Type | Primary Tool | Why |
|---|---|---|
| Functional tests | Skill (vibe-check) | Known flows, known selectors, fast |
| Accessibility audits | MCP (Playwright) | Need semantic page analysis |
| Visual regression | Skill + screenshots | Screenshot comparison is cheap |
| Exploratory testing | MCP | Agent needs to discover the UI |
| API integration tests | Skill + eval | vibe-check eval for XHR inspection |
| Performance checks | Skill + eval | vibe-check eval "performance.timing" |
Configuration
# test-framework-config.yaml
test_types:
functional:
tool: vibe-check
mode: daemon
headless: true
accessibility:
tool: playwright-mcp
a11y_analysis: true
visual:
tool: vibe-check
screenshots: true
comparison_threshold: 0.98
exploratory:
tool: playwright-mcp
snapshot_mode: full
max_depth: 5
Strategy 4: Phased Framework Adoption
Phase 1: Skills Only (Week 1-2)
Start with the simplest approach:
- Install vibe-check skill
- Write tests using known CSS selectors
- Run in daemon mode for development, oneshot for CI
# Simple test script
vibe-check navigate https://app.example.com/login
vibe-check type "#email" "test@example.com"
vibe-check type "#password" "password"
vibe-check click "#submit"
vibe-check wait ".dashboard"
vibe-check text ".welcome" | grep "Welcome"
Phase 2: Add MCP for Discovery (Week 3-4)
When you hit tests where selectors are unknown or unstable:
- Add Playwright MCP:
claude mcp add playwright -- npx @playwright/mcp - Use MCP only for page discovery and accessibility testing
- Keep all execution on vibe-check
Phase 3: Intelligent Routing (Week 5+)
Build routing logic that chooses the right tool:
- Known selectors → skill
- Unknown pages → MCP for discovery, then skill for execution
- Accessibility tests → MCP always
- CI runs → skill only (cost optimization)
Implementation: A Simple Hybrid Test
Here's what a hybrid test looks like in practice, as an agent would execute it:
Agent thinking: "I need to test the login flow on the new redesigned page.
I don't know the new selectors. Let me discover first."
Step 1: Navigate (Skill - cheap)
→ Bash: vibe-check navigate https://app.example.com/login
Step 2: Discover page structure (MCP - expensive but necessary)
→ browser_snapshot()
→ Agent receives accessibility tree:
[role="form" name="Login"]
[role="textbox" name="Email address" ref=3]
[role="textbox" name="Password" ref=4]
[role="button" name="Sign in" ref=5]
[role="link" name="Forgot password?" ref=6]
Step 3: Agent maps semantic names to selectors
→ Agent reasons: "Email address" field = textbox ref=3
→ Uses vibe-check find-all "input" --json to get CSS selectors
→ Maps: email → "input[aria-label='Email address']"
Step 4: Execute test (Skill - cheap)
→ Bash: vibe-check type "input[aria-label='Email address']" "test@example.com"
→ Bash: vibe-check type "input[aria-label='Password']" "secret"
→ Bash: vibe-check click "button[name='Sign in']"
→ Bash: vibe-check wait ".dashboard"
→ Bash: vibe-check text ".welcome"
Step 5: Verify + Screenshot (Skill - cheap)
→ Bash: vibe-check screenshot -o login-test-result.png
Total: 1 MCP call (~5K tokens) + 7 skill calls (~900 tokens) = ~5,900 tokens
vs. Pure MCP: ~35,000 tokens
Anti-Patterns to Avoid
Don't: Use MCP for Every Click
# BAD: Each action via MCP
browser_click(ref=5) # ~5K tokens (includes full snapshot refresh)
browser_type(ref=3, "hi") # ~5K tokens
browser_click(ref=7) # ~5K tokens
# Total: 15K+ tokens for 3 actions
Don't: Use Skills for Unknown Pages
# BAD: Guessing selectors
vibe-check click ".btn-primary" # Might not exist
vibe-check click "#submit" # Wrong ID
vibe-check click "button" # Wrong button
# Wasted 3 attempts + error handling
Do: Match the Tool to the Task
# GOOD: MCP for understanding, skill for action
MCP: What's on this page? → 5K tokens (one-time understanding)
Skill: Now click the right button → 130 tokens (precise action)
Interview Talking Point
"Our framework uses a hybrid approach. For known test flows with stable selectors, we use the vibe-check CLI skill — it's 29x cheaper in tokens and faster. For new features or pages where we don't know the DOM structure, we use Playwright MCP to discover the page layout via accessibility trees, then switch back to the skill for execution. We also use MCP exclusively for accessibility audits where semantic page analysis is the point. This gives us the efficiency of CLI skills for 90% of our work and the richness of MCP when we truly need it."