Usage Guide
This guide walks through the complete workflow for building WordPress plugins with the WPZylos MCP server -- from pointing at an existing plugin to scaffolding a brand-new one, adding features, and validating the result.
Setting Up a Project
Before you can inspect or modify a plugin, tell the MCP server where it lives:
set_project_target({ path: "D:/plugins/my-awesome-plugin" })
Once set, the server automatically reads the plugin directory and builds an in-memory map of:
- The entry file and bootstrap callable
- Registered service providers
- Models, controllers, middleware, and routes
- Config files and composer metadata
All subsequent tool calls operate against this active project. You can switch projects at any time by calling set_project_target again.
Creating a New Plugin
Step 1 -- Scaffold
Call scaffold_plugin with the required identifiers:
{
"name": "My Awesome Plugin",
"slug": "my-awesome-plugin",
"namespace": "MyVendor\\MyAwesomePlugin",
"prefix": "map_",
"textDomain": "my-awesome-plugin"
}
Step 2 -- Understand what was generated
The scaffolder creates a complete, boot-ready plugin:
| File / Directory | Purpose |
|---|---|
my-awesome-plugin.php | Entry file with plugin header |
bootstrap.php | Callable bootstrap -- returns the app instance |
src/PluginContext.php | Factory that wires everything together |
src/Lifecycle.php | Static activation / deactivation hooks |
config/app.php | Provider registration and plugin metadata |
routes/admin.php | Admin route definitions |
routes/ajax.php | AJAX route definitions |
composer.json | Autoloading and framework dependency |
Step 3 -- Recognise the patterns
Three patterns appear in every generated plugin:
PluginContext as factory
$app = PluginContext::create([
'plugin_file' => __FILE__,
'prefix' => 'map_',
'text_domain' => 'my-awesome-plugin',
]);
Callable bootstrap
The bootstrap file returns a closure or invokable that the entry file calls. This keeps the entry file thin and testable.
Static lifecycle
Lifecycle::activate() and Lifecycle::deactivate() are static methods registered via register_activation_hook / register_deactivation_hook. They handle table creation, option seeding, and cleanup without instantiating the full container.
Adding Features
Finding the right package
Not sure which framework package provides what you need? Ask:
recommend_package({ feature: "rest api" })
The server searches the package registry and returns matching packages with descriptions, classes, and typical use cases.
Scaffold a CRUD module
For database-backed features with a model, migration, controller, and views:
scaffold_crud_module({
"name": "Invoice",
"fields": [
{ "name": "number", "type": "string" },
{ "name": "amount", "type": "decimal" },
{ "name": "status", "type": "string", "default": "draft" }
],
"hasRest": true,
"hasViews": true
})
This generates:
app/Models/Invoice.php-- Eloquent-style modeldatabase/migrations/create_invoices_table.php-- Migrationapp/Http/Controllers/InvoiceController.php-- CRUD controllerresources/views/invoices/-- Blade-style view templatesapp/Providers/InvoiceServiceProvider.php-- Auto-registered provider- Route entries in
routes/admin.php
Scaffold a REST module
For API-only endpoints:
scaffold_rest_module({ name: "Invoice", methods: ["index", "show", "store", "update", "delete"] })
Scaffold a settings page
For admin settings with sections and fields:
scaffold_settings_page({
"name": "General",
"sections": [
{
"id": "api_settings",
"title": "API Configuration",
"fields": [
{ "name": "api_key", "type": "text", "label": "API Key" },
{ "name": "sandbox_mode", "type": "checkbox", "label": "Enable Sandbox" }
]
}
],
"capability": "manage_options"
})
Scaffold a custom post type
scaffold_cpt_module({
"name": "Portfolio",
"slug": "portfolio",
"supports": ["title", "editor", "thumbnail"],
"hasMetaBox": true
})
Individual generators
When you only need a single file, use the generate_* shortcuts:
generate_provider-- Service providergenerate_model-- Model classgenerate_controller-- Controller classgenerate_middleware-- Middleware classgenerate_from_stub-- Any registered stub template
Building from Blueprint
For a complete plugin in one shot, prepare a blueprint specification and call:
build_from_blueprint({
"spec": {
"plugin": {
"name": "My Awesome Plugin",
"slug": "my-awesome-plugin",
"namespace": "MyVendor\\MyAwesomePlugin",
"prefix": "map_",
"textDomain": "my-awesome-plugin"
},
"models": [
{
"name": "Contact",
"fields": [
{ "name": "name", "type": "string" },
{ "name": "email", "type": "string" },
{ "name": "message", "type": "text" }
]
}
],
"controllers": ["ContactController"],
"routes": {
"admin": ["/contacts"],
"rest": ["/contacts"]
},
"settings": {
"sections": ["general", "notifications"]
}
}
})
The server processes the entire spec, scaffolds the plugin, and generates all models, controllers, routes, providers, and config in a single pass.
Validation and Audit
Convention compliance
validate_conventions({ path: "D:/plugins/my-awesome-plugin" })
Checks naming conventions, directory structure, provider registration, namespace consistency, and config format against framework standards.
Security audit
validate_security({ path: "D:/plugins/my-awesome-plugin" })
Scans for common issues: missing nonce verification, unescaped output, direct file access without ABSPATH checks, raw SQL without $wpdb->prepare(), and capability checks on admin actions.
Comprehensive review
Use the audit_plugin prompt for a full review that combines convention checks, security analysis, performance patterns, and architectural recommendations:
audit_plugin({ path: "D:/plugins/my-awesome-plugin", area: "all" })
Tips for Prompting
When working with an AI agent that has access to this MCP server, the way you describe your request matters.
Be specific about structure
Good:
"Create a CRUD module called Booking with fields: guest_name (string), check_in (date), check_out (date), room_id (integer). Include REST endpoints and admin views."
Less effective:
"Add a booking system."
Name the tool when you know it
If you know which tool to use, say so:
"Use scaffold_crud_module to create a Subscription model with fields: plan (string), status (string), expires_at (datetime)."
Use the recommend step
When you are unsure which package handles a feature, start with:
"What package should I use for handling custom database tables?"
The agent will call recommend_package and give you an informed answer before scaffolding.
Combine tools in sequence
A typical feature-building session:
recommend_package-- find the right packageinspect_package-- understand its APIscaffold_*orgenerate_*-- build the featurevalidate_conventions-- confirm correctness
When to use prompts vs tools
| Scenario | Use |
|---|---|
| Generate a complete plugin from scratch | Prompt: create_plugin |
| Add one model or controller | Tool: generate_model / generate_controller |
| Full CRUD feature with migration + routes | Tool: scaffold_crud_module |
| Review an existing plugin | Prompt: audit_plugin |
| Migrate a legacy plugin to the framework | Prompt: migrate_plugin |
| Quick code search | Tool: search_framework or find_pattern |
Next Steps
- API Reference -- Full list of tools, resources, and prompts
- Examples -- Real-world plugin workflows