Skip to content

refactor: migrate legacy tools to inputSchema format#170

Merged
docdyhr merged 1 commit intomainfrom
refactor/tool-input-schema
Mar 15, 2026
Merged

refactor: migrate legacy tools to inputSchema format#170
docdyhr merged 1 commit intomainfrom
refactor/tool-input-schema

Conversation

@docdyhr
Copy link
Owner

@docdyhr docdyhr commented Mar 15, 2026

Summary

  • Convert 7 tool modules (auth, comments, media, pages, site, taxonomies, users) from legacy parameters array format to standard inputSchema JSON Schema format
  • Aligns all tools with the pattern already used by posts and SEO modules
  • Update 13 test files to assert on inputSchema instead of parameters

Details

The MCP SDK uses JSON Schema (inputSchema) for tool parameter definitions. The posts and SEO tools already used this format, but the remaining 7 tool modules still used a legacy parameters array format that required conversion in ToolRegistry.buildParameterSchema(). This PR eliminates that inconsistency.

The ToolRegistry still supports both formats for backward compatibility (cache and performance tools remain on the old format for now).

Test plan

  • All 2095 tests pass across 68 test files (4 batches)
  • Build compiles cleanly
  • Pre-commit hooks pass (lint, typecheck, security tests)

🤖 Generated with Claude Code

Summary by Sourcery

Migrate remaining WordPress tool modules from the legacy parameters array to the unified inputSchema JSON Schema format and update tests accordingly.

Enhancements:

  • Standardize auth, comments, media, pages, site, taxonomies, and users tools to expose parameter definitions via inputSchema objects instead of parameters arrays.
  • Define explicit JSON Schema properties and required fields for each tool’s inputs to align with the MCP SDK and existing posts/SEO tools.

Tests:

  • Update tool-related unit tests and validation tests to assert against inputSchema structures, properties, enums, and required fields rather than parameters arrays.

Copilot AI review requested due to automatic review settings March 15, 2026 23:11
@sourcery-ai
Copy link

sourcery-ai bot commented Mar 15, 2026

Reviewer's Guide

Refactors the WordPress MCP tools so that auth, comments, media, pages, site, taxonomies, and users tools expose parameters via a JSON Schema-based inputSchema field instead of a legacy parameters array, and updates associated tests to validate inputSchema structure and required fields.

Sequence diagram for ToolRegistry resolving legacy parameters vs inputSchema

sequenceDiagram
  participant ClientCode
  participant ToolRegistry
  participant PageTools
  participant ToolDefinition

  ClientCode->>PageTools: getTools()
  PageTools-->>ClientCode: Array of ToolDefinition

  loop for each tool
    ClientCode->>ToolRegistry: buildParameterSchema(tool)
    ToolRegistry->>ToolDefinition: check inputSchema
    alt tool has inputSchema
      ToolDefinition-->>ToolRegistry: inputSchema
      ToolRegistry-->>ClientCode: MCPToolSchema from inputSchema
    else tool has legacy parameters
      ToolDefinition-->>ToolRegistry: parameters array
      ToolRegistry-->>ClientCode: MCPToolSchema converted from parameters
    end
  end
Loading

Class diagram for WordPress tools using inputSchema

classDiagram
  class WordPressClient

  class MCPToolSchema {
    +string type
    +object properties
    +string[] required
  }

  class ToolDefinition {
    +string name
    +string description
    +MCPToolSchema inputSchema
    +handler(client WordPressClient, params Record)
  }

  class AuthTools {
    +getTools() Array~ToolDefinition~
    -handleTestAuth(client WordPressClient, params Record)
    -handleGetAuthStatus(client WordPressClient, params Record)
    -handleSwitchAuthMethod(client WordPressClient, params Record)
  }

  class CommentTools {
    +getTools() Array~ToolDefinition~
    -handleListComments(client WordPressClient, params Record)
    -handleGetComment(client WordPressClient, params Record)
    -handleCreateComment(client WordPressClient, params Record)
    -handleUpdateComment(client WordPressClient, params Record)
    -handleDeleteComment(client WordPressClient, params Record)
    -handleApproveComment(client WordPressClient, params Record)
    -handleSpamComment(client WordPressClient, params Record)
  }

  class MediaTools {
    +getTools() Array~ToolDefinition~
    -handleListMedia(client WordPressClient, params Record)
    -handleGetMedia(client WordPressClient, params Record)
    -handleUploadMedia(client WordPressClient, params Record)
    -handleUpdateMedia(client WordPressClient, params Record)
    -handleDeleteMedia(client WordPressClient, params Record)
  }

  class PageTools {
    +getTools() Array~ToolDefinition~
    -handleListPages(client WordPressClient, params Record)
    -handleGetPage(client WordPressClient, params Record)
    -handleCreatePage(client WordPressClient, params Record)
    -handleUpdatePage(client WordPressClient, params Record)
    -handleDeletePage(client WordPressClient, params Record)
    -handleGetPageRevisions(client WordPressClient, params Record)
  }

  class SiteTools {
    +getTools() Array~ToolDefinition~
    -handleGetSiteSettings(client WordPressClient, params Record)
    -handleUpdateSiteSettings(client WordPressClient, params Record)
    -handleSearchSite(client WordPressClient, params Record)
    -handleGetApplicationPasswords(client WordPressClient, params Record)
    -handleCreateApplicationPassword(client WordPressClient, params Record)
    -handleDeleteApplicationPassword(client WordPressClient, params Record)
  }

  class TaxonomyTools {
    +getTools() Array~ToolDefinition~
    -handleListCategories(client WordPressClient, params Record)
    -handleGetCategory(client WordPressClient, params Record)
    -handleCreateCategory(client WordPressClient, params Record)
    -handleUpdateCategory(client WordPressClient, params Record)
    -handleDeleteCategory(client WordPressClient, params Record)
    -handleListTags(client WordPressClient, params Record)
    -handleGetTag(client WordPressClient, params Record)
    -handleCreateTag(client WordPressClient, params Record)
    -handleUpdateTag(client WordPressClient, params Record)
    -handleDeleteTag(client WordPressClient, params Record)
  }

  class UserTools {
    +getTools() Array~ToolDefinition~
    -handleListUsers(client WordPressClient, params Record)
    -handleGetUser(client WordPressClient, params Record)
    -handleGetCurrentUser(client WordPressClient, params Record)
    -handleCreateUser(client WordPressClient, params Record)
    -handleUpdateUser(client WordPressClient, params Record)
    -handleDeleteUser(client WordPressClient, params Record)
  }

  class ToolRegistry {
    +buildParameterSchema(tool ToolDefinition) MCPToolSchema
  }

  AuthTools --> ToolDefinition
  CommentTools --> ToolDefinition
  MediaTools --> ToolDefinition
  PageTools --> ToolDefinition
  SiteTools --> ToolDefinition
  TaxonomyTools --> ToolDefinition
  UserTools --> ToolDefinition

  ToolDefinition --> MCPToolSchema
  ToolDefinition --> WordPressClient : handler uses

  ToolRegistry --> ToolDefinition : consumes
  ToolRegistry --> MCPToolSchema : returns
Loading

File-Level Changes

Change Details Files
Replace legacy parameters array definitions with JSON Schema-based inputSchema across remaining WordPress tool modules.
  • Update tool signatures in each tools class to use an optional inputSchema?: MCPToolSchema field instead of a parameters array.
  • Model each tool’s arguments as a JSON Schema object with type: "object", properties, and required arrays while preserving existing argument names, types, descriptions, enums, and requirement semantics.
  • Ensure tools that previously had no parameters now expose an empty-object schema with no required fields.
src/tools/auth.ts
src/tools/comments.ts
src/tools/media.ts
src/tools/pages.ts
src/tools/site.ts
src/tools/taxonomies.ts
src/tools/users.ts
Adjust tests to assert against inputSchema structure and semantics instead of parameters.
  • Update generic tool validation tests to expect an inputSchema object on each tool rather than a parameters array.
  • Rewrite tool-specific tests to inspect inputSchema.properties and inputSchema.required for presence, type, and enum constraints of each argument.
  • Update Taxonomy, Comment, User, Media, Page, Site, and Auth tool tests (including submodule tests) to align expectations with the new schema-based representation.
tests/tool-validation.test.js
tests/tools/auth.test.js
tests/tools/comments.test.js
tests/tools/media.test.js
tests/tools/pages.test.js
tests/tools/site.test.js
tests/tools/taxonomies.test.js
tests/tools/comments/CommentTools.test.js
tests/tools/media/MediaTools.test.js
tests/tools/pages/PageTools.test.js
tests/tools/taxonomies/TaxonomyTools.test.js
tests/tools/users.test.js
tests/tools/users/UserTools.test.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • There’s a lot of repeated inline JSON Schema for common patterns (e.g. simple id-required objects, list-with-search filters, etc.); consider extracting small helpers/factories for these to reduce duplication and keep future schema changes consistent across tools.
  • For tools that are intended to have no arguments (e.g. wp_get_site_settings, wp_get_current_user, auth status tools), you may want to add additionalProperties: false to their inputSchema to prevent accidental extra parameters and better reflect the contract.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- There’s a lot of repeated inline JSON Schema for common patterns (e.g. simple `id`-required objects, list-with-search filters, etc.); consider extracting small helpers/factories for these to reduce duplication and keep future schema changes consistent across tools.
