A Model Context Protocol (MCP) server that provides intelligent web browsing capabilities with automatic content filtering and cleaning. This server acts as a proxy between AI clients and web content, applying site-specific CSS rules to remove unwanted elements like advertisements, sidebars, and other clutter.
- Intelligent Web Navigation: Navigate to any URL with automatic content filtering
- Site-Specific CSS Rules: Custom CSS rules for different websites to clean up content
- MCP Integration: Full Model Context Protocol support for AI client integration
- NestJS Architecture: Built with NestJS for robust, scalable server architecture
- Streamable HTTP Transport: Modern MCP transport for efficient communication
- Automatic Content Cleaning: Remove ads, sidebars, and other unwanted elements
- Configurable CSS Rules: Easy to add new site-specific filtering rules
This MCP server acts as a bridge between AI clients and web content by:
- Receiving navigation requests from AI clients via MCP
- Connecting to a Playwright MCP server for actual web browsing
- Applying site-specific CSS rules to clean up the content
- Returning cleaned snapshots to the AI client
- BrowserTool: Main MCP tool that handles navigation and content filtering
- CSSConfigService: Manages site-specific CSS rules and JavaScript generation
- MCP Module: NestJS module that exposes tools via Model Context Protocol
- Node.js 18+
- A running Playwright MCP server (for actual web browsing)
- npm or yarn
-
Clone the repository
git clone https://github.com/isachivka/playwright-filter.git cd playwright-filter -
Install dependencies
npm install
-
Configure environment
cp .env.example .env # Edit .env with your configuration
Create a .env file with the following variables:
# Playwright MCP Server URL
PLAYWRIGHT_MCP_URL=http://192.168.1.10:8931
# Server Configuration
PORT=3000The server uses site-specific CSS and JavaScript rules to clean up web content. Rules are stored in two directories:
css-rules/default.css- Default CSS rules applied to all sitescss-rules/{domain}.css- Site-specific CSS rules (e.g.,rutracker.org.css)
js-rules/default.js- Default JavaScript rules applied to all sitesjs-rules/{domain}.js- Site-specific JavaScript rules (e.g.,rutracker.org.js)
-
CSS Rules: Create a new CSS file in
css-rules/with the domain name:touch css-rules/example.com.css
-
JavaScript Rules: Create a new JS file in
js-rules/with the domain name:touch js-rules/example.com.js
-
Add CSS rules to hide unwanted elements:
.advertisement, .ads, .sidebar, .footer { display: none !important; }
-
Add JavaScript rules for advanced manipulation:
// Remove specific elements document.querySelectorAll('.unwanted').forEach(el => el.remove()); // Modify page content const title = document.querySelector('h1'); if (title) title.textContent = 'Cleaned Title';
-
The server will automatically detect and apply both CSS and JavaScript rules when navigating to that domain.
# Start in development mode
npm run start:dev
# Build the project
npm run build
# Start production server
npm run start:prodThe server exposes the following MCP tools:
Navigate to a URL and return a cleaned snapshot of the page with automatic CSS filtering applied.
Parameters:
url(string, required): The URL to navigate to
Example:
{
"name": "browser_navigate",
"arguments": {
"url": "https://rutracker.org/forum/viewtopic.php?t=123456"
}
}Response: Returns a JSON snapshot of the cleaned page content with unwanted elements removed.
Close the current browser page.
Parameters:
- None
Example:
{
"name": "browser_close",
"arguments": {}
}Fill multiple form fields on the current page.
Parameters:
fields(array, required): Array of form fields to fill
Example:
{
"name": "browser_fill_form",
"arguments": {
"fields": [
{
"name": "Username",
"type": "textbox",
"ref": "input[name='username']",
"value": "myusername"
},
{
"name": "Remember me",
"type": "checkbox",
"ref": "input[type='checkbox']",
"value": "true"
}
]
}
}Perform a click action on a web page element.
Parameters:
element(string, required): Human-readable element descriptionref(string, required): Exact target element reference from page snapshotdoubleClick(boolean, optional): Whether to perform double clickbutton(string, optional): Button to click (left, right, middle)modifiers(array, optional): Modifier keys to press
Example:
{
"name": "browser_click",
"arguments": {
"element": "Login button",
"ref": "button[type='submit']",
"button": "left"
}
}Evaluate JavaScript expression on page or element.
Parameters:
function(string, required): JavaScript function to executeelement(string, optional): Human-readable element descriptionref(string, optional): Exact target element reference from page snapshot
Example:
{
"name": "browser_evaluate",
"arguments": {
"function": "() => { return document.title; }"
}
}Example with element:
{
"name": "browser_evaluate",
"arguments": {
"function": "(element) => { return element.textContent; }",
"element": "Main heading",
"ref": "h1"
}
}You can test the server using the MCP Inspector:
npm run inspectorplaywright-filter/
├── src/
│ ├── config/ # Configuration services
│ │ ├── css-config.service.ts
│ │ └── config.module.ts
│ ├── mcp/ # MCP server implementation
│ │ ├── browser.tool.ts # Main browser tool
│ │ └── mcp.module.ts # MCP module configuration
│ ├── app.module.ts # Main application module
│ └── main.ts # Application entry point
├── css-rules/ # Site-specific CSS rules
│ ├── default.css # Default cleaning rules
│ └── rutracker.org.css # RuTracker-specific rules
├── docs/ # Documentation
├── dist/ # Compiled JavaScript
└── package.json
npm run start- Start the applicationnpm run start:dev- Start in development mode with hot reloadnpm run start:debug- Start in debug modenpm run build- Build the applicationnpm run test- Run testsnpm run lint- Run ESLintnpm run format- Format code with Prettiernpm run inspector- Start MCP Inspector for testing
- Identify the domain you want to clean
- Create a CSS file:
css-rules/{domain}.css - Add CSS selectors to hide unwanted elements
- Test with the MCP Inspector
/* Hide common unwanted elements */
.advertisement,
.ads,
.sidebar,
.footer,
.header {
display: none !important;
}
/* Site-specific elements */
#sidebar1,
#main-nav,
#logo {
display: none !important;
}The project includes Docker configuration for easy deployment:
# Build Docker image
docker build -t playwright-filter .
# Run with Docker Compose
docker-compose up- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Make your changes
- Add tests if applicable
- Commit your changes:
git commit -m 'Add new feature' - Push to the branch:
git push origin feature/new-feature - Submit a pull request
This project is licensed under the UNLICENSED license - see the package.json file for details.
- Model Context Protocol - The protocol this server implements
- NestJS MCP Module - The NestJS module used for MCP integration
- Playwright - The underlying browser automation tool
For support and questions:
- Create an issue on GitHub
- Check the documentation in the
docs/directory - Review the MCP specification for protocol details
Note: This server requires a separate Playwright MCP server to function. Make sure you have a compatible Playwright MCP server running and accessible via the configured URL.