6eeb8b9087
Wraps the site tool wpb_build_page: build or update a Word Page from {kind, html} sections. The page lands as a native Word Page (payload in post meta, builder-rendered), so it stays editable and undoable in the builder. Also documents the builder tools in the bundled skill and README.
208 lines
7.8 KiB
Python
208 lines
7.8 KiB
Python
"""Tool schemas — what the LLM reads to decide when to call these tools.
|
|
|
|
Deliberately small (8 tools). The WordVibe site exposes ~100 tools over MCP;
|
|
registering all of them would put ~100 schemas on every API call. Everything
|
|
beyond these wrappers is reachable through `wordvibe_call`.
|
|
"""
|
|
|
|
_SITE = {
|
|
"type": "string",
|
|
"description": (
|
|
"Which configured site to use: its name or URL "
|
|
"(e.g. 'mysite' or 'https://mysite.com'). Omit to use the first configured site."
|
|
),
|
|
}
|
|
|
|
BUILD_PAGE = {
|
|
"name": "wordvibe_build_page",
|
|
"description": (
|
|
"Build or update a page in the site's Word Page Builder (WPB) from section HTML. Each "
|
|
"section is wrapped automatically in <section data-wpb-section=\"kind\" data-wpb-id=\"sec-…\">, "
|
|
"so the page opens natively in the builder and stays editable/undoable there. Use this to "
|
|
"publish a landing page, or to rebuild a page's sections, without a browser."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"title": {"type": "string", "description": "Page title."},
|
|
"sections": {
|
|
"type": "array",
|
|
"description": (
|
|
"Ordered list of sections. Each item: {kind, html} — kind is a kebab-case section "
|
|
"name (hero, features, pricing, testimonials, faq, cta, footer, gallery, contact, "
|
|
"about, services, custom); html is the section's inner HTML (inline styles are fine)."
|
|
),
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"kind": {"type": "string", "description": "Section kind, e.g. 'hero'."},
|
|
"html": {"type": "string", "description": "Inner HTML for the section."},
|
|
},
|
|
"required": ["kind", "html"],
|
|
},
|
|
},
|
|
"slug": {"type": "string", "description": "URL slug (optional)."},
|
|
"status": {
|
|
"type": "string",
|
|
"description": "draft, publish, pending or private (default: draft).",
|
|
},
|
|
"post_id": {
|
|
"type": "integer",
|
|
"description": "Existing page ID to update; omit to create a new page.",
|
|
},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["title", "sections"],
|
|
},
|
|
}
|
|
|
|
SITES = {
|
|
"name": "wordvibe_sites",
|
|
"description": (
|
|
"List the WordPress sites this plugin can drive (configured via WORDVIBE_SITE_URL / "
|
|
"WORDVIBE_MCP_SITES). Optionally probes each one to report whether its WordVibe MCP "
|
|
"server is reachable and enabled."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"probe": {
|
|
"type": "boolean",
|
|
"description": "Also connect to each site and report reachability (default false).",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
SITE_INFO = {
|
|
"name": "wordvibe_site_info",
|
|
"description": (
|
|
"Report what a WordVibe site is running: MCP server name/version (the plugin version), "
|
|
"WordPress name/version/URL, active theme, and plugin count. Use this first when you need "
|
|
"to know what you're working with."
|
|
),
|
|
"parameters": {"type": "object", "properties": {"site": _SITE}},
|
|
}
|
|
|
|
TOOLS = {
|
|
"name": "wordvibe_tools",
|
|
"description": (
|
|
"List the tools the WordVibe site exposes over MCP — file read/write/edit, codebase "
|
|
"search, database queries, posts/media, plugin & theme management, WP-CLI, cron, security "
|
|
"scans, and more. Call this when you need a capability that isn't covered by the "
|
|
"wordvibe_read_file / wordvibe_write_file / wordvibe_edit_file / wordvibe_search wrappers, "
|
|
"then invoke it with wordvibe_call."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"site": _SITE,
|
|
"filter": {
|
|
"type": "string",
|
|
"description": "Optional case-insensitive substring to filter tool names/descriptions.",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
CALL = {
|
|
"name": "wordvibe_call",
|
|
"description": (
|
|
"Call any tool on the WordVibe site by name (see wordvibe_tools for the catalogue). "
|
|
"This is the escape hatch for everything without a dedicated wrapper — e.g. post_list, "
|
|
"plugin_list, db_query (SELECT only), cli_exec, security_scan_installed, list_directory, "
|
|
"file_search, create_post. Arguments are passed through to the site tool as-is."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"tool": {"type": "string", "description": "Site tool name, e.g. 'post_list'."},
|
|
"arguments": {
|
|
"type": "object",
|
|
"description": "Arguments for the site tool (its own parameter names).",
|
|
},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["tool"],
|
|
},
|
|
}
|
|
|
|
READ_FILE = {
|
|
"name": "wordvibe_read_file",
|
|
"description": (
|
|
"Read a file from a WordVibe site (any path inside the WordPress install, e.g. "
|
|
"'wp-content/themes/my-theme/functions.php' or 'wp-config.php'). Always read a file "
|
|
"before writing or editing it."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {"type": "string", "description": "Path relative to the WordPress root."},
|
|
"lines": {
|
|
"type": "string",
|
|
"description": "Optional line range, e.g. '1-80' or '120-160'. Omit for the whole file.",
|
|
},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["path"],
|
|
},
|
|
}
|
|
|
|
WRITE_FILE = {
|
|
"name": "wordvibe_write_file",
|
|
"description": (
|
|
"Write (overwrite) a file on a WordVibe site. The site takes a safety snapshot of the "
|
|
"previous version before saving, so a rollback is always possible. Read the file first."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {"type": "string", "description": "Path relative to the WordPress root."},
|
|
"content": {"type": "string", "description": "Full new file content."},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["path", "content"],
|
|
},
|
|
}
|
|
|
|
EDIT_FILE = {
|
|
"name": "wordvibe_edit_file",
|
|
"description": (
|
|
"Make a targeted edit on a WordVibe site: replace the first exact occurrence of `search` "
|
|
"with `replace`. Preferred over wordvibe_write_file for small changes — it can't clobber "
|
|
"the rest of the file."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"path": {"type": "string", "description": "Path relative to the WordPress root."},
|
|
"search": {"type": "string", "description": "Exact text to find."},
|
|
"replace": {"type": "string", "description": "Replacement text."},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["path", "search", "replace"],
|
|
},
|
|
}
|
|
|
|
SEARCH = {
|
|
"name": "wordvibe_search",
|
|
"description": (
|
|
"Search a WordVibe site's codebase (themes, plugins, mu-plugins, core) and return matching "
|
|
"lines with context. Supports plain text or regex, scoped to a path and/or file pattern."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "Text or regex to search for."},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Optional subdirectory, e.g. 'wp-content/plugins/my-plugin'.",
|
|
},
|
|
"include": {"type": "string", "description": "Optional file glob, e.g. '*.php'."},
|
|
"regex": {"type": "boolean", "description": "Treat `query` as a regular expression."},
|
|
"site": _SITE,
|
|
},
|
|
"required": ["query"],
|
|
},
|
|
}
|