- For tools that are intended to have no arguments (e.g. `wp_get_site_settings`, `wp_get_current_user`, auth status tools), you may want to add `additionalProperties: false` to their `inputSchema` to prevent accidental extra parameters and better reflect the contract.

## Individual Comments

### Comment 1
<location path="src/tools/auth.ts" line_range="32-35" />
<code_context>
           "• Troubleshoot: Run when experiencing connection issues\n" +
           "• Health check: Regular verification of WordPress connectivity",
-        parameters: [], // The 'site' parameter is added dynamically by the server
+        // The 'site' parameter is added dynamically by the server
+        inputSchema: {
+          type: "object",
+          properties: {},
+        },
         handler: this.handleTestAuth.bind(this),
</code_context>
<issue_to_address>
**question (bug_risk):** Consider aligning the `wp_test_auth` schema with how the dynamic `site` parameter is injected and validated.

With `inputSchema` now defined as an empty object, any dynamically injected `site` field may not be represented in the runtime schema. Please confirm that either (a) the effective schema at validation time includes `site`, or (b) this tool’s validation is configured to allow unknown properties, so callers don’t hit schema/validation mismatches compared to tools where all fields are declared.
</issue_to_address>

### Comment 2
<location path="tests/tools/auth.test.js" line_range="72-81" />
<code_context>
+      const methodProp = switchTool.inputSchema.properties.method;
</code_context>
<issue_to_address>
**suggestion (testing):** Add an explicit check for tools that should have no user-supplied parameters (empty `properties`)

Since `wp_test_connection` and `wp_get_auth_status` now use an empty `inputSchema` with parameters added server-side, add an assertion in the auth tests that `Object.keys(tool.inputSchema.properties).length === 0` for these tools. This will guard against accidentally introducing user-facing parameters while still passing the tests.
</issue_to_address>

### Comment 3
<location path="tests/tool-validation.test.js" line_range="48" />
<code_context>
         expect(tool).toHaveProperty("name");
         expect(tool).toHaveProperty("description");
-        expect(tool).toHaveProperty("parameters");
+        expect(tool).toHaveProperty("inputSchema");
       });
     });
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen global tool validation to verify `inputSchema` structure, not just presence

Since this is the central invariant check for all tools, it’s a good place to validate the basic JSON Schema shape of `inputSchema`, not just its presence. For example, assert that `inputSchema.type === "object"`, `inputSchema.properties` is an object, and if `required` is present, it’s an array. That will better protect the migration from regressions without duplicating checks in individual tool tests.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +32 to +35
// The 'site' parameter is added dynamically by the server
inputSchema: {
type: "object",
properties: {},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (bug_risk): Consider aligning the wp_test_auth schema with how the dynamic site parameter is injected and validated.

With inputSchema now defined as an empty object, any dynamically injected site field may not be represented in the runtime schema. Please confirm that either (a) the effective schema at validation time includes site, or (b) this tool’s validation is configured to allow unknown properties, so callers don’t hit schema/validation mismatches compared to tools where all fields are declared.

Comment on lines +72 to +81
const methodProp = switchTool.inputSchema.properties.method;
expect(methodProp).toBeDefined();
expect(switchTool.inputSchema.required).toContain("method");
expect(methodProp.enum).toEqual(["app-password", "jwt", "basic", "api-key", "cookie"]);

const usernameParam = switchTool.parameters.find((p) => p.name === "username");
expect(usernameParam).toBeDefined();
expect(usernameParam.required).toBeFalsy();
const usernameProp = switchTool.inputSchema.properties.username;
expect(usernameProp).toBeDefined();
expect(switchTool.inputSchema.required).not.toContain("username");

const passwordParam = switchTool.parameters.find((p) => p.name === "password");
expect(passwordParam).toBeDefined();
expect(passwordParam.required).toBeFalsy();
const passwordProp = switchTool.inputSchema.properties.password;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add an explicit check for tools that should have no user-supplied parameters (empty properties)

Since wp_test_connection and wp_get_auth_status now use an empty inputSchema with parameters added server-side, add an assertion in the auth tests that Object.keys(tool.inputSchema.properties).length === 0 for these tools. This will guard against accidentally introducing user-facing parameters while still passing the tests.

expect(tool).toHaveProperty("name");
expect(tool).toHaveProperty("description");
expect(tool).toHaveProperty("parameters");
expect(tool).toHaveProperty("inputSchema");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Strengthen global tool validation to verify inputSchema structure, not just presence

Since this is the central invariant check for all tools, it’s a good place to validate the basic JSON Schema shape of inputSchema, not just its presence. For example, assert that inputSchema.type === "object", inputSchema.properties is an object, and if required is present, it’s an array. That will better protect the migration from regressions without duplicating checks in individual tool tests.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c0fae7082f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

enum?: string[];
items?: unknown;
}>;
inputSchema?: MCPToolSchema;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle inputSchema tools in documentation generator

After this migration, these tool classes no longer expose parameters, but the docs pipeline still reads only toolDef.parameters (for parameter extraction and example generation in src/docs/DocumentationGenerator.ts). As a result, running docs/OpenAPI generation now produces incomplete docs for migrated tools (missing parameter tables, required args, and realistic examples) even though the tools do accept those inputs via inputSchema.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates legacy WordPress tool modules from the old parameters[] format to MCP’s standard inputSchema JSON Schema format, aligning them with the existing posts/SEO tooling patterns and updating tests accordingly.

Changes:

  • Refactor 7 tool modules (auth, comments, media, pages, site, taxonomies, users) to define parameters via inputSchema instead of parameters.
  • Update tool-focused test suites to assert against inputSchema.properties / inputSchema.required.
  • Maintain ToolRegistry backward compatibility by still supporting both formats during schema building.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tools/auth.ts Converts auth tools to inputSchema definitions.
src/tools/comments.ts Converts comment tools to inputSchema definitions.
src/tools/media.ts Converts media tools to inputSchema definitions.
src/tools/pages.ts Converts page tools to inputSchema definitions.
src/tools/site.ts Converts site tools to inputSchema definitions.
src/tools/taxonomies.ts Converts taxonomy tools to inputSchema definitions.
src/tools/users.ts Converts user tools to inputSchema definitions.
tests/tools/auth.test.js Updates assertions from parameters to inputSchema.
tests/tools/comments.test.js Updates assertions from parameters to inputSchema.
tests/tools/comments/CommentTools.test.js Updates assertions from parameters to inputSchema.
tests/tools/media.test.js Updates assertions from parameters to inputSchema.
tests/tools/media/MediaTools.test.js Updates assertions from parameters to inputSchema.
tests/tools/pages.test.js Updates assertions from parameters to inputSchema.
tests/tools/pages/PageTools.test.js Updates assertions from parameters to inputSchema.
tests/tools/site.test.js Updates assertions from parameters to inputSchema.
tests/tools/taxonomies.test.js Updates assertions from parameters to inputSchema.
tests/tools/taxonomies/TaxonomyTools.test.js Updates assertions from parameters to inputSchema.
tests/tools/users.test.js Updates assertions from parameters to inputSchema.
tests/tools/users/UserTools.test.js Updates assertions from parameters to inputSchema.
tests/tool-validation.test.js Updates tool shape validation to require inputSchema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 16 to 22
*/
public getTools(): Array<{
name: string;
description: string;
parameters?: Array<{
name: string;
type?: string;
description?: string;
required?: boolean;
enum?: string[];
items?: unknown;
}>;
inputSchema?: MCPToolSchema;
handler: (client: WordPressClient, params: Record<string, unknown>) => Promise<unknown>;
}> {
@@ -1,4 +1,5 @@
import { WordPressClient } from "@/client/api.js";
import { MCPToolSchema } from "@/types/mcp.js";
enum: ["publish", "future", "draft", "pending", "private"],
},
],
required: [],
Convert 7 tool modules (auth, comments, media, pages, site, taxonomies,
users) from the legacy parameters array format to the standard inputSchema
JSON Schema format, matching the pattern already used by posts and SEO tools.

- Replace parameters arrays with inputSchema objects
- Use JSON Schema properties, required, and enum fields
- Update 13 test files to assert on inputSchema instead of parameters

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@docdyhr docdyhr force-pushed the refactor/tool-input-schema branch from c0fae70 to fbca260 Compare March 15, 2026 23:19
@docdyhr docdyhr merged commit 067aa3e into main Mar 15, 2026
25 checks passed
@docdyhr docdyhr deleted the refactor/tool-input-schema branch March 15, 2026 23:21
docdyhr pushed a commit that referenced this pull request Mar 15, 2026
## [3.1.12](v3.1.11...v3.1.12) (2026-03-15)

### ♻️ Refactoring

* migrate legacy tools to inputSchema JSON Schema format ([#170](#170)) ([067aa3e](067aa3e))
@docdyhr
Copy link
Owner Author

docdyhr commented Mar 15, 2026

🎉 This PR is included in version 3.1.12 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants