KS
Killer-Skills

mcp-client — how to use mcp-client how to use mcp-client, mcp-client setup guide, mcp-client alternative, mcp-client vs playwright, mcp-client install, mcp-client browser session management, universal mcp server connection, mcp-client multi-step operations, browser_run_code command

v1.0.0
GitHub

About this Skill

Perfect for Automated Workflow Agents needing seamless MCP server connections without context bloat. mcp-client is a universal client for connecting to MCP servers, allowing for efficient browser session management and multi-step operations.

Features

Connects to any MCP server without requiring tool definitions
Creates a new browser session for each MCP call
Closes the browser after each call for efficient resource management
Supports multi-step operations using the browser_run_code command
Requires redoing all steps from scratch to return to a previous state, such as a logged-in session

# Core Topics

cristian-robert cristian-robert
[0]
[0]
Updated: 3/7/2026

Quality Score

Top 5%
60
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add cristian-robert/autonomous-automation-tester/references/mcp-config.example.json

Agent Capability Analysis

The mcp-client MCP Server by cristian-robert is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use mcp-client, mcp-client setup guide, mcp-client alternative.

Ideal Agent Persona

Perfect for Automated Workflow Agents needing seamless MCP server connections without context bloat.

Core Value

Empowers agents to connect to any MCP server using Playwright, enabling multi-step operations via browser_run_code and handling browser sessions efficiently with each MCP call.

Capabilities Granted for mcp-client MCP Server

Automating MCP server interactions
Generating browser sessions for testing
Debugging MCP call issues with browser_run_code

! Prerequisites & Limits

  • Each MCP call creates a new browser session
  • Browser closes after each call
  • Requires redoing all steps for returning to a previous state
Project
SKILL.md
10.8 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

Universal MCP Client

Connect to any MCP server without bloating context with tool definitions.

⚠️ PLAYWRIGHT USERS: READ "CRITICAL: Playwright Browser Session Behavior" SECTION BELOW!

Each MCP call = new browser session. Browser CLOSES after each call. You CANNOT navigate in one call and click in another. Use browser_run_code for ANY multi-step operation. If you need to return to a state (e.g., logged in), you MUST redo ALL steps from scratch.

How It Works

Instead of loading all MCP tool schemas into context, this client:

  1. Lists available servers from config
  2. Queries tool schemas on-demand
  3. Executes tools with JSON arguments

Configuration

Config location priority:

  1. MCP_CONFIG_PATH environment variable
  2. .claude/skills/mcp-client/references/mcp-config.json
  3. .mcp.json in current directory
  4. ~/.claude.json

Commands

bash
1# List configured servers 2python scripts/mcp_client.py servers 3 4# List tools from a specific server 5python scripts/mcp_client.py tools playwright 6 7# Call a tool 8python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}'

CRITICAL: Playwright Browser Session Behavior

⚠️ The Session Problem

Each MCP call creates a NEW browser session. The browser CLOSES after each call.

This means:

bash
1# ❌ WRONG - These run in SEPARATE browser sessions! 2python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}' 3python scripts/mcp_client.py call playwright browser_click '{"element": "Accept cookies"}' 4python scripts/mcp_client.py call playwright browser_snapshot '{}' 5# ^ The snapshot captures a FRESH page, not the page after clicking!

✅ The Solution: browser_run_code

Use browser_run_code to run multiple Playwright steps in ONE browser session:

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://example.com\"); 4 5 // Wait for and click cookie banner 6 const acceptBtn = page.getByRole(\"button\", { name: /accept/i }); 7 if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) { 8 await acceptBtn.click(); 9 await page.waitForTimeout(1000); 10 } 11 12 // Wait for page to stabilize 13 await page.waitForLoadState(\"networkidle\"); 14 15 // Return snapshot data for analysis 16 const snapshot = await page.accessibility.snapshot(); 17 return JSON.stringify(snapshot, null, 2); 18 " 19}'

When to Use Each Approach

