对于大部分站群用户来说,网站管理的便捷性变成了首要考虑因素。本文将通过实际示例,一步步教大家构建自己的MCP服务器,可将Claude等AI助手与Kinsta API连接,轻松处理机构日常的WordPress主机管理任务。
MCP服务器可以让AI助手执行以下操作:
- 列出账户下的所有WordPress站点
- 显示特定站点的环境信息
- 清除指定环境中的缓存
- 克隆现有站点,快速启动新站点
- 查看哪些插件和主题已过时或存在安全漏洞
- 在特定环境中触发插件更新
服务器设置完成后,将连接到MCP主机/客户端(本文以Claude for Desktop为例),具体交互流程如下:
1、Claude在接收提示时,会调用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主机综合评测(定价/功能/特点/性能/速度)》
4、获取Kinsta API密钥和公司ID:
- 前往您的MyKinsta仪表板;
- 导航至API密钥页面(您的姓名 > 公司设置 > API密钥);
- 单击创建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请求,为避免重复编写代码,创建一个通用辅助函数,添加在服务器实例下方:
步骤3:实现工具执行(核心环节)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;
}
工具是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可通过以下命令快速打开:
步骤2:配置MCP服务器code ~/Library/Application\ Support/Claude/claude_desktop_config.json
在配置文件中,将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)。

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

示例:在Claude中发送“更新所有站点的Akismet插件”,AI会自动调用get_plugins工具查找插件状态,再调用update_plugin工具执行更新,最后通过get_operation_status工具反馈进度。
相关推荐:
《如何在Hostinger VPS上使用MCP创建自托管的n8n个人助理》
《DigitalOcean接入MCP 国外云主机可轻松连接AI助手》
(本文由美国主机侦探原创,转载请注明出处“美国主机侦探”和原文地址!)
微信扫码加好友进群
主机优惠码及时掌握
QQ群号:938255063
主机优惠发布与交流




