In the previous tutorials, we learned the theory behind MCP: MCP Fundamentals (tutorial 1), the MCP Host, Client & Server architecture (tutorial 2), and MCP Tools, Resources & Prompts (tutorial 3). Now it is time to actually build one.
Tutorial 1
MCP Fundamentals
↓
Tutorial 2
MCP Host, Client & Server
↓
Tutorial 3
MCP Tools, Resources & Prompts
↓
Tutorial 4
BUILD YOUR FIRST MCP SERVERInstead of only discussing Host, Client, Server, Tools, Resources and Prompts, we will create a working MCP server using TypeScript. Our server will expose 1 Tool, 1 Resource and 1 Prompt. Then we will build a small MCP client and connect it to the server.
MCP CLIENT
│
│ MCP
▼
QA MCP SERVER
│
├── TOOL
│
├── RESOURCE
│
└── PROMPTThis is the foundation you need before moving into Playwright MCP, GitHub Copilot + MCP, Testing Agents and Agentic AI Testing.
1. What Are We Building?
We will create a small MCP server called qa-mcp-server. It will expose three capabilities.
- Tool: validate-product-price — validates whether a product price is valid according to a simple business rule.
- Resource: qa://testing-guidelines — provides QA testing guidelines to the MCP client.
- Prompt: review-requirement — a reusable prompt for analyzing software requirements.
QA MCP SERVER
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
TOOL RESOURCE PROMPT
Validate Product QA Guidelines Requirement
Price Review2. Prerequisites
For the current TypeScript SDK, use Node.js 20+, npm, TypeScript and VS Code. The MCP TypeScript documentation currently recommends Node.js 20 or later for the getting-started flow.
node --version
# v20.x.x or newer
npm --version3. Create the Project
mkdir qa-mcp-server
cd qa-mcp-server
# Initialize Node
npm init -y
# Enable ES modules
npm pkg set type=moduleqa-mcp-server/
│
└── package.json4. Install MCP Server Dependencies
npm install @modelcontextprotocol/server zod tsx
mkdir srcThe current v2 SDK publishes the server separately as @modelcontextprotocol/server; Zod can be used to define input schemas.
qa-mcp-server/
│
├── node_modules/
│
├── src/
│
├── package.json
└── package-lock.json5. Why Do We Need Zod?
MCP tools and prompts can define structured inputs. For example, our tool needs a price value that should be a number. We can define it using Zod:
z.object({
price: z.number()
})The MCP SDK validates tool calls against the schema before invoking the handler. This helps prevent invalid input from reaching our business logic.
6. Create the MCP Server
Create src/index.ts and start with the imports:
import { McpServer } from '@modelcontextprotocol/server';
import { serveStdio } from '@modelcontextprotocol/server/stdio';
import * as z from 'zod/v4';McpServer
↓
Creates our MCP server
serveStdio
↓
Connects the server using stdio
Zod
↓
Defines input schemas7. Create the Server Instance
const server = new McpServer({
name: 'qa-mcp-server',
version: '1.0.0'
});Now we have a QA MCP SERVER, but it currently exposes nothing. No tools, no resources, no prompts. Let's add them.
8. Create Our First MCP Tool
We will create validate-product-price. Our business rule is: product price must be greater than 0.
server.registerTool(
'validate-product-price',
{
title: 'Validate Product Price',
description:
'Validates whether a product price is greater than zero.',
inputSchema: z.object({
price: z.number()
})
},
async ({ price }) => {
const valid = price > 0;
return {
content: [
{
type: 'text',
text: valid
? `PASS: Product price ${price} is valid.`
: `FAIL: Product price ${price} must be greater than zero.`
}
]
};
}
);Current SDK v2 uses registerTool(name, config, handler) and schema objects such as z.object(...).
9. Understand the Tool Code
The tool name 'validate-product-price' identifies the tool. The description is very important — the AI may use tool metadata to understand what the tool does and when to use it. Good descriptions improve tool selection.
10. Tool Input Schema
inputSchema: z.object({
price: z.number()
})price = 100 is valid, price = -25 is still technically a number (our business logic determines it is invalid), but price = "hello" would not match the schema at all.
11. Tool Handler
The handler receives the validated input. Our business rule is price > 0. If price = 100 the result is PASS; if price = -5 the result is FAIL.
async ({ price }) => {
const valid = price > 0;
// ...
}12. Tool Response
MCP TOOL
│
▼
EXECUTE LOGIC
│
▼
RESULT
│
▼
MCP CLIENT13. Tool Execution Architecture
MCP CLIENT
│
│ Call Tool
▼
QA MCP SERVER
│
▼
validate-product-price
│
▼
Check:
price > 0 ?
│
┌───┴───┐
│ │
YES NO
│ │
PASS FAIL14. Add Our First MCP Resource
Now we will expose testing information through the resource qa://testing-guidelines.
server.registerResource(
'testing-guidelines',
'qa://testing-guidelines',
{
title: 'QA Testing Guidelines',
description: 'Basic enterprise QA testing guidelines.',
mimeType: 'text/plain'
},
async (uri) => ({
contents: [
{
uri: uri.href,
text: `
Enterprise QA Testing Guidelines
1. Understand requirements before automation.
2. Review acceptance criteria.
3. Identify positive and negative scenarios.
4. Validate UI and API behavior.
5. Validate backend data when required.
6. Keep tests independent.
7. Avoid shared test data.
8. Use stable selectors.
9. Separate test logic from framework utilities.
10. Run critical tests in CI/CD.
`.trim()
}
]
})
);The current SDK supports registerResource with a URI and a read callback; the handler returns a contents collection.
15. What Did We Just Build?
MCP CLIENT
│
│ Read Resource
▼
QA MCP SERVER
│
▼
qa://testing-guidelines
│
▼
Testing Guidelines16. Why Resources Matter for SDETs
Imagine a real enterprise MCP server exposing qa://architecture, qa://acceptance-criteria, qa://api-contract, qa://database-schema and qa://automation-standards. An AI agent could retrieve this context before performing testing tasks:
Read Requirements
↓
Read Test Guidelines
↓
Understand Architecture
↓
Design Tests
↓
Execute Tests17. Add Our First MCP Prompt
server.registerPrompt(
'review-requirement',
{
title: 'Review Software Requirement',
description:
'Reviews a software requirement from an SDET perspective.',
argsSchema: z.object({
requirement: z.string()
})
},
({ requirement }) => ({
messages: [
{
role: 'user',
content: {
type: 'text',
text: `
Review the following software requirement:
${requirement}
Analyze it from an SDET perspective.
Identify:
1. Functional requirements
2. Business rules
3. Positive test scenarios
4. Negative test scenarios
5. Boundary conditions
6. Missing information
7. API testing needs
8. Database validation needs
9. Security considerations
10. Automation opportunities
`.trim()
}
}
]
})
);The v2 SDK provides registerPrompt(name, config, callback) and supports an argsSchema such as a Zod object.
18. Understand the Prompt
The prompt accepts a requirement, for example: "An administrator should be able to create a product. Product name is mandatory. Price must be greater than zero." The reusable prompt then asks the AI to analyze functional requirements, business rules, positive/negative scenarios, boundary cases, missing requirements, API testing, database testing, security and automation opportunities. Instead of rewriting these instructions every time, we package them into a reusable MCP prompt.
19. Our MCP Server Now Has All Three
QA MCP SERVER
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
TOOL RESOURCE PROMPT
validate-product- testing- review-
price guidelines requirementTOOL
=
DO SOMETHING
RESOURCE
=
PROVIDE INFORMATION
PROMPT
=
PROVIDE REUSABLE INSTRUCTIONS20. Start the MCP Server Using stdio
Now we need a transport. For our local tutorial we will use stdio. The easiest complete structure wraps the server creation:
import { McpServer } from '@modelcontextprotocol/server';
import { serveStdio } from '@modelcontextprotocol/server/stdio';
import * as z from 'zod/v4';
serveStdio(() => {
const server = new McpServer({
name: 'qa-mcp-server',
version: '1.0.0'
});
// register capabilities here
return server;
});The official SDK supports stdio for local, process-spawned MCP integrations.
21. Complete MCP Server Code
Your complete src/index.ts can look like this:
import { McpServer } from '@modelcontextprotocol/server';
import { serveStdio } from '@modelcontextprotocol/server/stdio';
import * as z from 'zod/v4';
serveStdio(() => {
const server = new McpServer({
name: 'qa-mcp-server',
version: '1.0.0'
});
// =====================================================
// TOOL
// =====================================================
server.registerTool(
'validate-product-price',
{
title: 'Validate Product Price',
description:
'Validates whether a product price is greater than zero.',
inputSchema: z.object({
price: z.number()
})
},
async ({ price }) => {
const valid = price > 0;
return {
content: [
{
type: 'text',
text: valid
? `PASS: Product price ${price} is valid.`
: `FAIL: Product price ${price} must be greater than zero.`
}
]
};
}
);
// =====================================================
// RESOURCE
// =====================================================
server.registerResource(
'testing-guidelines',
'qa://testing-guidelines',
{
title: 'QA Testing Guidelines',
description:
'Basic enterprise QA testing guidelines.',
mimeType: 'text/plain'
},
async (uri) => ({
contents: [
{
uri: uri.href,
text: `
Enterprise QA Testing Guidelines
1. Understand requirements before automation.
2. Review acceptance criteria.
3. Identify positive and negative scenarios.
4. Validate UI and API behavior.
5. Validate backend data when required.
6. Keep tests independent.
7. Avoid shared test data.
8. Use stable selectors.
9. Separate test logic from framework utilities.
10. Run critical tests in CI/CD.
`.trim()
}
]
})
);
// =====================================================
// PROMPT
// =====================================================
server.registerPrompt(
'review-requirement',
{
title: 'Review Software Requirement',
description:
'Reviews a software requirement from an SDET perspective.',
argsSchema: z.object({
requirement: z.string()
})
},
({ requirement }) => ({
messages: [
{
role: 'user',
content: {
type: 'text',
text: `
Review the following software requirement:
${requirement}
Analyze it from an SDET perspective.
Identify:
1. Functional requirements
2. Business rules
3. Positive test scenarios
4. Negative test scenarios
5. Boundary conditions
6. Missing information
7. API testing needs
8. Database validation needs
9. Security considerations
10. Automation opportunities
`.trim()
}
}
]
})
);
return server;
});22. Project Structure
qa-mcp-server/
│
├── src/
│ └── index.ts
│
├── package.json
├── package-lock.json
└── node_modules/23. Add a Start Script
{
"scripts": {
"start": "tsx src/index.ts"
}
}npm startYou may not see a normal web application screen. That is expected. This is not a React application or a REST API UI — it is an MCP server waiting for MCP communication.
24. Why Don't We Open localhost:3000?
This is an important concept. Our server currently uses stdio, not an HTTP web server.
MCP CLIENT
│
│ stdin / stdout
▼
MCP SERVERYou therefore do not test this local stdio server by simply opening http://localhost:3000. A compatible MCP client communicates with it through the configured transport.
25. What Is stdio?
CLIENT
│
│ request
▼
stdin
MCP SERVER
stdout
│
│ response
▼
CLIENTstdio means Standard Input + Standard Output. This is particularly useful for local MCP servers that a host launches as a child process.
26. Build a Small MCP Client
To fully understand what is happening, let's create our own client. The v2 TypeScript SDK provides the client as a separate package.
npm install @modelcontextprotocol/clientCreate src/client.ts.
27. Connect the Client to Our Server
import { Client } from '@modelcontextprotocol/client';
import {
StdioClientTransport
} from '@modelcontextprotocol/client/stdio';
const client = new Client({
name: 'qa-mcp-client',
version: '1.0.0'
});
const transport = new StdioClientTransport({
command: 'npx',
args: ['tsx', 'src/index.ts']
});
await client.connect(transport);When connect() is called, the stdio client transport can launch the MCP server as a child process and complete the MCP initialization handshake.
client.ts
│
▼
MCP Client
│
│ launches
▼
index.ts
│
▼
MCP Server28. List Available Tools
const tools = await client.listTools();
console.log('TOOLS');
console.log(
tools.tools.map(tool => tool.name)
);TOOLS
[
'validate-product-price'
]The client has discovered the tool exposed by our server.
29. Call the Tool
const toolResult = await client.callTool({
name: 'validate-product-price',
arguments: {
price: 100
}
});
console.log('TOOL RESULT');
console.log(toolResult);Client
↓
validate-product-price
↓
price = 100
↓
price > 0
↓
PASSTry price: -100. Now -100 > 0 is FALSE, so the result is FAIL.
30. Read the Resource
const resources = await client.listResources();
console.log('RESOURCES');
console.log(
resources.resources.map(resource => resource.uri)
);
// [ 'qa://testing-guidelines' ]
const resource = await client.readResource({
uri: 'qa://testing-guidelines'
});
console.log('RESOURCE');
console.log(resource.contents);The client receives our testing guidelines.
31. The Resource Flow
CLIENT
│
│ resources/read
▼
MCP SERVER
│
▼
qa://testing-guidelines
│
▼
QA Guidelines
│
▼
CLIENTThe current SDK distinguishes reading resources by URI from calling executable tools.
32. Discover the Prompt
CLIENT
↓
List Prompts
↓
SERVER
↓
review-requirementThe client can retrieve the reusable prompt and supply its required argument: requirement. For example: "Admin users can create products. Product name is required. Price must be greater than zero." The returned prompt becomes structured context that an AI host can provide to its model.
33. Important Point: The MCP Server Is Not the LLM
Our server contains the prompt "Review this requirement...", but our server itself is not performing AI reasoning.
MCP SERVER
│
│ returns prompt
▼
MCP HOST
│
▼
LLM
│
▼
AI RESPONSE34. Close the Client
await client.close();This ends the connection. For production-quality client code, use finally so the connection closes even if something fails. The official client guide recommends this pattern to avoid leaving spawned server processes running.
35. Complete Client Example
import { Client } from '@modelcontextprotocol/client';
import {
StdioClientTransport
} from '@modelcontextprotocol/client/stdio';
const client = new Client({
name: 'qa-mcp-client',
version: '1.0.0'
});
const transport = new StdioClientTransport({
command: 'npx',
args: ['tsx', 'src/index.ts']
});
try {
await client.connect(transport);
console.log('\nCONNECTED TO MCP SERVER\n');
// ========================================
// LIST TOOLS
// ========================================
const tools = await client.listTools();
console.log('TOOLS');
console.log(
tools.tools.map(tool => tool.name)
);
// ========================================
// CALL TOOL
// ========================================
const toolResult = await client.callTool({
name: 'validate-product-price',
arguments: {
price: 100
}
});
console.log('\nTOOL RESULT');
console.log(toolResult);
// ========================================
// LIST RESOURCES
// ========================================
const resources =
await client.listResources();
console.log('\nRESOURCES');
console.log(
resources.resources.map(
resource => resource.uri
)
);
// ========================================
// READ RESOURCE
// ========================================
const resource =
await client.readResource({
uri: 'qa://testing-guidelines'
});
console.log('\nRESOURCE CONTENT');
console.log(resource.contents);
} finally {
await client.close();
}36. Run the Client
npx tsx src/client.tsThe client:
Starts
↓
Launches MCP Server
↓
Initializes Connection
↓
Discovers Tool
↓
Calls Tool
↓
Discovers Resource
↓
Reads Resource
↓
Closes ConnectionThis is your first real MCP client/server interaction.
37. What Actually Happened?
src/client.ts
│
▼
MCP CLIENT
│
│ stdio
▼
src/index.ts
│
▼
MCP SERVER
│
├── Tool
│
├── Resource
│
└── PromptThe client didn't import our functions directly. Instead, it communicated with the server through MCP. That distinction is extremely important.
38. Why Not Just Import a JavaScript Function?
You might ask: why create MCP Client → MCP Server when we could just write validateProductPrice(100)? Because MCP solves a different problem. A regular function is primarily application code. MCP provides a standardized interface through which compatible AI applications can discover and interact with capabilities.
Instead of:
Application A
↓
Custom Integration
Application B
↓
Different Custom Integration
Application C
↓
Another Integration
you expose capabilities through:
MCP SERVER
and compatible hosts can understand the protocol.39. Where Does an AI Host Fit?
Our custom client helped us understand the protocol. A real AI-enabled workflow adds another layer:
USER
│
▼
AI HOST
│
▼
AI MODEL
│
▼
MCP CLIENT
│
▼
QA MCP SERVER
│
├── Tools
├── Resources
└── PromptsNow the model can potentially decide: I need this resource. I should call this tool. This prompt is relevant.
40. How Tool Discovery Helps the AI
Suppose our server describes the tool validate-product-price as "Validates whether a product price is greater than zero." Then the user asks: "Is a product price of -50 valid?" The AI can see an appropriate capability and invoke it.
USER QUESTION
│
▼
AI
│
▼
DISCOVER TOOLS
│
▼
validate-product-price
│
▼
CALL TOOL
│
▼
RESULT41. From Demo Server to Real QA Server
Our example is intentionally simple. A real Quality Engineering MCP server could expose:
TOOLS
──────────────────────────
get-test-result
run-api-test
query-qa-database
get-product-by-id
validate-api-schema
check-environment-health
create-test-data
delete-test-dataRESOURCES
──────────────────────────
qa://architecture
qa://test-strategy
qa://api-contract
qa://database-schema
qa://coding-standards
qa://environment-guidePROMPTS
──────────────────────────
review-requirement
generate-test-scenarios
analyze-test-failure
review-playwright-test
generate-defect-reportNow MCP starts becoming extremely relevant to SDETs.
42. Example Real QA MCP Architecture
AI AGENT
│
▼
MCP CLIENT
│
▼
QA MCP SERVER
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
TOOLS RESOURCES PROMPTS
Run API Test API Contract Review Requirement
Query DB DB Schema Generate Tests
Validate JSON Architecture Analyze Failure
Create Test Data Test Strategy Defect Summary43. What If We Add Playwright?
Now it becomes much more interesting. Imagine our MCP tool open-application internally uses Playwright:
AI
│
▼
MCP CLIENT
│
▼
QA MCP SERVER
│
▼
Browser Tool
│
▼
PLAYWRIGHT
│
▼
BROWSER
│
▼
APPLICATIONWe are now moving toward Playwright MCP.
44. Example Browser Tool Concept
Conceptually, our MCP server could expose navigate, click, type, inspect and snapshot. Then:
User
"Verify that login works."
↓
AI
↓
navigate
↓
inspect
↓
type username
↓
type password
↓
click login
↓
inspect resultThis begins the transition from a simple MCP server into browser-based Agentic Testing.
45. MCP Server vs Playwright Framework
Traditional Playwright:
TEST CODE
│
▼
PLAYWRIGHT
│
▼
BROWSER
MCP-connected browser workflow:
AI
│
▼
MCP CLIENT
│
▼
MCP SERVER
│
▼
PLAYWRIGHT
│
▼
BROWSERDo not confuse these architectures. Both can exist together.
46. Deterministic Automation Still Matters
Traditional Playwright tests remain extremely valuable:
test('admin creates product', async ({ page }) => {
await page.goto('/products');
await page
.getByRole('button', {
name: 'Add Product'
})
.click();
await page
.getByLabel('Product Name')
.fill('Laptop');
await page
.getByLabel('Price')
.fill('1000');
await page
.getByRole('button', {
name: 'Save'
})
.click();
await expect(
page.getByText('Laptop')
).toBeVisible();
});This is predictable, repeatable and CI/CD friendly.
47. MCP Adds Another Capability Layer
MCP can enable AI-driven workflows such as exploring an application, understanding an unfamiliar page, investigating a failure, reading engineering context, dynamically selecting tools and coordinating multiple systems.
48. Local vs Remote MCP Server
Our server is local:
CLIENT
│
│ stdio
▼
LOCAL MCP SERVER
But MCP servers can also use network transports:
AI HOST
│
▼
MCP CLIENT
│
│ HTTP
▼
REMOTE MCP SERVER
│
▼
ENTERPRISE SYSTEMFor remote servers, security becomes even more important. The current TypeScript SDK supports stdio for local integrations and Streamable HTTP for remote server scenarios.
49. Security Considerations
Our demo tool is harmless: validate a product price. But imagine tools like delete-user, drop-table, deploy-production or delete-cloud-resource. Those capabilities can be dangerous. A production MCP server should consider:
- Authentication
- Authorization
- Least privilege
- Input validation
- Environment restrictions
- Audit logging
- Secret management
- Human approval
- Tool-specific permissions
50. Good Tool Design
Avoid overly generic tools. Bad: executeAnything. Better: queryQaDatabaseReadOnly. Even better for some use cases: getProductById.
Specific tools are often easier to understand, easier to secure, easier to audit, and easier for AI to select correctly.
51. Never Give Testing Agents Unlimited Production Access
Bad:
AI AGENT
│
▼
MCP SERVER
│
▼
PRODUCTION DATABASE
FULL ADMIN ACCESS
Better:
AI AGENT
│
▼
QA MCP SERVER
│
▼
QA DATABASE
READ ONLY52. What We Learned From the Code
We can now map our implementation directly back to the theory:
- new McpServer(...) — create the server
- server.registerTool(...) — expose an executable capability
- server.registerResource(...) — expose information/context
- server.registerPrompt(...) — expose reusable instructions
- serveStdio(...) — provide MCP communication through standard input/output
- new Client(...) — create an MCP client
- client.connect(...) — connect client and server and perform initialization
53. Full Architecture We Just Built
USER
│
▼
MCP CLIENT APP
│
stdio
│
▼
QA MCP SERVER
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
validate-product- testing- review-
price guidelines requirement
TOOL RESOURCE PROMPTAdd an AI host:
USER
│
▼
AI HOST
│
▼
MODEL
│
▼
MCP CLIENT
│
▼
MCP SERVER
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Tools Resources PromptsThat is MCP in practice.
54. Common Beginner Mistakes
- Mistake 1 — Thinking MCP Server = LLM. Wrong. The MCP server exposes capabilities; the LLM performs reasoning.
- Mistake 2 — Thinking Tool = Prompt. Wrong. Tool = Action; Prompt = Instruction.
- Mistake 3 — Thinking Resource = Tool. Wrong. Resource = Information; Tool = Action.
- Mistake 4 — Giving tools extremely broad permissions, like execute_any_shell_command. Be very careful with generic high-powered tools.
- Mistake 5 — Putting credentials directly into code. Use environment variables, secret stores, CI secrets or enterprise credential systems instead.
55. Interview Question: What is an MCP Server?
56. Interview Question: How do you build an MCP server?
1. Create project
2. Install MCP SDK
3. Create McpServer
4. Register tools
5. Register resources
6. Register prompts
7. Select transport
8. Start server
9. Connect an MCP client
10. Discover and invoke capabilities57. Interview Question: What does stdio do?
58. Interview Question: Does an MCP server need all three: tools, resources, and prompts?
No. A server can expose whatever capabilities are appropriate. For example, a Browser MCP Server would expose mostly Tools, while another server might primarily expose documentation as Resources.
59. Interview Question: Why use schemas for tools?
Schemas describe expected inputs, for example z.object({ productId: z.number() }). They improve validation, reliability, tool discoverability and error handling.
60. What We Built vs What Comes Next
Our current server:
AI
↓
MCP
↓
Simple QA Functions
Next we want:
AI
↓
MCP
↓
PLAYWRIGHT
↓
BROWSER
↓
APPLICATIONThat is where MCP becomes directly connected to your Playwright automation expertise.
61. Learning Progress So Far
MCP Fundamentals
✓
Host / Client / Server
✓
Tools / Resources / Prompts
✓
Build MCP Server
✓
Next:
PLAYWRIGHT MCP62. Final Takeaway
The most important lesson from this tutorial is that an MCP server is not mysterious. At its core:
CREATE SERVER
↓
REGISTER CAPABILITIES
↓
TOOLS
RESOURCES
PROMPTS
↓
SELECT TRANSPORT
↓
CONNECT CLIENT
↓
DISCOVER CAPABILITIES
↓
CALL / READ / USE THEMMCP CLIENT
│
▼
QA MCP SERVER
│
├── validate-product-price
│ TOOL
│
├── qa://testing-guidelines
│ RESOURCE
│
└── review-requirement
PROMPTWhen an AI host is added:
HUMAN
│
▼
AI
│
▼
MCP CLIENT
│
▼
MCP SERVER
│
▼
ENGINEERING CAPABILITIES
And when Playwright is added:
HUMAN
│
▼
AI
│
▼
MCP
│
▼
PLAYWRIGHT MCP SERVER
│
▼
PLAYWRIGHT
│
▼
BROWSER
│
▼
APPLICATIONThat is the bridge between MCP fundamentals and Agentic AI Testing with Playwright.
Complete professional Playwright + TypeScript enterprise framework
Production-grade architecture, fixtures, reporters and CI/CD — ready to run.
Get Playwright tutorials in your inbox
Weekly tips, real-world examples, and framework patterns – no spam, unsubscribe anytime.
Playwright Framework Series
View all →- 1Getting Started with Playwright: Installation, Setup, and Your First Test
- 2Playwright Locators: The Complete Guide with Real-World Examples
- 3Playwright Actions: Complete Guide to Click, Fill, Hover, Keyboard, Mouse & File Upload
- 4Playwright Assertions Complete Guide: Web-First Assertions, Auto-Retry & Custom Matchers
- 5Playwright Auto Waiting: The Complete Guide with Real-World Examples
- 6Playwright Fixtures: The Complete Guide with Real-World Examples
- 7Playwright Browser Context & Multiple Tabs: The Complete Guide with Real-World Examples
- 8Playwright Authentication & Session Management: Complete Guide with Enterprise Examples
- 9Playwright Network Interception & API Mocking: Complete Guide with Real-World Examples
- 10Playwright Page Object Model (POM): The Complete Guide with Enterprise Examples
- 11Page Object Model with Playwright: A Practical Guide
- 12How to Build a Robust Professional Playwright Framework from Scratch (Step-by-Step)
- 13Building an Enterprise Playwright Framework from Scratch
API Testing Series
View all →- 1Part 1 : Playwright API Testing Tutorial: Build Enterprise-Level API Automation Framework
- 2Part 2: Playwright API Testing Tutorial: Setting Up Project & Sending Your First API Request
- 3Part 3: Mastering CRUD Operations in Playwright API Testing
- 4Part 4: Authentication in Playwright API Testing (Bearer Token, JWT, API Key & Reusable Fixtures)
- 5Part 5: Building an Enterprise-Level Playwright API Automation Framework
- 6Part 6: API Models, Schema Validation & Test Data Management in Playwright
- 7Part 7: Custom Fixtures, Hooks, Logging & Parallel Execution in Playwright API Testing
- 8Part 8: Building a Production-Ready Playwright API Framework (Environment Management, CI/CD, Reporting & Best Practices)
- 9Part 9: Advanced Playwright API Testing Techniques for Enterprise Automation
- 10Part 10: Building a Complete Enterprise Playwright API Automation Framework (Final Part)
- 11Playwright Backend Testing Tutorial – REST API, GraphQL, WebSocket, Kafka, Database & Microservices