ScenarioToolWhy
Simple page load + snapshotbrowser_navigateReturns snapshot automatically
Multi-step interactionbrowser_run_codeKeeps session alive
Click then observe resultbrowser_run_codeSession persists
Fill form and submitbrowser_run_codeSession persists
Hover to reveal menubrowser_run_codeSession persists

Playwright Workflows for Test Discovery

1. Basic Page Exploration (Single Step)

browser_navigate returns both navigation result AND accessibility snapshot:

bash
1python scripts/mcp_client.py call playwright browser_navigate '{"url": "https://example.com"}'

Output includes:

  • Page URL and title
  • Full accessibility tree (all visible elements with roles, names, states)
  • Element references for further interaction

Use this when: Simple page load without interactions

2. Page with Cookie Banner (Multi-Step)

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://www.olx.ro\"); 4 5 // Handle cookie consent 6 try { 7 const cookieBtn = page.getByRole(\"button\", { name: \"Accept\" }); 8 await cookieBtn.click({ timeout: 5000 }); 9 await page.waitForTimeout(1000); 10 } catch (e) { 11 // No cookie banner 12 } 13 14 // Get accessibility snapshot 15 const snapshot = await page.accessibility.snapshot({ interestingOnly: false }); 16 return JSON.stringify(snapshot, null, 2); 17 " 18}'

3. Navigate to Subpage (Multi-Step)

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://www.olx.ro\"); 4 5 // Dismiss cookies 6 const acceptBtn = page.getByRole(\"button\", { name: \"Accept\" }); 7 if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) { 8 await acceptBtn.click(); 9 await page.waitForTimeout(500); 10 } 11 12 // Navigate to login 13 await page.goto(\"https://www.olx.ro/cont/\"); 14 15 // Wait for redirect to login domain 16 await page.waitForURL(/login\\.olx\\.ro/, { timeout: 10000 }); 17 18 // Get form structure 19 const snapshot = await page.accessibility.snapshot(); 20 return JSON.stringify({ url: page.url(), snapshot }, null, 2); 21 " 22}'

4. Explore Element Interactions (Multi-Step)

Use this to understand how menus/dropdowns behave:

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://www.olx.ro\"); 4 5 // Dismiss cookies 6 const acceptBtn = page.getByRole(\"button\", { name: \"Accept\" }); 7 if (await acceptBtn.isVisible({ timeout: 3000 }).catch(() => false)) { 8 await acceptBtn.click(); 9 } 10 11 // Click on category to see what happens 12 const categoryLink = page.getByRole(\"link\", { name: /Auto, moto/i }).first(); 13 await categoryLink.click(); 14 15 // Wait to see result 16 await page.waitForTimeout(1500); 17 18 // Capture state after click 19 const snapshot = await page.accessibility.snapshot(); 20 return JSON.stringify({ 21 url: page.url(), 22 didNavigate: page.url().includes(\"auto\"), 23 snapshot: snapshot 24 }, null, 2); 25 " 26}'

5. Fill Form and Capture State

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://login.olx.ro\"); 4 5 // Fill login form 6 await page.locator(\"input[type=email]\").fill(\"test@example.com\"); 7 await page.locator(\"input[type=password]\").fill(\"test123\"); 8 9 // Click login button 10 await page.getByTestId(\"login-submit-button\").click(); 11 12 // Wait for response 13 await page.waitForTimeout(3000); 14 15 // Capture any error messages 16 const errors = await page.locator(\"[class*=error], [role=alert]\").allTextContents(); 17 const snapshot = await page.accessibility.snapshot(); 18 19 return JSON.stringify({ 20 url: page.url(), 21 errors: errors, 22 snapshot: snapshot 23 }, null, 2); 24 " 25}'

Gathering Selectors for Page Objects

Best Practices

1. Use Accessibility Tree First

The snapshot from browser_navigate or browser_run_code provides:

  • Role: button, link, textbox, combobox, etc.
  • Name: accessible name (from label, aria-label, text content)
  • State: disabled, checked, expanded, etc.

