Skip to main content
Glama
InstaWP

WordPress MCP Server

by InstaWP

WordPress MCPサーバー

これはWordPress用のModel Context Protocol(MCP)サーバーで、Claude for DesktopなどのMCP互換クライアントを介して自然言語でWordPressサイトを操作できます。このサーバーは、WordPressのさまざまなデータと機能をMCPツールとして公開します。

使用方法

Claude Desktop

  1. Claude Desktopをダウンロードしてインストールします。

  2. Claude Desktopの設定を開き、「Developer」タブに移動します。

  3. claude_desktop_config.json.exampleファイルの内容をコピーします。

  4. 「Edit Config」をクリックしてclaude_desktop_config.jsonファイルを開きます。

  5. サンプルファイルの内容を設定ファイルにコピー&ペーストします。WordPressサイトの実際の値にプレースホルダー値を必ず置き換えてください。アプリケーションキーを生成するには、このガイドに従ってください - Application Passwords。

  6. 設定を保存します。

  7. Claude Desktopを再起動します。

Related MCP server: WordPress MCP Server

機能

このサーバーは、WordPressのコアデータを操作するためのツールを提供し、マルチサイト管理をサポートします - 単一のMCPサーバーインスタンスから複数のWordPressサイトを管理できます。

マルチサイト管理(3ツール)

単一のMCPサーバーから複数のWordPressサイトを管理します:

  • list_sites: 設定済みのすべてのWordPressサイトを一覧表示

  • get_site: 特定のサイト設定の詳細を取得

  • test_site: 特定のWordPressサイトへの接続をテスト

すべてのコンテンツおよびタクソノミーツールは、特定のサイトを対象とするオプションのsite_idパラメータをサポートしています。

統合コンテンツ管理(9ツール)

単一のインテリジェントなツールセットで、すべてのコンテンツタイプ(投稿、固定ページ、カスタム投稿タイプ)を処理します:

  • list_content: フィルタリングとページネーション付きで任意のコンテンツタイプを一覧表示

  • get_content: IDとタイプで特定のコンテンツを取得

  • create_content: 任意のタイプの新しいコンテンツを作成

  • update_content: 任意のタイプの既存コンテンツを更新(対象を絞った部分編集を含む)

  • delete_content: 任意のタイプのコンテンツを削除

  • discover_content_types: サイト上のすべての利用可能なコンテンツタイプを検出

  • find_content_by_url: 任意のWordPress URLからコンテンツを検索し、必要に応じて更新できるスマートURLリゾルバー(対象を絞った部分編集を含む)

  • get_content_by_slug: すべてのコンテンツタイプを横断してスラッグで検索

  • get_content_summary: 監査および検索ワークフロー用に最小限のサマリー(id、title、slug、status、excerpt、taxonomies、word count、Yoast SEOフィールド)を返します。idまたはurlで検索します。

統合タクソノミー管理(8ツール)

単一のツールセットで、すべてのタクソノミー(カテゴリー、タグ、カスタムタクソノミー)を処理します:

  • discover_taxonomies: サイト上のすべての利用可能なタクソノミーを検出

  • list_terms: 任意のタクソノミーのタームを一覧表示

  • get_term: IDで特定のタームを取得

  • create_term: 任意のタクソノミーに新しいタームを作成

  • update_term: 既存のタームを更新

  • delete_term: 任意のタクソノミーからタームを削除

  • assign_terms_to_content: 任意のコンテンツタイプにタームを割り当て

  • get_content_terms: 任意のコンテンツのすべてのタームを取得

専門ツール

  • メディア:

    • list_media: すべてのメディアアイテムを一覧表示(ページネーションと検索をサポート)。

    • get_media: IDで特定のメディアアイテムを取得。

    • create_media: URLまたはローカルファイルパスから新しいメディアアイテムを作成。

    • update_media: 既存のメディアアイテムを更新。

    • delete_media: メディアアイテムを削除。

    • edit_media: 後方互換性のために保持されているupdate_mediaのレガシーエイリアス。

  • ユーザー:

    • list_users: フィルタリング、並べ替え、ページネーションオプション付きで全ユーザーを一覧表示。

    • get_user: IDで特定のユーザーを取得。

    • create_user: 新しいユーザーを作成。

    • update_user: 既存のユーザーを更新。

    • delete_user: ユーザーを削除。

  • コメント:

    • list_comments: フィルタリング、並べ替え、ページネーションオプション付きで全コメントを一覧表示。

    • get_comment: IDで特定のコメントを取得。

    • create_comment: 新しいコメントを作成。

    • update_comment: 既存のコメントを更新。

    • delete_comment: コメントを削除。

  • プラグイン:

    • list_plugins: サイトにインストールされているすべてのプラグインを一覧表示。

    • get_plugin: 特定のプラグインの詳細を取得。

    • activate_plugin: プラグインを有効化。

    • deactivate_plugin: プラグインを無効化。

    • create_plugin: 新しいプラグインを作成。

  • プラグインリポジトリ:

  • search_plugins: WordPress.orgリポジトリでプラグインを検索。

  • get_plugin_info: リポジトリからプラグインの詳細情報を取得。

  • データベースクエリ:

  • execute_sql_query: WordPressデータベースに対して読み取り専用のSQLクエリを実行(カスタムエンドポイントの設定が必要)。

主な利点

メディアアップロードワークフロー

MCPサーバーを実行している同じマシンからローカルのスクリーンショットをアップロード:

{
  "file_path": "./screenshots/homepage.png",
  "title": "Homepage Screenshot",
  "alt_text": "Homepage screenshot showing the hero section"
}

リモートURLからメディアをアップロード:

{
  "source_url": "https://example.com/assets/hero-image.png",
  "title": "Hero Image",
  "caption": "Imported from the design system"
}

返されたメディアIDを新しいコンテンツのアイキャッチ画像として使用:

{
  "content_type": "post",
  "title": "Release Notes",
  "content": "<p>Launch summary...</p>",
  "featured_media": 123
}

スマートURL解決

find_content_by_urlツールは以下が可能です:

  • 任意のWordPress URLを受け取り、対応するコンテンツを自動的に検索

  • URLパターンからコンテンツタイプを検出(例:/documentation/ → documentationカスタム投稿タイプ)

  • 1回の操作でコンテンツをオプションで更新

  • 投稿、固定ページ、および任意のカスタム投稿タイプで動作

監査・検索サマリー

get_content_summaryツールは、単一のコンテンツの最小限の固定形状の表現を返します。レシピ投稿ではレンダリングされたRecipe MakerカードのHTMLのために50KBを超えることもある完全なWP RESTレスポンスが過剰となる、監査および検索ワークフロー向けに設計されています。

IDで検索(オプションのcontent_type付き、デフォルトはpost):

{
  "id": 4274,
  "content_type": "post"
}

URLで検索(コンテンツタイプはURLから検出されます):

{
  "url": "https://example.com/blog/easy-smoked-asparagus/"
}

idとurlは相互に排他的です - 正確に1つを指定してください。

レスポンスの形状は固定されています:

{
  "id": 4274,
  "title": "Easy Smoked Asparagus & Hot Honey",
  "slug": "easy-smoked-asparagus",
  "status": "publish",
  "link": "https://example.com/blog/easy-smoked-asparagus/",
  "excerpt": "Smoky asparagus with hot honey.",
  "date_modified": "2026-04-30T10:14:00",
  "categories": [12, 7],
  "tags": [33],
  "featured_media": 9012,
  "word_count": 875,
  "yoast_focus_keyword": "smoked asparagus",
  "yoast_meta_title": "Easy Smoked Asparagus | Example",
  "yoast_meta_description": "Smoky charred asparagus finished with chili-lime hot honey."
}

フィールドの注意点:

  • titleとexcerptはプレーンテキストに変換されます(HTMLタグは削除され、基本的なエンティティはデコードされます)。

  • word_countは、Yoast SEOが有効な場合はyoast_head_json.schema.@graph[].wordCountを優先します。それ以外の場合は、HTMLを除去したレンダリング済み投稿コンテンツから計算されます。

  • yoast_meta_titleとyoast_meta_descriptionは投稿のyoast_head_jsonから読み取られます。Yoast SEOが有効でない場合はnullになります。

  • yoast_focus_keywordはmeta._yoast_wpseo_focuskwから読み取られます。WordPressコアはshow_in_restで登録されたメタキーのみを公開し、Yoast SEOはこのキーをデフォルトでは登録しないため、このフィールドは通常nullになります(より広範なメタキーREST公開問題の文脈についてはPR #17を参照)。

  • このツールはyoast_head_jsonを読み取るために、PR #16で追加されたレスポンストリミングを内部的にバイパスします。トリミングは他のすべてのツールには引き続き適用されます。

ユニバーサルコンテンツ操作

すべてのコンテンツ操作は単一のcontent_typeパラメータを使用します:

{
  "content_type": "post", // for blog posts
  "content_type": "page", // for static pages
  "content_type": "product", // for WooCommerce products
  "content_type": "documentation" // for custom post types
}

対象を絞ったコンテンツ編集

update_contentとfind_content_by_url.update_fieldsは、完全なドキュメントを再送信せずに既存の生のWordPressコンテンツにパッチを適用できます。

正確なマッチングを容易にするために、get_contentとfind_content_by_urlはどちらもinclude_raw_content: trueを受け入れます。有効にすると、レスポンスはWordPressの編集コンテキストで取得され、content_edit.target_textが必要とするものと一致するトップレベルのcontent_rawフィールドが含まれます。

{
  "content_type": "page",
  "id": 7,
  "include_raw_content": true
}

投稿の最後に短いリリースノートを追加:

{
  "content_type": "post",
  "id": 42,
  "content_edit": {
    "operation": "append",
    "value": "\n<p>Update: Early access is now open.</p>",
    "content_format": "html"
  }
}

一意のHTMLフラグメントまたはマーカーコメントをその場で置換:

{
  "content_type": "page",
  "id": 7,
  "content_edit": {
    "operation": "replace",
    "target_text": "<!-- pricing-card -->\n<p>Old price</p>\n<!-- /pricing-card -->",
    "value": "<!-- pricing-card -->\n<p>New price</p>\n<!-- /pricing-card -->",
    "content_format": "html"
  }
}

注意点:

  • レンダリングされたWordPress HTMLは、エンティティがエスケープされたりマークアップが展開されたりする可能性があるため、content.rawと異なる場合があります。正確なtarget_textが必要な場合はinclude_raw_contentを使用してください。

  • target_textは保存されている生のWordPressコンテンツと正確に一致します。

  • 同じtarget_textが複数回出現する場合は、occurrenceを渡して1から始まるマッチを選択します。

  • Gutenbergブロックとして保存された投稿の場合、ブロックに変換すべきMarkdownまたはHTMLを挿入するときはcontent_edit.convert_to_blocksを設定してください。

ユニバーサルタクソノミー操作

すべてのタクソノミー操作は単一のtaxonomyパラメータを使用します:

{
  "taxonomy": "category", // for categories
  "taxonomy": "post_tag", // for tags
  "taxonomy": "product_category", // for WooCommerce
  "taxonomy": "skill" // for custom taxonomies
}

taxonomyパラメータは、タクソノミーのスラッグまたはそのrest_baseのいずれかを受け入れます(カスタムタクソノミーではこれらが異なる場合があります。例:スラッグdocumentation_category、rest_base documentation-categories)。ツールは/wp/v2/taxonomiesを介して識別子を解決し、推測する代わりに不明なタクソノミーではエラーを返します。assign_terms_to_contentはWordPressのレスポンスに対して書き込みを検証し、タームが実際に保存されなかった場合はエラーを報告します。

レシピカード(WP Recipe Maker)

WP Recipe Maker(WPRM)を実行しているサイトでは、レシピカードが周囲のブログ投稿からショートコードで参照される別のwprm_recipeカスタム投稿タイプに保存されます。統合コンテンツツールはこれらのレシピを直接処理します - レシピ専用のツールファミリーは必要ありません。

レシピの読み取り - get_content、list_content、find_content_by_url、get_content_by_slugはすべてcontent_type: "wprm_recipe"で動作します。WPRMは、材料、手順、時間、器具、栄養、メモ、評価を含む完全な構造化レシピペイロードをRESTレスポンスのrecipeフィールドとして公開します。

レシピの書き込み - create_contentまたはupdate_contentのcustom_fields.recipeを介してレシピペイロードを渡します。WPRMはWordPress REST挿入アクション(rest_insert_wprm_recipe)にフックし、リクエストボディのルートからrecipeを読み取るため、WPRMのデータモデルで文書化された任意のフィールドが受け入れられます。

recipeペイロードはcustom_fields(リクエストボディのルートに展開される)を介して渡す必要があります。metaパラメータはその値をmetaキーの下にネストするため、WPRMのRESTフックには到達しません。

更新の例:

{
  "content_type": "wprm_recipe",
  "id": 4274,
  "custom_fields": {
    "recipe": {
      "name": "Easy Smoked Asparagus",
      "summary": "Smoky asparagus with hot honey.",
      "servings": "4",
      "servings_unit": "people",
      "prep_time": "5",
      "cook_time": "60",
      "total_time": "65",
      "ingredients": [
        {
          "name": "",
          "ingredients": [
            { "uid": 0, "amount": "1", "unit": "Bunch", "name": "Asparagus Spears", "notes": "" },
            { "uid": 1, "amount": "1", "unit": "tbsp", "name": "Olive Oil", "notes": "" }
          ]
        }
      ],
      "instructions": [
        {
          "name": "",
          "instructions": [
            { "uid": 0, "name": "", "text": "Preheat smoker to 225°F.", "ingredients": [] },
            { "uid": 1, "name": "", "text": "Drizzle with oil, season, smoke 1 hour.", "ingredients": [] }
          ]
        }
      ],
      "notes": "Thicker spears need more time."
    }
  }
}

グループ化された材料と手順 - レシピはアイテムを「ソース用」/「チキン用」などの名前付きグループに分割できます。外側のingredients(またはinstructions)配列の各エントリは、独自のnameと内部配列を持つ1つのグループです:

{
  "ingredients": [
    { "name": "For the sauce",   "ingredients": [ /* items */ ] },
    { "name": "For the chicken", "ingredients": [ /* items */ ] }
  ]
}

一般的に使用されるレシピフィールド:

フィールド

型

備考

name

string

レシピカードのタイトル

summary

string

短い説明(HTML可)

servings

string

例:"4"

servings_unit

string

例:"people"、"servings"

prep_time

string

分単位、例:"15"

cook_time

string

分単位

total_time

string

分単位

ingredients

array of groups

上記のネスト構造

instructions

array of groups

上記のネスト構造

notes

string

HTML可

equipment

array

{ id, name, notes, amount, uid }形式のアイテム

image_url

string

image_idが指定されていない場合のURLアップロード

コース、料理、キーワードはWPRMタクソノミー(wprm_course、wprm_cuisine、wprm_keyword)として保存されます。統合タクソノミーツール(list_terms、create_termなど)で管理し、assign_terms_to_contentでレシピにリンクします。

WPRMは保存時にrecipe.summaryをWordPressのpost_contentフィールドに自動同期します。投稿本文とレシピのサマリーを異なるものにしたい場合は、custom_fields.recipeと一緒にcontentを明示的に渡してください。

設定

単一サイト設定

単一のWordPressサイトを管理するには、次の環境変数を使用します:

WORDPRESS_API_URL=https://your-wordpress-site.com
WORDPRESS_USERNAME=wp_username
WORDPRESS_PASSWORD=wp_app_password

マルチサイト設定

単一のMCPサーバーから複数のWordPressサイトを管理するには、番号付きの環境変数を使用します:

# Site 1 (Production)
WORDPRESS_1_URL=https://production-site.com
WORDPRESS_1_USERNAME=admin
WORDPRESS_1_PASSWORD=app_password_1
WORDPRESS_1_ID=production
WORDPRESS_1_DEFAULT=true
WORDPRESS_1_ALIASES=prod,main

# Site 2 (Staging)
WORDPRESS_2_URL=https://staging-site.com
WORDPRESS_2_USERNAME=admin
WORDPRESS_2_PASSWORD=app_password_2
WORDPRESS_2_ID=staging
WORDPRESS_2_ALIASES=stage,dev

# Site 3 (Development)
WORDPRESS_3_URL=https://dev-site.com
WORDPRESS_3_USERNAME=admin
WORDPRESS_3_PASSWORD=app_password_3
WORDPRESS_3_ID=development

マルチサイト設定オプション:

  • WORDPRESS_N_URL: WordPressサイトURL(必須)

  • WORDPRESS_N_USERNAME: WordPressユーザー名(必須)

  • WORDPRESS_N_PASSWORD: WordPressアプリケーションパスワード(必須)

  • WORDPRESS_N_ID: サイト識別子(オプション、デフォルトは siteN)

  • WORDPRESS_N_DEFAULT: true に設定すると、このサイトがデフォルトになります(オプション、最初のサイトがデフォルト)

  • WORDPRESS_N_ALIASES: サイト検出用のカンマ区切りのエイリアス(オプション)

サーバーは最大10サイトをサポートします。マルチサイト構成を使用する場合、すべてのツールは特定のサイトを対象とするオプションの site_id パラメータを受け付けます。

npxと.envファイルでの使用

このMCPサーバーは、グローバルにインストールせずにnpxを使用して直接実行できます:

npx -y @instawp/mcp-wp

現在のディレクトリに、次の変数を含む .env ファイルがあることを確認してください:

WORDPRESS_API_URL=https://your-wordpress-site.com
WORDPRESS_USERNAME=wp_username
WORDPRESS_PASSWORD=wp_app_password

# Optional: Custom SQL query endpoint (default: /mcp/v1/query)
WORDPRESS_SQL_ENDPOINT=/mcp/v1/query

# Optional: Comma-separated list of top-level fields to strip from
# WordPress REST API responses before they are returned to the MCP
# client. Defaults to "yoast_head,yoast_head_json" — read-only schema
# markup that adds ~10KB to every response but is rarely useful to the
# LLM. Set to an empty string to disable trimming.
MCP_WP_STRIP_FIELDS=yoast_head,yoast_head_json

ユーザーエージェント

このサーバーが行うすべてのアウトバウンドリクエスト(すべてのツールが使用するWordPress RESTクライアント、SQLエンドポイント、2つのapi.wordpress.orgルックアップ、リモートメディアのダウンロード)は、axiosのデフォルトの axios/<version> ユーザーエージェントを送信します。

WORDPRESS_USER_AGENT を設定すると、すべての場所でそれを上書きできます:

WORDPRESS_USER_AGENT=MyAgency-MCP/1.0 (+https://example.com)

サイトの前段にあるCDNやWAFがデフォルトを拒否する場合を除き、未設定のままにしてください。空または空白のみの値は未設定として扱われます。裸の Mozilla/5.0 は避けてください。これは広く知られたボットのシグネチャであり、いくつかのエッジがまさにブロックする対象です(#28を参照)。そのため、このサーバーのどこからも送信されません。

レスポンスのトリミング

デフォルトでは、サーバーはすべてのWordPress REST APIレスポンスからトップレベルの yoast_head フィールドと yoast_head_json フィールドを削除してから、MCPクライアントに返します。これらのフィールドにはYoast SEOのプリレンダリング済みスキーママークアップが含まれており、LLMがほとんど必要としない一方で、毎回のリクエストでトークンを消費します。

  • トリミングは、単一オブジェクトのレスポンスとオブジェクトの配列の両方に適用されます。

  • 削除されるのはトップレベルのフィールドのみで、ネストされたオブジェクトは変更されません。

  • MCP_WP_STRIP_FIELDS 環境変数(カンマ区切り)でリストを上書きできます。空文字列に設定すると、トリミングを完全に無効化できます。

メタフィールドの制限

create_content、update_content、find_content_by_url(update_fields.meta を使用する場合)の meta パラメータは、WordPressの /wp/v2/{type}/{id} エンドポイントに直接転送されます。WordPressコアは、register_post_meta(..., ['show_in_rest' => true]) で登録されていないメタキーを黙って破棄します。MCPサーバーには独自の許可リストはありません。どのキーが永続化されるかの判断はWordPressに委ねています。

つまり、SEOプラグインのキーは、デフォルトではこのMCPサーバー経由で書き込めません。そのようなキーには次のものがあります:

  • Yoast SEO: _yoast_wpseo_* (focuskw, metadesc, title, opengraph-, twitter-, canonical, meta-robots-*, primary_category, …)

  • Rank Math: rank_math_* (title, description, focus_keyword, robots, facebook_, twitter_, primary_category, …)

  • All in One SEO(v4+): SEOデータを wp_postmeta ではなくカスタムテーブル(wp_aioseo_posts)に保存します。そのため、meta フィールドからはどのような方法でもアクセスできません。

サーバーは、送信したキーがWordPressによって破棄されたことを検出すると、ツールの結果の先頭にそれらのキーを列挙した Warning: ブロックを追加します。これにより、黙って破棄されたことがLLMの呼び出し元に可視化されますが、WordPressにキーを受け入れさせることはできません。

SEOメタの書き込みを有効にするには、目的の各キーに対して show_in_rest => true と適切な auth_callback を指定して register_post_meta を呼び出す、小さなWordPressコンパニオンプラグインをインストールしてください。まさにこれを実現する専用の mcp-wp-seo-bridge プラグインが現在スコープ定義されています。

現在実際に機能するキー

プラグインの作者がすでにREST用に登録しているプラグインキーです。例: Genesisのレイアウトメタ(_genesis_layout)、WP Recipe Makerのフィールド(wprm-*)、ConvertKitの _wp_convertkit_post_meta など。サイト上でどのキーが往復できるかを確認するには、update_content でテスト値を書き込み、レスポンスの meta ブロックを確認してください。キーが表示されていれば、永続化されています。

同じ制限は、unified-taxonomies ツール(create_term、update_term)のタームメタにも適用されます。

SQLクエリツールの有効化(オプション)

execute_sql_query ツールを使用すると、WordPressデータベースに対して読み取り専用のSQLクエリを実行できます。これはオプション機能であり、WordPressサイトにカスタムREST APIエンドポイントを追加する必要があります。

セキュリティ上の注意:

  • このツールは安全性のため、読み取り専用クエリ(SELECT、WITH...SELECT、EXPLAIN)のみを受け付けます

  • INSERT、UPDATE、DELETE、DROP、その他の変更ステートメントを含むクエリは拒否されます

  • SQLインジェクションを防ぐため、複数ステートメントのクエリはブロックされます

  • クエリと結果は logs/wordpress-api.log に記録されます。クエリに機密データを含めないようにしてください

  • このツールには管理者レベルの権限(manage_options ケイパビリティ)が必要です

設定: デフォルトでは、ツールは /mcp/v1/query のエンドポイントを想定しています。WORDPRESS_SQL_ENDPOINT 環境変数(例: WORDPRESS_SQL_ENDPOINT=/custom/v1/query)を設定してカスタマイズできます。

この機能を有効にするには、次のコードをWordPressサイトに追加します(カスタムプラグインまたはテーマの functions.php 経由):

add_action('rest_api_init', function() {
    register_rest_route('mcp/v1', '/query', array(
        'methods' => 'POST',
        'callback' => function($request) {
            global $wpdb;

            $query = $request->get_param('query');

            // Additional security check
            if (!current_user_can('manage_options')) {
                return new WP_Error('unauthorized', 'Unauthorized', array('status' => 401));
            }

            // Only allow SELECT queries
            if (stripos(trim($query), 'SELECT') !== 0) {
                return new WP_Error('invalid_query', 'Only SELECT queries allowed', array('status' => 400));
            }

            $results = $wpdb->get_results($query, ARRAY_A);

            if ($wpdb->last_error) {
                return new WP_Error('query_error', $wpdb->last_error, array('status' => 400));
            }

            return array(
                'results' => $results,
                'num_rows' => count($results)
            );
        },
        'permission_callback' => function() {
            return current_user_can('manage_options');
        }
    ));
});

このコードを追加すると、execute_sql_query ツールを使用して次のようなクエリを実行できます:

SELECT * FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 10

開発

前提条件

  • Node.jsとnpm: Node.js(バージョン18以上)とnpmがインストールされていることを確認してください。Node 18はサーバーを実行するのに十分です。コントリビュートにはNode 20以上が必要です。テストツール(Vitest 4)がそれを要求するためです。CIは20.xと22.xで実行されます。

  • WordPressサイト: REST APIが有効なアクティブなWordPressサイトが必要です。

  • WordPress API認証: WordPress REST APIの認証を設定します。通常、認証プラグインまたは認証方法(アプリケーションパスワードなど)が必要です。

  • MCPクライアント: MCPサーバーと通信できるアプリケーションが必要です。現時点では、Claude Desktopが推奨されます。

インストールとセットアップ

  1. リポジトリをクローンする:

    git clone <repository_url>
    cd wordpress-mcp-server
  2. 依存関係をインストールする:

    npm install
  3. .env ファイルを作成する:

    プロジェクトディレクトリのルートに .env ファイルを作成し、WordPress APIの認証情報を追加します。

    単一サイトの場合:

    WORDPRESS_API_URL=https://your-wordpress-site.com
    WORDPRESS_USERNAME=wp_username
    WORDPRESS_PASSWORD=wp_app_password

    複数サイトの場合:

    WORDPRESS_1_URL=https://site1.com
    WORDPRESS_1_USERNAME=admin
    WORDPRESS_1_PASSWORD=app_password_1
    WORDPRESS_1_ID=site1
    WORDPRESS_1_DEFAULT=true
    
    WORDPRESS_2_URL=https://site2.com
    WORDPRESS_2_USERNAME=admin
    WORDPRESS_2_PASSWORD=app_password_2
    WORDPRESS_2_ID=site2

    プレースホルダーを実際の値に置き換えてください。

  4. サーバーをビルドする:

    npm run build
  5. Claude Desktopを設定する:

    • Claude Desktopの設定を開き、「Developer」タブに移動します。

    • 「Edit Config」をクリックして claude_desktop_config.json ファイルを開きます。

    • mcpServers セクションの下に新しいサーバー設定を追加します。build/server.js ファイルへの絶対パスとWordPress環境変数を指定する必要があります。

    • 設定を保存します。

サーバーの実行

Claude Desktopを設定すると、Claude Desktopが起動するたびにサーバーが自動的に起動します。

テスト用にコマンドラインからサーバーを直接実行することもできます:

npm start

または開発モードで:

npm run dev

テストの実行

このリポジトリはユニットテストに Vitest を使用しています。テストは tests/ ディレクトリにあり、マルチサイトの SiteManager とMCPツールレジストリの配線をカバーしています。

npm test          # one-shot run
npm run test:watch  # watch mode

テストは、.github/workflows/test.yml によって、pull_request 時と main へのプッシュ時に実行されます。

リリース

修正をマージしても誰にも届きません。npmはリリースが実行されるまで、最後に公開されたバージョンを提供し続けます。公開は .github/workflows/release.yml によって自動化されており、バージョンタグによってトリガーされます:

# on main, with the fix already merged:
# 1. move the CHANGELOG's [Unreleased] block under a `[x.y.z] - <date>` heading and commit it
# 2. bump and tag — `npm version` writes package.json, commits, and creates the vx.y.z tag
npm version patch          # or minor / major
# 3. push the commit and the tag; the tag is what triggers the publish
git push origin main --follow-tags

CHANGELOGの編集は npm version の前に行ってください。後からコミットを修正(amend)すると、タグが修正前のコミットを指したままになり、ワークフローはそのコミットから公開してしまいます。

ワークフローは、タグと package.json が一致しない場合、またはそのバージョンがすでにnpm上にある場合に公開を拒否します。その後、ビルド、テストの実行、provenance による公開を行い、レジストリが実際に新しいバージョンを提供していることを確認してから成功を報告します。

タグが存在するが公開に失敗した場合(またはこのワークフローより前に作成されたタグの場合)、Actions → Release → Run workflow から再実行します。ブランチセレクターは main のままにし(ワークフローファイルはそこから読み込まれます)、入力にタグ名を渡します。2つの注意点があります: タグのツリーには後述の repository フィールドがすでに含まれている必要があり、provenanceの証明にはタグではなくワークフローのディスパッチ元のrefが記録されます。したがって、実際のリリースでは、バージョンを切り直してタグプッシュの経路を使用することをお勧めします。

公開は成功したが検証ステップが赤くなった場合(2分以上遅延したレジストリ)、何かをする前にnpmjs.comを確認してください。バージョンは公開されており、再実行すると設計上「すでにnpm上にある」ことを防ぐガードで失敗します。その場合、修正する必要はありません。

一度だけのセットアップ: ワークフローには、@instawp スコープに対する公開権限を持つnpm automationトークンが必要で、リポジトリのシークレット NPM_TOKEN(Settings → Secrets and variables → Actions)として保存されます。具体的にはautomationトークンが必要です。クラシックな公開トークンは、2FAが有効なアカウントではCIで失敗します。

npmの trusted publishing を使用すれば、保存されたトークンを完全に不要にできます。ただし、npm ≥ 11.5.1 が必要であり、setup-node は現在Node 22でnpm 10.xを提供しているため、ジョブ内でnpmもアップグレードしない限り、ここでは使用できません。

provenance付きで公開するには、package.json の repository フィールドがこのリポジトリと一致している必要があります。一致しない場合、レジストリは公開を拒否します。削除しないでください。

セキュリティ

  • APIキーやシークレットをバージョン管理にコミットしないでください。

  • クライアントとサーバー間の通信にはHTTPSを使用してください。

  • インジェクション攻撃を防ぐため、クライアントから受け取ったすべての入力を検証してください。

  • 適切なエラーハンドリングとレート制限を実装してください。

プロジェクト概要

アーキテクチャ

サーバーは複雑さを軽減するために統合ツールアーキテクチャを使用しています:

src/
├── server.ts                    # MCP server entry point
├── wordpress.ts                 # WordPress REST API client
├── cli.ts                      # CLI interface
├── config/
│   └── site-manager.ts         # Multi-site management
├── types/
│   └── wordpress-types.ts      # TypeScript definitions
└── tools/
    ├── index.ts                # Tool aggregation
    ├── site-management.ts      # Site management (3 tools)
    ├── unified-content.ts      # Universal content management (8 tools)
    ├── unified-taxonomies.ts   # Universal taxonomy management (8 tools)
    ├── media.ts               # Media management (5 canonical tools + edit_media alias)
    ├── users.ts               # User management (~5 tools)
    ├── comments.ts            # Comment management (~5 tools)
    ├── plugins.ts             # Plugin management (~5 tools)
    ├── plugin-repository.ts   # WordPress.org plugin search (~2 tools)
    └── sql-query.ts           # Database queries (1 tool)

主な機能

  • マルチサイトサポート: 単一のMCPサーバーインスタンスから複数のWordPressサイトを管理

  • スマートURL解決: URLからコンテンツタイプを自動的に検出し、対応するコンテンツを検索

  • ユニバーサルコンテンツ管理: 単一のツールセットで投稿、固定ページ、カスタム投稿タイプを処理

  • ユニバーサルタクソノミー管理: 単一のツールセットでカテゴリー、タグ、カスタムタクソノミーを処理

  • 型安全性: Zodスキーマ検証による完全なTypeScriptサポート

  • 包括的なロギング: デバッグ用の詳細なAPIリクエスト/レスポンスロギング

  • エラーハンドリング: 情報提供メッセージによるグレースフルなエラーハンドリング

はじめに

  1. リポジトリをクローンし、npm install で依存関係をインストールします

  2. WordPressの認証情報を記載した .env ファイルを作成します

  3. npm run build でプロジェクトをビルドします

  4. サーバーをClaude Desktopに設定します

  5. 自然言語でWordPressサイトを管理しましょう!

コントリビューション

このプロジェクトを改善するために、遠慮なくissueを開いたり、プルリクエストを作成したりしてください。詳細な開発ガイドラインについては CLAUDE.md を参照してください。

Related MCP Connectors

Related MCP Servers