Skip to main content
Glama
InstaWP

WordPress MCP Server

by InstaWP

Servidor MCP de WordPress

Este es un servidor de Model Context Protocol (MCP) para WordPress, que te permite interactuar con tu sitio de WordPress usando lenguaje natural a través de un cliente compatible con MCP como Claude Desktop. Este servidor expone varios datos y funcionalidades de WordPress como herramientas MCP.

Uso

Claude Desktop

  1. Descarga e instala Claude Desktop.

  2. Abre la configuración de Claude Desktop y navega a la pestaña "Developer".

  3. Copia el contenido del archivo claude_desktop_config.json.example.

  4. Haz clic en "Edit Config" para abrir el archivo claude_desktop_config.json.

  5. Copia y pega el contenido del archivo de ejemplo en el archivo de configuración. Asegúrate de reemplazar los valores de marcador de posición con tus valores reales para el sitio de WordPress. Para generar las claves de aplicación, sigue esta guía - Application Passwords.

  6. Guarda la configuración.

  7. Reinicia Claude Desktop.

Related MCP server: WordPress MCP Server

Características

Este servidor proporciona herramientas para interactuar con los datos principales de WordPress y admite gestión de múltiples sitios: gestiona varios sitios de WordPress desde una única instancia del servidor MCP.

Gestión de Múltiples Sitios (3 herramientas)

Gestiona varios sitios de WordPress desde un único servidor MCP:

  • list_sites: Lista todos los sitios de WordPress configurados

  • get_site: Obtiene detalles sobre una configuración de sitio específica

  • test_site: Prueba la conexión con un sitio de WordPress específico

Todas las herramientas de contenido y taxonomías admiten un parámetro opcional site_id para apuntar a sitios específicos.

Gestión Unificada de Contenido (9 herramientas)

Maneja TODOS los tipos de contenido (entradas, páginas, tipos de contenido personalizados) con un único conjunto de herramientas inteligentes:

  • list_content: Lista cualquier tipo de contenido con filtrado y paginación

  • get_content: Obtiene contenido específico por ID y tipo

  • create_content: Crea contenido nuevo de cualquier tipo

  • update_content: Actualiza contenido existente de cualquier tipo, incluyendo ediciones parciales específicas

  • delete_content: Elimina contenido de cualquier tipo

  • discover_content_types: Encuentra todos los tipos de contenido disponibles en tu sitio

  • find_content_by_url: Resolvedor de URL inteligente que puede encontrar y opcionalmente actualizar contenido desde cualquier URL de WordPress, incluyendo ediciones parciales específicas

  • get_content_by_slug: Busca por slug en todos los tipos de contenido

  • get_content_summary: Devuelve un resumen mínimo (id, título, slug, estado, extracto, taxonomías, recuento de palabras, campos de Yoast SEO) para flujos de trabajo de auditoría y consulta. Busca por id o url.

Gestión Unificada de Taxonomías (8 herramientas)

Maneja TODAS las taxonomías (categorías, etiquetas, taxonomías personalizadas) con un único conjunto de herramientas:

  • discover_taxonomies: Encuentra todas las taxonomías disponibles en tu sitio

  • list_terms: Lista términos en cualquier taxonomía

  • get_term: Obtiene un término específico por ID

  • create_term: Crea un término nuevo en cualquier taxonomía

  • update_term: Actualiza un término existente

  • delete_term: Elimina un término de cualquier taxonomía

  • assign_terms_to_content: Asigna términos a cualquier tipo de contenido

  • get_content_terms: Obtiene todos los términos de cualquier contenido

Herramientas Especializadas

  • Medios:

    • list_media: Lista todos los elementos multimedia (admite paginación y búsqueda).

    • get_media: Recupera un elemento multimedia específico por ID.

    • create_media: Crea un elemento multimedia nuevo desde una URL o una ruta de archivo local.

    • update_media: Actualiza un elemento multimedia existente.

    • delete_media: Elimina un elemento multimedia.

    • edit_media: Alias heredado de update_media que se mantiene por compatibilidad con versiones anteriores.

  • Usuarios:

    • list_users: Lista todos los usuarios con opciones de filtrado, ordenación y paginación.

    • get_user: Recupera un usuario específico por ID.

    • create_user: Crea un usuario nuevo.

    • update_user: Actualiza un usuario existente.

    • delete_user: Elimina un usuario.

  • Comentarios:

    • list_comments: Lista todos los comentarios con opciones de filtrado, ordenación y paginación.

    • get_comment: Recupera un comentario específico por ID.

    • create_comment: Crea un comentario nuevo.

    • update_comment: Actualiza un comentario existente.

    • delete_comment: Elimina un comentario.

  • Plugins:

    • list_plugins: Lista todos los plugins instalados en el sitio.

    • get_plugin: Recupera detalles sobre un plugin específico.

    • activate_plugin: Activa un plugin.

    • deactivate_plugin: Desactiva un plugin.

    • create_plugin: Crea un plugin nuevo.

  • Repositorio de Plugins:

  • search_plugins: Busca plugins en el repositorio de WordPress.org.

  • get_plugin_info: Obtiene información detallada sobre un plugin del repositorio.

  • Consultas a la Base de Datos:

  • execute_sql_query: Ejecuta consultas SQL de solo lectura contra la base de datos de WordPress (requiere configuración de un endpoint personalizado).

Ventajas Clave

Flujos de Trabajo de Carga de Medios

Sube una captura de pantalla local desde la misma máquina que ejecuta el servidor MCP:

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

Sube medios desde una URL remota:

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

Usa el ID de medio devuelto como medio destacado en contenido nuevo:

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

Resolución Inteligente de URL

La herramienta find_content_by_url puede:

  • Tomar cualquier URL de WordPress y encontrar automáticamente el contenido correspondiente

  • Detectar tipos de contenido a partir de patrones de URL (p. ej., /documentation/ → tipo de contenido personalizado documentation)

  • Opcionalmente actualizar el contenido en una sola operación

  • Funciona con entradas, páginas y cualquier tipo de contenido personalizado

Resúmenes de Auditoría y Consulta

La herramienta get_content_summary devuelve una representación mínima y de forma fija de una sola pieza de contenido. Diseñada para flujos de trabajo de auditoría y consulta donde la respuesta REST completa de WP — que puede superar los 50KB en entradas de recetas debido al HTML renderizado de la tarjeta de Recipe Maker — es excesiva.

Consulta por ID (con content_type opcional, que por defecto es post):

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

Consulta por URL (el tipo de contenido se detecta a partir de la URL):

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

id y url son mutuamente excluyentes: proporciona exactamente uno.

La forma de la respuesta es fija:

{
  "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."
}

Notas sobre los campos:

  • title y excerpt se reducen a texto plano (se eliminan las etiquetas HTML y se decodifican las entidades básicas).

  • word_count prefiere yoast_head_json.schema.@graph[].wordCount cuando Yoast SEO está activo; de lo contrario, se calcula a partir del contenido renderizado de la entrada con el HTML eliminado.

  • yoast_meta_title y yoast_meta_description se leen de yoast_head_json en la entrada. Son null cuando Yoast SEO no está activo.

  • yoast_focus_keyword se lee de meta._yoast_wpseo_focuskw. El núcleo de WordPress solo expone las claves de metadatos que están registradas con show_in_rest, y Yoast SEO no registra esta clave por defecto, por lo que este campo normalmente será null a menos que un plugin complementario la registre (consulta el PR #17 para obtener contexto sobre el problema más amplio de exposición de claves de metadatos en REST).

  • Esta herramienta omite internamente el recorte de respuesta añadido en el PR #16 para poder leer yoast_head_json. El recorte sigue aplicándose a todas las demás herramientas.

Operaciones Universales de Contenido

Todas las operaciones de contenido usan un único parámetro 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
}

Ediciones de Contenido Específicas

update_content y find_content_by_url.update_fields pueden modificar el contenido bruto existente de WordPress sin reenviar el documento completo.

Para facilitar la coincidencia exacta, tanto get_content como find_content_by_url aceptan include_raw_content: true. Cuando está habilitado, la respuesta se obtiene con el contexto de edición de WordPress e incluye un campo de nivel superior content_raw que coincide con lo que necesita content_edit.target_text.

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

Añade una nota de versión corta al final de una entrada:

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

Reemplaza un fragmento HTML único o un comentario de marcador en su lugar:

{
  "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"
  }
}

Notas:

  • El HTML renderizado de WordPress puede diferir de content.raw porque las entidades pueden estar escapadas y el marcado puede estar expandido, así que usa include_raw_content cuando necesites un target_text exacto.

  • target_text coincide exactamente con el contenido bruto almacenado de WordPress.

  • Si el mismo target_text aparece varias veces, pasa occurrence para elegir la coincidencia basada en 1.

  • Para entradas almacenadas como bloques de Gutenberg, establece content_edit.convert_to_blocks al insertar Markdown o HTML que deba convertirse en bloques.

Operaciones Universales de Taxonomías

Todas las operaciones de taxonomías usan un único parámetro taxonomy:

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

El parámetro taxonomy acepta tanto el slug de la taxonomía como su rest_base (pueden diferir para taxonomías personalizadas, p. ej., slug documentation_category con rest_base documentation-categories). Las herramientas resuelven el identificador mediante /wp/v2/taxonomies y generan un error en taxonomías desconocidas en lugar de adivinar. assign_terms_to_content verifica la escritura contra la respuesta de WordPress e informa de un error si los términos no se guardaron realmente.

Tarjetas de Recetas (WP Recipe Maker)

Los sitios que ejecutan WP Recipe Maker (WPRM) almacenan las tarjetas de recetas en un tipo de contenido personalizado separado wprm_recipe al que se hace referencia mediante shortcode desde la entrada de blog circundante. Las herramientas de contenido unificadas manejan estas recetas directamente: no se necesita una familia de herramientas específica para recetas.

Lectura de recetasget_content, list_content, find_content_by_url y get_content_by_slug funcionan todas con content_type: "wprm_recipe". WPRM expone el payload completo de receta estructurada como un campo recipe en la respuesta REST, incluyendo ingredientes, instrucciones, tiempos, equipo, nutrición, notas y valoración.

Escritura de recetas — pasa el payload de la receta mediante custom_fields.recipe en create_content o update_content. WPRM se engancha a la acción de inserción REST de WordPress (rest_insert_wprm_recipe) y lee recipe de la raíz del cuerpo de la solicitud, por lo que se acepta cualquier campo documentado por el modelo de datos de WPRM.

El payload recipe debe pasarse mediante custom_fields (que se expande en la raíz del cuerpo de la solicitud). El parámetro meta anida sus valores bajo una clave meta, que nunca llega al enganche REST de WPRM.

Ejemplo de actualización:

{
  "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."
    }
  }
}

Ingredientes e instrucciones agrupados — las recetas pueden dividir los elementos en grupos con nombre como "Para la salsa" / "Para el pollo". Cada entrada en el array externo ingredients (o instructions) es un grupo con su propio name y array interno:

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

Campos de receta de uso común:

Campo

Tipo

Notas

name

string

Título de la tarjeta de receta

summary

string

Descripción breve (se permite HTML)

servings

string

p. ej., "4"

servings_unit

string

p. ej., "people", "servings"

prep_time

string

minutos, p. ej., "15"

cook_time

string

minutos

total_time

string

minutos

ingredients

array de grupos

estructura anidada mostrada arriba

instructions

array de grupos

estructura anidada mostrada arriba

notes

string

se permite HTML

equipment

array

elementos con forma { id, name, notes, amount, uid }

image_url

string

carga por URL cuando no se proporciona image_id

Curso, cocina y palabra clave se almacenan como taxonomías de WPRM (wprm_course, wprm_cuisine, wprm_keyword). Gestiona las con las herramientas de taxonomía unificadas (list_terms, create_term, …) y vincúlalas a una receta con assign_terms_to_content.

WPRM sincroniza automáticamente recipe.summary de vuelta al campo post_content de WordPress al guardar. Si quieres que el cuerpo de la entrada y el resumen de la receta difieran, pasa content explícitamente junto con custom_fields.recipe.

Configuración

Configuración de Sitio Único

Para gestionar un único sitio de WordPress, usa las siguientes variables de entorno:

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

Configuración de Múltiples Sitios

Para gestionar varios sitios de WordPress desde un único servidor MCP, usa variables de entorno numeradas:

# 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

Opciones de Configuración de Múltiples Sitios:

  • WORDPRESS_N_URL: URL del sitio WordPress (obligatorio)

  • WORDPRESS_N_USERNAME: nombre de usuario de WordPress (obligatorio)

  • WORDPRESS_N_PASSWORD: contraseña de aplicación de WordPress (obligatorio)

  • WORDPRESS_N_ID: identificador del sitio (opcional, por defecto siteN)

  • WORDPRESS_N_DEFAULT: establézcalo en true para que este sea el sitio por defecto (opcional, el primer sitio es el predeterminado)

  • WORDPRESS_N_ALIASES: alias separados por comas para la detección de sitios (opcional)

El servidor admite hasta 10 sitios. Al usar la configuración de varios sitios, todas las herramientas aceptan un parámetro opcional site_id para apuntar a sitios específicos.

Uso con npx y archivo .env

Puede ejecutar este servidor MCP directamente con npx sin necesidad de instalarlo globalmente:

npx -y @instawp/mcp-wp

Asegúrese de tener un archivo .env en su directorio actual con las siguientes variables:

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

Agente de usuario

Cada solicitud saliente que hace este servidor (el cliente REST de WordPress usado por todas las herramientas, el endpoint SQL, las dos consultas a api.wordpress.org y las descargas de medios remotos) envía el agente de usuario predeterminado de axios axios/<version>.

Establezca WORDPRESS_USER_AGENT para sobrescribirlo en todos los casos:

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

Déjelo sin establecer a menos que un CDN o WAF frente a su sitio rechace el valor predeterminado; un valor vacío o con solo espacios en blanco se trata como no establecido. Evite un Mozilla/5.0 simple: es una firma de bot muy conocida y es exactamente lo que varios bordes de red bloquean (ver #28), por eso aquí no se envía ninguno.

Recorte de respuestas

De forma predeterminada, el servidor elimina los campos de nivel superior yoast_head y yoast_head_json de cada respuesta de la API REST de WordPress antes de devolverla al cliente MCP. Estos campos contienen el marcado de esquema pre-renderizado de Yoast SEO, que el LLM casi nunca necesita pero por el que paga tokens en cada solicitud.

  • El recorte se aplica tanto a respuestas de objetos individuales como a matrices de objetos.

  • Solo se eliminan los campos de nivel superior; los objetos anidados no se modifican.

  • Sobrescriba la lista con la variable de entorno MCP_WP_STRIP_FIELDS (separada por comas). Establézcala en una cadena vacía para desactivar el recorte por completo.

Limitaciones del campo meta

El parámetro meta en create_content, update_content y find_content_by_url (con update_fields.meta) se reenvía directamente al endpoint /wp/v2/{type}/{id} de WordPress. El núcleo de WordPress descarta silenciosamente cualquier clave meta que no haya sido registrada mediante register_post_meta(..., ['show_in_rest' => true]). El servidor MCP no tiene ninguna lista de permitidos propia: depende de WordPress para aplicar qué claves persisten.

Esto significa que las claves de los plugins de SEO no se pueden escribir a través de este servidor MCP de forma predeterminada, incluyendo:

  • 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+): almacena los datos de SEO en una tabla personalizada (wp_aioseo_posts), no en wp_postmeta; no se puede acceder a ellos mediante el campo meta de ninguna manera.

El servidor detecta cuando WordPress descarta claves que usted envió y antepone un bloqueo Warning: al resultado de la herramienta enumerándolas. Esto hace visible el descarte silencioso para el llamador del LLM, pero no puede hacer que WordPress acepte las claves.

Para habilitar la escritura de metadatos de SEO, instale un pequeño plugin complementario de WordPress que llame a register_post_meta para cada clave deseada con show_in_rest => true y un auth_callback apropiado. Se está desarrollando un plugin separado mcp-wp-seo-bridge para hacer exactamente esto.

Qué claves funcionan hoy

Las claves de plugins que el autor del plugin ya registró para REST, por ejemplo, los metadatos de diseño de Genesis (_genesis_layout), los campos de WP Recipe Maker (wprm-*) o los de ConvertKit (_wp_convertkit_post_meta). Para comprobar qué claves hacen el viaje de ida y vuelta en su sitio, escriba un valor de prueba mediante update_content e inspeccione el bloque meta en la respuesta: si la clave aparece, persistió.

La misma limitación se aplica a los metadatos de términos en las herramientas unified-taxonomies (create_term, update_term).

Habilitación de la herramienta de consulta SQL (opcional)

La herramienta execute_sql_query le permite ejecutar consultas SQL de solo lectura contra su base de datos de WordPress. Esta es una función opcional que requiere agregar un endpoint personalizado de la API REST a su sitio de WordPress.

Notas de seguridad:

  • Esta herramienta solo acepta consultas de solo lectura (SELECT, WITH...SELECT, EXPLAIN) por seguridad

  • Las consultas que contengan INSERT, UPDATE, DELETE, DROP u otras declaraciones modificadoras serán rechazadas

  • Las consultas de múltiples declaraciones están bloqueadas para prevenir la inyección SQL

  • Las consultas y los resultados se registran en logs/wordpress-api.log; evite incluir datos sensibles en las consultas

  • Esta herramienta requiere permisos de nivel administrador (manage_options)

Configuración: De forma predeterminada, la herramienta espera el endpoint en /mcp/v1/query. Puede personalizarlo estableciendo la variable de entorno WORDPRESS_SQL_ENDPOINT (por ejemplo, WORDPRESS_SQL_ENDPOINT=/custom/v1/query).

Para habilitar esta función, agregue el siguiente código a su sitio de WordPress (mediante un plugin personalizado o el archivo functions.php de su tema):

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');
        }
    ));
});

Después de agregar este código, puede usar la herramienta execute_sql_query para ejecutar consultas como:

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

Desarrollo

Requisitos previos

  • Node.js y npm: asegúrese de tener Node.js (versión 18 o superior) y npm instalados. Node 18 es suficiente para ejecutar el servidor. Contribuir requiere Node 20 o superior, porque las herramientas de prueba (Vitest 4) lo requieren; CI ejecuta 20.x y 22.x.

  • Sitio de WordPress: necesita un sitio de WordPress activo con la API REST habilitada.

  • Autenticación de la API de WordPress: configure la autenticación para la API REST de WordPress. Esto normalmente requiere un plugin o método de autenticación (como Application Passwords).

  • Cliente MCP: necesita una aplicación que pueda comunicarse con el servidor MCP. Actualmente, se recomienda Claude Desktop.

Instalación y configuración

  1. Clone el repositorio:

    git clone <repository_url>
    cd wordpress-mcp-server
  2. Instale las dependencias:

    npm install
  3. Cree un archivo .env:

    Cree un archivo .env en el directorio raíz de su proyecto y agregue sus credenciales de la API de WordPress.

    Para un solo sitio:

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

    Para varios sitios:

    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

    Reemplace los marcadores de posición con sus valores reales.

  4. Compile el servidor:

    npm run build
  5. Configure Claude Desktop:

    • Abra la configuración de Claude Desktop y navegue hasta la pestaña "Developer".

    • Haga clic en "Edit Config" para abrir el archivo claude_desktop_config.json.

    • Agregue una nueva configuración de servidor en la sección mcpServers. Deberá proporcionar la ruta absoluta al archivo build/server.js y sus variables de entorno de WordPress.

    • Guarde la configuración.

Ejecución del servidor

Una vez que haya configurado Claude Desktop, el servidor debería iniciarse automáticamente cada vez que Claude Desktop se inicie.

También puede ejecutar el servidor directamente desde la línea de comandos para realizar pruebas:

npm start

o en modo de desarrollo:

npm run dev

Ejecución de pruebas

El repositorio usa Vitest para pruebas unitarias. Las pruebas se encuentran en tests/ y cubren el SiteManager de varios sitios y el registro de herramientas MCP.

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

Las pruebas se ejecutan en pull_request y en los envíos a main mediante .github/workflows/test.yml.

Publicación de versiones

Fusionar una corrección no llega a nadie: npm sigue sirviendo la última versión publicada hasta que se ejecuta una publicación. La publicación está automatizada por .github/workflows/release.yml, activada por una etiqueta de versión:

# 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

Haga la edición del CHANGELOG antes de npm version. Modificar el commit después deja la etiqueta apuntando al commit anterior a la modificación, y el flujo de trabajo publicaría desde ese.

El flujo de trabajo se niega a publicar si la etiqueta y package.json no coinciden, o si esa versión ya está en npm; luego compila, ejecuta las pruebas, publica con procedencia y confirma que el registro realmente sirve la nueva versión antes de informar éxito.

Si una etiqueta existe pero la publicación falló (o es anterior a este flujo de trabajo), vuelva a ejecutarlo desde Actions → Release → Run workflow, dejando el selector de rama en main (ahí es donde se lee el archivo del flujo de trabajo) y pasando el nombre de la etiqueta en la entrada. Dos advertencias: el árbol de la etiqueta ya debe contener el campo repository descrito a continuación, y la atestación de procedencia registra la ref desde la que se despachó el flujo de trabajo, no la etiqueta; por lo tanto, para una publicación real, prefiera volver a cortar una versión y usar la ruta de envío de etiqueta.

Si la publicación tiene éxito pero el paso de verificación se pone en rojo (un registro que permaneció lento durante más de dos minutos), verifique npmjs.com antes de hacer nada: la versión está publicada, y volver a ejecutarlo ahora fallará por diseño con la protección de ya-en-npm. No hay nada que arreglar en ese caso.

Configuración, una vez: el flujo de trabajo necesita un token de automatización de npm con derechos de publicación en el ámbito @instawp, almacenado como secreto de repositorio NPM_TOKEN (Settings → Secrets and variables → Actions). Específicamente un token de automatización: un token de publicación clásico falla en CI en una cuenta con 2FA obligatorio.

La publicación de confianza de npm eliminaría el token almacenado por completo, pero requiere npm ≥ 11.5.1 y setup-node actualmente incluye npm 10.x con Node 22, por lo que no es utilizable aquí sin también actualizar npm dentro del trabajo.

Publicar con procedencia requiere que el campo repository en package.json coincida con este repositorio; el registro rechaza la publicación de otro modo. No lo elimine.

Seguridad

  • Nunca confíe sus claves de API o secretos al control de versiones.

  • Use HTTPS para la comunicación entre el cliente y el servidor.

  • Valide todas las entradas recibidas del cliente para prevenir ataques de inyección.

  • Implemente un manejo de errores adecuado y limitación de velocidad.

Resumen del proyecto

Arquitectura

El servidor usa una arquitectura de herramientas unificada para reducir la complejidad:

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)

Características clave

  • Soporte de varios sitios: administre múltiples sitios de WordPress desde una sola instancia del servidor MCP

  • Resolución inteligente de URL: detecte automáticamente los tipos de contenido a partir de las URL y encuentre el contenido correspondiente

  • Gestión de contenido universal: un solo conjunto de herramientas maneja entradas, páginas y tipos de contenido personalizados

  • Gestión de taxonomías universal: un solo conjunto de herramientas maneja categorías, etiquetas y taxonomías personalizadas

  • Seguridad de tipos: soporte completo de TypeScript con validación de esquemas Zod

  • Registro integral: registro detallado de solicitudes/respuestas de API para depuración

  • Manejo de errores: manejo de errores elegante con mensajes informativos

Primeros pasos

  1. Clone el repositorio e instale las dependencias con npm install

  2. Cree un archivo .env con sus credenciales de WordPress

  3. Compile el proyecto con npm run build

  4. Configure Claude Desktop con el servidor

  5. ¡Comience a usar lenguaje natural para administrar su sitio de WordPress!

Contribución

Siéntase libre de abrir problemas o hacer solicitudes de extracción para mejorar este proyecto. Consulte CLAUDE.md para obtener pautas de desarrollo detalladas.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
3wRelease cycle
4Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables AI assistants to interact with WordPress sites through the WordPress REST API. Supports multiple WordPress sites with secure authentication, enabling content management, post operations, and site configuration through natural language.
    24
    116
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with WordPress sites through the REST API. Supports multiple WordPress sites with secure authentication, enabling content management, post operations, and site configuration through natural language.
    24
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables interaction with WordPress sites through the REST API, supporting content management for posts, pages, users, plugins, and custom post types with Application Password authentication.
    1,270
    2
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to manage WordPress sites through natural conversation, supporting post creation, content updates, site queries, and draft-to-publish workflows via the WordPress REST API.
    9
    MIT

View all related MCP servers

Related MCP Connectors

  • Sync Lightroom, Figma, Dropbox & Canva assets to WordPress and Shopify via natural language.

  • Sync Lightroom, Figma, Dropbox & Canva assets to WordPress and Shopify via natural language.

  • Publish to self-hosted WordPress from AI agents: markdown, images, SEO, and Notion sync.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/InstaWP/mcp-wp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server