Map these to Playwright locators:

typescript
1// From snapshot: { role: "button", name: "Căutare" } 2page.getByRole('button', { name: /Căutare/i }) 3 4// From snapshot: { role: "textbox", name: "Ce anume cauți?" } 5page.getByRole('textbox', { name: /Ce anume cauți/i }) 6 7// From snapshot: { role: "link", name: "Auto, moto și ambarcațiuni" } 8page.getByRole('link', { name: /Auto, moto/i })

2. Selector Priority

PriorityMethodUse When
1getByRole()Element has semantic role + accessible name
2getByTestId()Element has data-testid attribute
3getByText()Unique text content
4getByPlaceholder()Input with placeholder
5locator('[attr="value"]')CSS attribute selector
6locator('.class')CSS class (fragile, avoid)

3. Handling Multiple Matches

typescript
1// Use .first() when multiple match 2page.getByRole('link', { name: 'Category' }).first() 3 4// Use parent context 5page.locator('nav').getByRole('link', { name: 'Category' }) 6 7// Use filter 8page.getByRole('button').filter({ hasText: /submit/i })

4. Get Full DOM for Complex Cases

When accessibility tree isn't enough, get raw HTML:

bash
1python scripts/mcp_client.py call playwright browser_run_code '{ 2 "code": " 3 await page.goto(\"https://example.com\"); 4 5 // Get specific element HTML 6 const formHtml = await page.locator(\"form\").first().innerHTML(); 7 8 // Or get all buttons with their attributes 9 const buttons = await page.locator(\"button\").evaluateAll(btns => 10 btns.map(b => ({ 11 text: b.textContent, 12 testid: b.dataset.testid, 13 class: b.className, 14 type: b.type 15 })) 16 ); 17 18 return JSON.stringify({ formHtml, buttons }, null, 2); 19 " 20}'

Quick Reference: Playwright MCP Tools

ToolSession BehaviorUse Case
browser_navigateNew session, returns snapshotSimple page load
browser_run_codeSingle session, custom scriptMulti-step operations
browser_clickNew sessionSingle click (usually not useful alone)
browser_typeNew sessionSingle type (usually not useful alone)
browser_snapshotReuses if session existsGet current page state
browser_screenshotReuses if session existsVisual capture

Tool Arguments

browser_navigate

json
1{"url": "https://example.com"}

browser_run_code

json
1{ 2 "code": "await page.goto('https://example.com'); return await page.title();" 3}

The code must be valid JavaScript that:

  • Uses page object (Playwright Page)
  • Uses await for async operations
  • Returns the data you want (use JSON.stringify for objects)

browser_click

json
1{"element": "Submit button", "ref": "optional-element-ref"}

browser_type

json
1{"element": "Email input", "text": "user@example.com"}

Error Handling

ErrorCauseFix
"No MCP config found"Missing config fileCreate mcp-config.json
"Server not found"Server not in configAdd server to config
"Connection failed"Server not runningStart the MCP server
"Invalid JSON"Bad tool argumentsCheck argument format
"Timeout"Page too slowIncrease timeout in code
"Element not found"Wrong selectorCheck snapshot for actual names

Setup

  1. Copy the example config:

    bash
    1cp .claude/skills/mcp-client/references/mcp-config.example.json \ 2 .claude/skills/mcp-client/references/mcp-config.json
  2. The config should contain:

    json
    1{ 2 "mcpServers": { 3 "playwright": { 4 "command": "npx", 5 "args": ["@playwright/mcp@latest"] 6 } 7 } 8}
  3. Install dependencies:

    bash
    1pip install mcp fastmcp

Config Example

See references/mcp-config.example.json

Available Servers

See references/mcp-servers.md for:

  • Playwright (browser automation)
  • GitHub (repository operations)
  • Filesystem (file access)
  • Sequential Thinking (reasoning)
  • And more...

Dependencies

bash
1pip install mcp fastmcp

Related Skills

Looking for an alternative to mcp-client or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication