亚马逊云科技

广告

安信SSL证书

广告

MCP服务器搭建教程(用AI轻松管理WordPress主机)

美国云服务器推荐

对于大部分站群用户来说,网站管理的便捷性变成了首要考虑因素。本文将通过实际示例,一步步教大家构建自己的MCP服务器,可将Claude等AI助手与Kinsta API连接,轻松处理机构日常的WordPress主机管理任务。

MCP服务器可以让AI助手执行以下操作:

  • 列出账户下的所有WordPress站点
  • 显示特定站点的环境信息
  • 清除指定环境中的缓存
  • 克隆现有站点,快速启动新站点
  • 查看哪些插件和主题已过时或存在安全漏洞
  • 在特定环境中触发插件更新

服务器设置完成后,将连接到MCP主机/客户端(本文以Claude for Desktop为例),具体交互流程如下:

1、Claude在接收提示时,会调用MCP工具检索外部数据;

调用MCP工具检索外部数据

2、Claude根据检索到的工具数据,生成结构化响应并展示给用户。

生成结构化响应

在深入代码编写前,务必了解MCP在这套设置中的作用:并非替换现有API或改变其工作方式,而是在AI助手与API之间搭建桥梁,提供一组AI可按需调用的工具。每个工具对应一项特定操作(如列出站点、清除缓存)。

当向AI助手提出问题时,助手会判断是否需要调用相关工具。若需要,会通过MCP服务器调用该工具,服务器与API通信后,将结果以简洁易懂的形式返回给AI。所有操作均需经过批准方可执行,且仅公开预设工具供调用。

本文示例中,MCP服务器与Kinsta API通信,公开有限的WordPress主机管理操作,无需自定义UI、后台自动化或特殊AI设置,上手门槛极低。

一、MCP服务器搭建前提条件

要跟随本文操作,需要准备以下几项:

1、稳定的Node.js环境

2、基础的TypeScript知识

3、已启用API访问权限的Kinsta账户

Kinsta(直达官网)提供专业的WordPress托管服务,即便在高并发场景下,也能确保网站稳定运行。可浏览Kinsta的托管方案,或联系销售团队,找到最适合配置。

选择Kinsta WordPress托管服务,将获得:

  • MyKinsta控制面板,所有操作一键掌控;
  • 专业迁移团队提供的无限次免费迁移服务;
  • WordPress专家7×24×365全天候技术支持;
  • 强大的云基础设施和尖端服务器,保障性能;
  • 集成Cloudflare,提供企业级安全防护;
  • 全球27个数据中心,覆盖全球用户,降低访问延迟。

相关阅读:

Kinsta主机综合评测(定价/功能/特点/性能/速度)

Kinsta主机免费30天方案领取教程

WordPress网站迁移至Kinsta主机图文教程

4、获取Kinsta API密钥和公司ID:

  • 前往您的MyKinsta仪表板;
  • 导航至API密钥页面(您的姓名 > 公司设置 > API密钥);
  • 单击创建API密钥;
  • 选择到期时间,或设置自定义开始日期以及密钥的到期小时数;
  • 为密钥指定一个唯一名称;
  • 单击生成。

获取Kinsta API密钥

二、项目设置

首先,为项目创建新目录并初始化Node.js应用,执行以下命令:

mkdir kinsta-mcp
cd kinsta-mcp
npm init -y

接下来,安装MCP SDK及所需依赖:

npm install @modelcontextprotocol/sdk zod@3
npm install -D typescript @types/node

创建基本项目结构:

mkdir src
touch src/index.ts

然后更新package.json文件,确保Node能运行构建后的服务器,更新后的内容如下:

{
“name”: “kinsta-mcp-server”,
“version”: “1.0.0”,
“description”: “MCP server for managing WordPress sites via the Kinsta API”,
“type”: “module”,
“scripts”: {
“build”: “tsc”
},
“dependencies”: {
“@modelcontextprotocol/sdk”: “^1.0.0”,
“zod”: “^3.24.0”
},
“devDependencies”: {
“@types/node”: “^22.0.0”,
“typescript”: “^5.0.0”
}
}

最后,在项目根目录添加tsconfig.json文件,配置如下:

{
“compilerOptions”: {
“target”: “ES2022”,
“module”: “Node16”,
“moduleResolution”: “Node16”,
“outDir”: “./build”,
“rootDir”: “./src”,
“strict”: true,
“esModuleInterop”: true,
“skipLibCheck”: true,
“forceConsistentCasingInFileNames”: true
},
“include”: [“src/**/*”],
“exclude”: [“node_modules”]
}

完成以上配置后,即可开始构建MCP服务器本身。

三、构建MCP服务器

项目设置完成后,Kinsta开始搭建MCP服务器:首先导入所需包并创建服务器实例,然后添加API通信辅助函数,最后注册对应WordPress主机操作的工具。

步骤1:导入包并创建服务器

打开src/index.ts文件,在文件顶部添加以下导入语句(修正原文笔误,补充完整依赖):

import { McpServer } from “@modelcontextprotocol/sdk/server/mcp.js”;
import { StdioServerTransport } from “@modelcontextprotocol/sdk/server/stdio.js”;
import { z } from “zod”;

这些模块的作用如下:

  • McpServer:核心服务器,负责注册工具、处理AI客户端的请求;
  • StdioServerTransport:允许服务器通过标准输入/输出通信,适配大多数桌面AI客户端;
  • zod:用于定义和验证每个工具接受的输入参数,确保输入有效。

接下来,定义API和凭据相关常量:

const KINSTA_API_BASE = “https://api.kinsta.com/v2”;
const KINSTA_API_KEY = process.env.KINSTA_API_KEY;
const KINSTA_COMPANY_ID = process.env.KINSTA_COMPANY_ID;

创建MCP服务器实例:

const server = new McpServer({
name: “kinsta”,
version: “1.0.0”,
});

其中,name决定服务器在MCP客户端中的显示名称,version为可选版本号,便于后续迭代开发时区分。

步骤2:添加API请求辅助函数

Kinsta构建的多数工具都需要向Kinsta API发送HTTP请求,为避免重复编写代码,创建一个通用辅助函数,添加在服务器实例下方:

async function kinstaRequest(
endpoint: string,
options: RequestInit = {}
): Promise {
const url = `${KINSTA_API_BASE}${endpoint}`;
const headers = {
Authorization: `Bearer ${KINSTA_API_KEY}`,
“Content-Type”: “application/json”,
…options.headers,
};

const response = await fetch(url, { …options, headers });

if (!response.ok) {
const errorText = await response.text();
throw new Error(`Kinsta API error (${response.status}): ${errorText}`);
}

return response.json() as Promise;
}

步骤3:实现工具执行(核心环节)

工具是MCP服务器公开的核心功能,每个工具对应一个特定操作,AI助手获得批准后即可调用。每个工具均包含以下4个部分:

  • 工具名称(如list_sites,便于AI识别);
  • 简短描述(帮助AI助手判断何时使用该工具);
  • 输入模式(验证输入有效性,避免无效操作);
  • 处理函数(调用API并格式化输出,便于AI和用户理解)。

注意:Kinsta将响应格式化为纯文本,而非原始JSON——这样AI助手能更高效地处理结果,也更适合在聊天界面展示。

工具1:列出所有WordPress站点

该工具用于检索公司账户下的所有WordPress站点,是多站点管理的基础操作(多数其他操作需以站点ID为前提)。

首先定义API响应的接口结构:

interface Site {
id: string;
name: string;
display_name: string;
status: string;
site_labels: Array;
}

interface ListSitesResponse {
company: {
sites: Site[];
};
}

然后注册该工具:

server.registerTool(
“list_sites”,
{
description:
“Get all WordPress sites for your company. Returns site IDs, names, and status.”,
inputSchema: {},
},
async () => {
const data = await kinstaRequest(
`/sites?company=${KINSTA_COMPANY_ID}`
);

const sites = data.company.sites;

if (!sites || sites.length === 0) {
return {
content: [
{ type: “text”, text: “No sites found for this company.” }
],
};
}

const siteList = sites
.map((site) => {
const labels =
site.site_labels?.map((l) => l.name).join(“, “) || “none”;

return `• ${site.display_name} (${site.name})
ID: ${site.id}
Status: ${site.status}
Labels: ${labels}`;
})
.join(“\n\n”);

return {
content: [
{
type: “text”,
text: `Found ${sites.length} site(s):\n\n${siteList}`,
},
],
};
}
);

该工具无需输入参数,调用API后会将站点信息格式化为可读文本,AI助手可直接用于回答“我的账户有哪些站点?”等问题,无需额外解析。

工具2:获取指定站点的环境

获取站点ID后,通常需要查看其环境信息(如正式环境、测试环境),该工具可返回指定站点的所有环境详情。

定义API响应接口结构:

interface Environment {
id: string;
name: string;
display_name: string;
is_premium: boolean;
primaryDomain?: {
id: string;
name: string;
};
container_info?: {
php_engine_version: string;
};
}

interface GetEnvironmentsResponse {
site: {
environments: Environment[];
};
}

注册工具(需传入站点ID作为输入):

server.registerTool(
“get_environments”,
{
description:
“Get environments (live, staging) for a specific site. Requires the site ID.”,
inputSchema: {
site_id: z.string().describe(“The site ID to get environments for”),
},
},
async ({ site_id }) => {
const data = await kinstaRequest(
`/sites/${site_id}/environments`
);

const envs = data.site.environments;

if (!envs || envs.length === 0) {
return {
content: [
{ type: “text”, text: “No environments found for this site.” }
],
};
}

const envList = envs
.map((env) => {
const domain = env.primaryDomain?.name || “No domain”;
const php = env.container_info?.php_engine_version || “Unknown”;
const type = env.is_premium
? “Premium Staging”
: env.name === “live”
? “Live”
: “Staging”;

return `• ${env.display_name} (${type})
ID: ${env.id}
Domain: ${domain}
PHP: ${php}`;
})
.join(“\n\n”);

return {
content: [
{
type: “text”,
text: `Found ${envs.length} environment(s):\n\n${envList}`,
},
],
};
}
);

该工具是执行清除缓存、克隆站点、更新插件等操作的前置步骤,可快速获取环境ID和相关配置。

工具3:清除站点环境缓存

清除缓存是日常例行操作,且为异步操作——触发后API立即返回操作ID,缓存清除在后台执行。

定义接口结构并注册工具:

interface OperationResponse {
operation_id: string;
message: string;
status: number;
}

server.registerTool(
“clear_site_cache”,
{
description:
“Clear the cache for a site environment. Requires the environment ID.”,
inputSchema: {
environment_id: z
.string()
.describe(“The environment ID to clear cache for”),
},
},
async ({ environment_id }) => {
const data = await kinstaRequest(
“/sites/tools/clear-cache”,
{
method: “POST”,
body: JSON.stringify({ environment_id }),
}
);

return {
content: [
{
type: “text”,
text: `Cache clear initiated!

Operation ID: ${data.operation_id}
Message: ${data.message}

Use get_operation_status to check progress.`,
},
],
};
}
);

工具不等待操作完成,直接返回操作ID,既保证交互速度,也方便AI助手后续跟进进度。

工具4:克隆现有站点

克隆站点是机构常用操作(如使用模板创建新客户站点),无需从零搭建,可基于现有环境快速生成新站点,复用之前的OperationResponse接口结构。

server.registerTool(
“clone_site”,
{
description:
“Clone an existing site environment to create a new site. Great for spinning up new client sites from a template.”,
inputSchema: {
display_name: z
.string()
.describe(“Name for the new cloned site”),
source_env_id: z
.string()
.describe(“The environment ID to clone from”),
},
},
async ({ display_name, source_env_id }) => {
const data = await kinstaRequest(
“/sites/clone”,
{
method: “POST”,
body: JSON.stringify({
company: KINSTA_COMPANY_ID,
display_name,
source_env_id,
}),
}
);

return {
content: [
{
type: “text”,
text: `Site clone initiated!

New site: ${display_name}
Operation ID: ${data.operation_id}
Message: ${data.message}

Use get_operation_status to check progress.`,
},
],
};
}
);

该工具可与其他工具配合使用,例如AI助手可先克隆站点,操作完成后立即列出环境、检查插件状态,形成完整工作流。

工具5:检查异步操作状态

缓存清除、站点克隆等操作为异步执行,需通过该工具查看进度,定义接口结构并注册:

interface OperationStatusResponse {
status?: number;
message?: string;
}

server.registerTool(
“get_operation_status”,
{
description:
“Check the status of an async operation (cache clear, site clone, etc.)”,
inputSchema: {
operation_id: z
.string()
.describe(“The operation ID to check”),
},
},
async ({ operation_id }) => {
const response = await fetch(
`${KINSTA_API_BASE}/operations/${encodeURIComponent(operation_id)}`,
{
headers: {
Authorization: `Bearer ${KINSTA_API_KEY}`,
},
}
);

const data: OperationStatusResponse = await response.json();

if (response.status === 200) {
return {
content: [
{
type: “text”,
text: `Operation completed successfully!

Message: ${data.message || “Operation finished”}`,
},
],
};
}

if (response.status === 202) {
return {
content: [
{
type: “text”,
text: `Operation still in progress…

Message: ${data.message || “Processing”}`,
},
],
};
}

return {
content: [
{
type: “text”,
text: `Operation status: ${response.status}

Message: ${data.message || “Unknown status”}`,
},
],
};
}
);

工具6:获取所有站点的插件信息

管理多个WordPress站点时,插件是常见问题来源。该工具可查看整个公司账户下的所有插件,包括安装环境、更新状态和安全漏洞。

定义接口结构并注册工具:

interface PluginEnvironment {
id: string;
site_display_name: string;
display_name: string;
plugin_status: string;
plugin_update: string | null;
plugin_version: string;
is_plugin_version_vulnerable: boolean;
plugin_update_version: string | null;
}

interface Plugin {
name: string;
title: string;
latest_version: string | null;
is_latest_version_vulnerable: boolean;
environment_count: number;
update_count: number;
environments: PluginEnvironment[];
}

interface GetPluginsResponse {
company: {
plugins: {
total: number;
items: Plugin[];
};
};
}

该工具本身不接受任何输入:

server.registerTool(
“get_plugins”,
{
description:
“Get all WordPress plugins across all sites. Shows which plugins have updates available or security vulnerabilities.”,
inputSchema: {},
},
async () => {
const data = await kinstaRequest(
`/company/${KINSTA_COMPANY_ID}/wp-plugins`
);

const plugins = data.company.plugins.items;

if (!plugins || plugins.length === 0) {
return {
content: [
{ type: “text”, text: “No plugins found.” }
],
};
}

const sorted = […plugins].sort(
(a, b) => b.update_count – a.update_count
);

const pluginList = sorted.slice(0, 20).map((plugin) => {
const status =
plugin.update_count > 0
? `⚠️ ${plugin.update_count} site(s) need update`
: “✅ Up to date”;

const vulnerable =
plugin.is_latest_version_vulnerable ? ” 🔴 VULNERABLE” : “”;

return `• ${plugin.title} (${plugin.name})${vulnerable}
Latest: ${plugin.latest_version || “unknown”}
Installed on: ${plugin.environment_count} environment(s)
${status}`;
}).join(“\n\n”);

const outdatedCount = plugins.filter(
(p) => p.update_count > 0
).length;

return {
content: [
{
type: “text”,
text: `Found ${data.company.plugins.total} plugins (${outdatedCount} have updates available):\n\n${pluginList}`,
},
],
};
}
);

工具7:获取所有站点的主题信息

主题与插件存在类似的更新和漏洞问题,该工具工作方式与插件工具一致,专注于WordPress主题的状态查询,定义接口结构如下(无需重复注册逻辑,参考插件工具即可):

interface ThemeEnvironment {
id: string;
site_display_name: string;
display_name: string;
theme_status: string;
theme_update: string | null;
theme_version: string;
is_theme_version_vulnerable: boolean;
theme_update_version: string | null;
}

interface Theme {
name: string;
title: string;
latest_version: string | null;
is_latest_version_vulnerable: boolean;
environment_count: number;
update_count: number;
environments: ThemeEnvironment[];
}

interface GetThemesResponse {
company: {
themes: {
total: number;
items: Theme[];
};
};
}

工具8:更新特定环境的插件

该工具可在指定环境中,将特定插件更新到目标版本,使用之前的异步操作响应结构,注册如下:

server.registerTool(
“update_plugin”,
{
description:
“Update a specific plugin to a new version on a site environment.”,
inputSchema: {
environment_id: z
.string()
.describe(“The environment ID where the plugin is installed”),
plugin_name: z
.string()
.describe(“The plugin name/slug (e.g., ‘akismet’, ‘elementor’)”),
update_version: z
.string()
.describe(“The version to update to (e.g., ‘5.3’)”),
},
},
async ({ environment_id, plugin_name, update_version }) => {
const data = await kinstaRequest(
`/sites/environments/${environment_id}/plugins`,
{
method: “PUT”,
body: JSON.stringify({
name: plugin_name,
update_version,
}),
}
);

return {
content: [
{
type: “text”,
text: `Plugin update initiated!

Plugin: ${plugin_name}
Target version: ${update_version}
Operation ID: ${data.operation_id}
Message: ${data.message}

Use get_operation_status to check progress.`,
},
],
};
}
);

插件更新为异步操作,返回操作ID可让AI助手跟踪进度,避免误判更新状态。

四、运行MCP服务器

所有工具注册完成后,最后一步是启动MCP服务器,使其可被AI客户端访问。在src/index.ts文件末尾添加主函数,使用STDIO传输连接服务器:

async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(“Kinsta MCP Server running on stdio”);
}

main().catch((error) => {
console.error(“Fatal error:”, error);
process.exit(1);
});

重要提示:由于服务器通过STDIO通信,所有日志必须输出到stderr(使用console.error),若写入stdout会干扰MCP消息,导致连接中断。

接下来构建项目,将TypeScript文件编译为可执行代码:

npm run build

构建完成后,编译后的文件会生成在build目录中,服务器即可被MCP客户端启动(完整代码可在GitHub上获取)。

五、使用Claude for Desktop测试服务器

提示:Claude for Desktop目前支持macOS和Windows系统;若使用Linux系统,需将服务器连接到其他AI助手或构建自定义MCP客户端。

要让Claude for Desktop识别并启动MCP服务器,需配置其配置文件,步骤如下:

步骤1:打开Claude配置文件

找到Claude Desktop的配置文件路径:

~/Library/Application Support/Claude/claude_desktop_config.json

若文件不存在,直接创建;使用VS Code可通过以下命令快速打开:

code ~/Library/Application\ Support/Claude/claude_desktop_config.json

步骤2:配置MCP服务器

在配置文件中,将MCP服务器添加到mcpServers项下,示例如下(替换路径和凭据):

{
“mcpServers”: {
“kinsta”: {
“command”: “node”,
“args”: [“/ABSOLUTE/PATH/TO/mcp-server-demo-kinsta-api/build/index.js”],
“env”: {
“KINSTA_API_KEY”: “your-api-key-here”,
“KINSTA_COMPANY_ID”: “your-company-id-here”
}
}
}
}

注意:args中的路径需指向build目录下编译后的index.js文件(而非TypeScript源代码),配置完成后重启Claude for Desktop。

步骤3:验证连接并使用

Claude重启后,打开新聊天窗口,点击输入框旁边的“+”图标,将鼠标悬停在“连接器”上,即可看到注册的MCP服务器(kinsta)。

MCP服务器

点击服务器完成注册后,即可开始使用:Claude会自动判断需调用的工具、传递所需输入,将结果以纯文本形式返回,无需手动操作API或服务器。

使用MCP服务器

示例:在Claude中发送“更新所有站点的Akismet插件”,AI会自动调用get_plugins工具查找插件状态,再调用update_plugin工具执行更新,最后通过get_operation_status工具反馈进度。

相关推荐:

如何构建Hostinger API MCP服务器

如何在Hostinger VPS上使用MCP创建自托管的n8n个人助理

DigitalOcean接入MCP 国外云主机可轻松连接AI助手

(本文由美国主机侦探原创,转载请注明出处“美国主机侦探”和原文地址!)

主机侦探企业微信

微信扫码加好友进群

主机优惠码及时掌握

主机侦探QQ群

QQ群号:938255063

主机优惠发布与交流

温馨提示:

1、本站部分图片来源于互联网,如有侵权请联系删除。邮箱:2942802716#qq.com(#改为@)

2、本文评论没有专人回复,如果您有问题请到美国主机侦探论坛提问!

3、美国主机侦探免费为您提供美国主机购买咨询。

RAKsmart美国服务器
下一篇
调用MCP工具检索外部数据
已经没有了
返回顶部