Content
# WordPress Malware Cleanup MCP Server
[](https://opensource.org/licenses/MIT)
[](https://modelcontextprotocol.io)
[](https://wordpress.org)
A production-ready Model Context Protocol (MCP) server for cleaning malware from WordPress sites via SSH and WP-CLI. Designed for agencies and developers managing multiple WordPress installations.
**Author:** Varun Dubey
**Company:** [Wbcom Designs](https://wbcomdesigns.com)
**Version:** 1.0.0
---
## Table of Contents
- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Available Tools](#available-tools)
- [Usage Examples](#usage-examples)
- [Cleanup Workflow](#cleanup-workflow)
- [Security Considerations](#security-considerations)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [License](#license)
- [Credits](#credits)
---
## Features
### Multi-Site Management
- Add and manage 20+ WordPress sites from a single interface
- Persistent configuration storage
- Batch operations across all sites
- Status tracking and reporting
### Comprehensive Malware Scanning
- **Core File Verification** - Compare against official WordPress checksums
- **Plugin Integrity Check** - Verify plugins against WordPress.org
- **MU-Plugins Detection** - Scan must-use plugins for backdoors
- **Uploads Security** - Find PHP files that shouldn't exist
- **Deep Pattern Matching** - Detect obfuscated code and known signatures
- **Database Injection Scan** - Find malicious content in posts/options
- **Recently Modified Files** - Identify infection timeline
### User Security
- List and audit administrator accounts
- Track user activity before deletion
- Find recently created suspicious users
- Safe user deletion with content reassignment
### Safe Cleanup Operations
- **Quarantine System** - Move files instead of deleting (allows recovery)
- **Automatic Backups** - Database export before changes
- **Core Reinstallation** - Restore official WordPress files
- **Plugin Reinstallation** - Fresh install from repository
- **Permission Fixes** - Set secure file permissions
### Security Hardening
- Reset all admin passwords
- Regenerate security salts
- Disable admin file editing
- Add .htaccess security rules
- Update WordPress, plugins, and themes
### Reporting & Logging
- Detailed cleanup reports
- Action logging per site
- Export configurations
- Status summaries
---
## Requirements
### Your Mac (Client)
- macOS 13+ (Ventura or later)
- [Homebrew](https://brew.sh)
- [Claude Code](https://claude.com/claude-code) CLI
- [uv](https://docs.astral.sh/uv/) (Python package manager)
### WordPress Servers
- SSH access (password or key-based)
- WP-CLI installed and in PATH
- WordPress 5.0+
---
## macOS Setup Guide
Complete setup from scratch on a fresh Mac. Takes ~5 minutes.
### Prerequisites
- [Homebrew](https://brew.sh) installed
- [Claude Code](https://claude.com/claude-code) CLI installed
- [uv](https://docs.astral.sh/uv/) installed (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
### Step 1: Install System Dependencies
```bash
# Python 3.12 (macOS system Python is too old for the mcp package)
brew install python@3.12
# sshpass (required for password-based SSH auth)
brew install sshpass
```
### Step 2: Clone the Repository
```bash
git clone https://github.com/vapvarun/wp-malware-cleanup-mcp.git ~/.claude/wp-malware-cleanup-mcp
cd ~/.claude/wp-malware-cleanup-mcp
```
### Step 3: Create Virtual Environment & Install Dependencies
```bash
# Create venv with Python 3.12
uv venv --python 3.12 .venv
# Install dependencies into venv
uv pip install -r requirements.txt
```
### Step 4: Register MCP Server with Claude Code
```bash
# Register globally (available in all Claude Code sessions)
claude mcp add -s user wp-malware-cleanup -- \
~/.claude/wp-malware-cleanup-mcp/.venv/bin/python \
~/.claude/wp-malware-cleanup-mcp/server.py
```
### Step 5: Verify
```bash
claude mcp list
# Should show: wp-malware-cleanup: ... ✓ Connected
```
### Step 6: Restart Claude Code
Close and reopen Claude Code so the new MCP tools are loaded.
---
## Configuration
### Claude Code (Recommended)
The `claude mcp add` command in Step 4 automatically writes to `~/.claude.json`:
```json
{
"mcpServers": {
"wp-malware-cleanup": {
"command": "/Users/YOU/.claude/wp-malware-cleanup-mcp/.venv/bin/python",
"args": ["/Users/YOU/.claude/wp-malware-cleanup-mcp/server.py"]
}
}
}
```
### Claude Desktop (Optional)
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"wp-malware-cleanup": {
"command": "/Users/YOU/.claude/wp-malware-cleanup-mcp/.venv/bin/python",
"args": ["/Users/YOU/.claude/wp-malware-cleanup-mcp/server.py"]
}
}
}
```
> **Note:** Replace `/Users/YOU` with your actual home directory path.
### Data Storage Locations
The server stores data in `~/.wp-malware-cleanup/`:
```
~/.wp-malware-cleanup/
├── sites.json # Site configurations
├── quarantine/ # Quarantined malicious files
├── reports/ # Generated cleanup reports
└── logs/ # Per-site action logs
```
---
## Quick Start
After setup, restart Claude Code and use these tools in conversation:
### 1. Add Your First Site
**With password auth** (common for InstaWP, managed hosting):
```
wp_add_site(
name="my-site",
host="147.182.198.163",
username="sshuser",
wp_path="/home/sshuser/web/example.com",
auth_type="password",
site_url="https://example.com"
)
```
**With SSH key auth** (recommended for production):
```
wp_add_site(
name="client-blog",
host="example.com",
username="deploy",
wp_path="/var/www/html",
auth_type="key",
key_path="~/.ssh/id_rsa"
)
```
### 2. Test the Connection
```
# Password auth - provide password each time (not stored on disk for security)
wp_test_connection("my-site", password="your-ssh-password")
# Key auth - no password needed
wp_test_connection("client-blog")
```
> **Security note:** Passwords are never stored on disk. They are passed via the `SSHPASS` environment variable at runtime and discarded after the SSH session ends.
### 3. Run a Full Scan
```
wp_full_scan("my-site", password="your-ssh-password")
```
### 4. View All Sites
```
wp_list_sites()
```
---
## Available Tools
### Site Management
| Tool | Description |
|------|-------------|
| `wp_add_site` | Add a new WordPress site |
| `wp_update_site` | Update site configuration |
| `wp_get_site` | Get detailed site information |
| `wp_list_sites` | List all sites with status |
| `wp_remove_site` | Remove a site from configuration |
| `wp_test_connection` | Test SSH and WP-CLI connectivity |
### Scanning Tools
| Tool | Description |
|------|-------------|
| `wp_verify_core` | Verify WordPress core file integrity |
| `wp_verify_plugins` | Check plugins against WordPress.org |
| `wp_scan_suspicious_plugins` | **NEW** Detect plugins with random/malware-like folder names |
| `wp_scan_hidden_admins` | **NEW** Find suspicious admin accounts (typosquatted emails, recent creation) |
| `wp_scan_app_passwords` | **NEW** Detect suspicious WordPress application passwords |
| `wp_scan_webshells` | **NEW** Detect file manager backdoors and web shells |
| `wp_scan_mu_plugins` | Scan must-use plugins for malware |
| `wp_scan_uploads` | Find dangerous files in uploads |
| `wp_scan_malware_patterns` | Deep scan for malware signatures |
| `wp_scan_recently_modified` | Find files changed in last N days |
| `wp_full_scan` | Run all scans comprehensively |
| `wp_full_scan_verbose` | **NEW** Full scan with detailed command-by-command output |
### User Audit Tools
| Tool | Description |
|------|-------------|
| `wp_list_admins` | List all administrator users |
| `wp_audit_user` | Detailed audit of user activity |
| `wp_find_recent_users` | Find users created recently |
| `wp_delete_user` | Delete user after audit |
### Cleanup Tools
| Tool | Description |
|------|-------------|
| `wp_complete_cleanup` | **NEW** Full cleanup + hardening in one command |
| `wp_quarantine_file` | Move malicious file to quarantine |
| `wp_read_file` | Read file contents for analysis |
| `wp_remove_mu_plugin` | Quarantine an mu-plugin |
| `wp_reinstall_core` | Reinstall WordPress core files |
| `wp_reinstall_plugin` | Reinstall a plugin from repo |
| `wp_clean_uploads_php` | Remove all PHP from uploads |
| `wp_fix_permissions` | Fix file/directory permissions |
### Security Hardening
| Tool | Description |
|------|-------------|
| `wp_reset_passwords` | Reset all admin passwords |
| `wp_regenerate_salts` | Regenerate security salts |
| `wp_disable_file_editing` | Disable theme/plugin editor |
| `wp_harden_wpconfig` | **NEW** Apply security constants to wp-config.php |
| `wp_install_security_mu_plugin` | **NEW** Install persistent security MU-plugin |
| `wp_full_harden` | **NEW** Complete hardening in one command |
| `wp_update_all` | Update core, plugins, themes |
| `wp_add_security_htaccess` | Add security rules to .htaccess |
### Database Tools
| Tool | Description |
|------|-------------|
| `wp_check_db_injections` | Scan database for malware |
| `wp_backup_database` | Create database backup |
| `wp_clean_db_spam` | Remove spam comments |
### Batch Operations
| Tool | Description |
|------|-------------|
| `wp_batch_scan` | Scan all configured sites |
| `wp_batch_update` | Update all clean sites |
### Reporting
| Tool | Description |
|------|-------------|
| `wp_generate_report` | Generate detailed cleanup report |
| `wp_generate_case_study` | **NEW** Generate anonymized case study for public sharing |
| `wp_export_sites` | Export site configurations |
| `wp_version` | Show version information |
### Case Studies
Anonymized malware case studies are available in [`docs/case-studies/`](docs/case-studies/). These document real-world infections with:
- Detection signatures and IOCs
- Code analysis and behavior
- Remediation steps
- Lessons learned
### Threat Intelligence Database
| Tool | Description |
|------|-------------|
| `wp_threat_db_stats` | Show database statistics (signatures, detections) |
| `wp_threat_db_sync` | Sync with GitHub community signatures |
| `wp_threat_add_signature` | Add new malware signature to local database |
| `wp_threat_learn_from_cleanup` | Learn malware hash from cleanup for future detection |
| `wp_threat_check_file` | Check specific file against threat database |
| `wp_threat_export` | Export signatures for GitHub contribution |
| `wp_threat_top_signatures` | Show most frequently detected signatures |
| `wp_threat_report` | Generate threat intelligence report |
---
## Usage Examples
### Adding Multiple Sites
```python
# Site with SSH key
wp_add_site(
name="site1",
host="server1.example.com",
username="deploy",
wp_path="/var/www/site1",
auth_type="key",
key_path="~/.ssh/id_rsa"
)
# Site with different port
wp_add_site(
name="site2",
host="server2.example.com",
port=2222,
username="admin",
wp_path="/home/admin/public_html",
auth_type="key",
key_path="~/.ssh/server2_key"
)
```
### Batch Scanning All Sites
```python
# Scan all sites
wp_batch_scan()
# Scan only pending sites
wp_batch_scan(status_filter="pending")
```
### Complete Cleanup Workflow
```python
# 1. Backup first!
wp_backup_database("infected-site")
# 2. Run full scan
wp_full_scan("infected-site")
# 3. Audit suspicious users
wp_list_admins("infected-site")
wp_audit_user("infected-site", "suspicious_user")
# 4. Delete malicious user
wp_delete_user("infected-site", "suspicious_user", "real_admin", confirm=True)
# 5. Clean malicious files
wp_clean_uploads_php("infected-site", confirm=True)
wp_remove_mu_plugin("infected-site", "malware.php")
# 6. Reinstall core and plugins
wp_reinstall_core("infected-site")
# 7. Harden security
wp_reset_passwords("infected-site")
wp_regenerate_salts("infected-site")
wp_disable_file_editing("infected-site")
wp_add_security_htaccess("infected-site")
# 8. Update everything
wp_update_all("infected-site")
# 9. Verify cleanup
wp_full_scan("infected-site")
# 10. Generate report
wp_generate_report("infected-site")
```
---
## Cleanup Workflow
### Phase 1: Assessment
1. **Backup Database**
```
wp_backup_database("site-name")
```
2. **Run Full Scan**
```
wp_full_scan("site-name")
```
3. **Check Recently Modified Files**
```
wp_scan_recently_modified("site-name", days=14)
```
### Phase 2: User Audit
1. **List Admin Users**
```
wp_list_admins("site-name")
```
2. **Find Recent Users**
```
wp_find_recent_users("site-name", days=30)
```
3. **Audit Suspicious Users**
```
wp_audit_user("site-name", "suspicious_username")
```
4. **Delete Malicious Users**
```
wp_delete_user("site-name", "hacker", "legitimate_admin", confirm=True)
```
### Phase 3: File Cleanup
1. **Clean Uploads Directory**
```
wp_clean_uploads_php("site-name", confirm=True)
```
2. **Remove Malicious MU-Plugins**
```
wp_scan_mu_plugins("site-name")
wp_remove_mu_plugin("site-name", "malware.php")
```
3. **Quarantine Suspicious Files**
```
wp_quarantine_file("site-name", "/full/path/to/file.php")
```
### Phase 4: Core Restoration
1. **Reinstall WordPress Core**
```
wp_reinstall_core("site-name")
```
2. **Verify Core Files**
```
wp_verify_core("site-name")
```
3. **Reinstall Affected Plugins**
```
wp_reinstall_plugin("site-name", "plugin-slug")
```
### Phase 5: Security Hardening
1. **Reset All Passwords**
```
wp_reset_passwords("site-name")
```
> ⚠️ Save the new passwords securely!
2. **Regenerate Salts**
```
wp_regenerate_salts("site-name")
```
3. **Disable File Editing**
```
wp_disable_file_editing("site-name")
```
4. **Add Security Rules**
```
wp_add_security_htaccess("site-name")
```
5. **Fix Permissions**
```
wp_fix_permissions("site-name")
```
### Phase 6: Updates & Verification
1. **Update Everything**
```
wp_update_all("site-name")
```
2. **Final Verification Scan**
```
wp_full_scan("site-name")
```
3. **Generate Report**
```
wp_generate_report("site-name")
```
---
## Security Considerations
### SSH Key Authentication (Recommended)
Always use SSH keys instead of passwords:
```bash
# Generate SSH key
ssh-keygen -t ed25519 -C "malware-cleanup"
# Copy to server
ssh-copy-id -i ~/.ssh/id_ed25519 user@server
```
### Data Storage Security
- Site configurations are stored locally in `~/.wp-malware-cleanup/`
- **Passwords are NEVER stored** - provide them at runtime
- Quarantined files are kept on the remote server
- Reports may contain sensitive information - store securely
### Principle of Least Privilege
- Use a dedicated SSH user for cleanup operations
- Grant only necessary permissions
- Consider using sudo for specific WP-CLI commands
### Audit Trail
All actions are logged to `~/.wp-malware-cleanup/logs/{site-name}.log`
---
## Troubleshooting
### "Connection refused" or "Connection timed out"
1. Verify the hostname and port are correct
2. Check if SSH is running on the server
3. Verify firewall allows SSH connections
4. Test manually: `ssh -p PORT user@host`
### "WP-CLI not found"
Install WP-CLI on the WordPress server:
```bash
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
```
### "Permission denied"
1. Check SSH key permissions: `chmod 600 ~/.ssh/id_rsa`
2. Verify the user has access to the WordPress directory
3. Check if the user can run WP-CLI: `wp --info`
### "sshpass not found"
If using password authentication:
- Ubuntu/Debian: `sudo apt install sshpass`
- macOS: `brew install hudochenkov/sshpass/sshpass`
- **Recommended:** Use SSH keys instead
### Command Timeout
For large sites, increase the timeout:
- Database exports may take longer
- Full scans on large sites need more time
- Consider running scans during low-traffic periods
### False Positives in Malware Scan
Some legitimate code may trigger false positives:
- Base64 encoding in plugins (e.g., for image handling)
- Minified JavaScript
- Vendor libraries
Review each finding manually before taking action.
---
## Community Threat Intelligence Database
This project includes a community-driven threat intelligence database that grows with contributions from the WordPress security community.
### How It Works
1. **Local Learning**: When you clean malware, the tool can learn the file hashes and patterns
2. **GitHub Sync**: Sync your local database with the community repository
3. **Contribute Back**: Export your discoveries and submit a pull request
### Syncing with Community Database
```python
# Sync latest signatures from GitHub
wp_threat_db_sync()
# Check current database stats
wp_threat_db_stats()
# After confirming malware, teach the system
wp_threat_learn_from_cleanup("/path/to/malware.php", "abc123hash", "backdoor", "Description")
# Export for contribution
wp_threat_export()
```
### Community Files
| File | Description |
|------|-------------|
| `community-signatures.json` | Malware detection patterns (50+ signatures) |
| `community-hashes.json` | Known malicious file hashes |
### Security Features
- **Secure Random Filenames**: All backup files, reports, and quarantine directories use cryptographically secure random names to prevent attackers from guessing file locations
- **Restricted Permissions**: Quarantine and backup directories are created with 700 permissions
- **No Predictable Paths**: File naming uses SHA256-based random tokens
---
## Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
### Contributing Signatures
To contribute malware signatures:
1. Use `wp_threat_export()` to export your local signatures
2. Fork this repository
3. Add your signatures to `community-signatures.json` or `community-hashes.json`
4. Submit a pull request with a description of what malware the signatures detect
**Guidelines:**
- Only submit confirmed malware signatures
- Include clear descriptions
- Test for false positives before submitting
- Do not include sensitive information
### Development Setup
```bash
git clone https://github.com/vapvarun/wp-malware-cleanup-mcp.git
cd wp-malware-cleanup-mcp
pip install -e .
```
### Running Tests
```bash
python -m pytest tests/
```
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## Credits
**Author:** Varun Dubey
**Company:** [Wbcom Designs](https://wbcomdesigns.com)
### Built With
- [Model Context Protocol (MCP)](https://modelcontextprotocol.io) - Protocol for LLM integrations
- [WP-CLI](https://wp-cli.org) - Command-line interface for WordPress
- [FastMCP](https://github.com/jlowin/fastmcp) - Python MCP server framework
### Acknowledgments
- WordPress Security Team for security best practices
- The WP-CLI community for the excellent command-line tool
- Anthropic for the Model Context Protocol specification
---
## Support
For support, questions, or custom development:
- **Website:** [https://wbcomdesigns.com](https://wbcomdesigns.com)
- **GitHub Issues:** [Report a bug](https://github.com/vapvarun/wp-malware-cleanup-mcp/issues)
---
## Changelog
### Version 1.0.0 (2024)
- Initial release
- Multi-site management
- Comprehensive malware scanning
- User audit capabilities
- Safe cleanup operations
- Security hardening tools
- Batch operations
- Detailed reporting
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
firecrawl
Firecrawl MCP Server enables web scraping, crawling, and content extraction.
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
Sequential Thinking
A structured MCP server for dynamic problem-solving and reflective thinking.