Apito MCP服务器
一种模型上下文协议(MCP)服务器 阿皮托 -API构建器和无头CMS。该服务器使Claude等LLM能够与Apito的系统GraphQL API交互,以创建模型、管理字段和构建模式。
特性
- 模型管理:在Apito项目中创建、列出、查询和删除模型
- 现场管理:添加、更新、重命名和删除具有显式类型规范的字段
- 关系管理:在模型之间创建关系(has_one,has_many)
- 全字段类型支持:所有Apito字段类型,包括文本、多行、数字、日期、布尔值、媒体、对象、重复、列表(含子类型)和地理
- 资源:将模型模式作为MCP资源公开,以便于访问
- 错误处理:全面的错误处理和详细的消息
- Cloudflare Workers:部署为远程MCP服务器,以便与任何MCP客户端一起使用
- 项目相关API密钥:API密钥按请求传递,允许不同的项目使用同一个工作者
MCP客户端配置(光标/MCP远程)
将apito-mcp服务器添加到mcp客户端配置中(例如Cursor ~/.cursor/mcp.json 或项目 .cursor/mcp.json):
{
"mcpServers": {
"apito-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://apito-mcp.apito.workers.dev/sse",
"--header",
"X-Apito-Key:${APITO_API_KEY}"
],
"env": {
"APITO_API_KEY": "ak_your-api-key-here"
}
}
}
}替换 ak_your-api-key-here 使用Apito API密钥。这 X-Apito-Key 每个请求都会向远程工作器发送标头。
MCP工具
create_model
在Apito中创建新模型。
论据:
model_name(必填):型号名称single_record(可选):这是否是单记录模型
add_field
向现有模型添加字段。您必须指定 field_type 和 input_type 明确地。
论据:
model_name(必填):型号名称field_label(必填):字段的标签/名称field_type(必填):字段类型(请参阅下面的有效组合)input_type(必填):输入类型(请参阅下面的有效组合)field_sub_type(可选):必填list领域。有效值:dynamicList,dropdown,multiSelectparent_field(可选):嵌套字段的父字段名称is_object_field(可选):此字段是否可以包含嵌套字段(自动设置object和repeated类型)field_description(可选):字段描述validation(可选):验证规则(要求见下文)serial(可选):用于字段排序的序列号
有效的字段类型组合:
- 文本字段:
field_type="text",input_type="string"-单行文本输入 - 富文本字段:
field_type="multiline",input_type="string"-带格式的多行编辑器 - 日期时间字段:
field_type="date",input_type="string"-日期和时间输入 - 动态数组:
field_type="list",field_sub_type="dynamicList",input_type="string"-允许多个项目的灵活列表 - 下拉菜单:
field_type="list",field_sub_type="dropdown",input_type="string"-单选预定义列表
- 需要: validation.fixed_list_elements (字符串数组)和 validation.fixed_list_element_type="string"
- 多复选框选择器:
field_type="list",field_sub_type="multiSelect",input_type="string"-允许选择多个选项
- 需要: validation.fixed_list_elements (字符串数组)和 validation.fixed_list_element_type="string"
- 布尔字段:
field_type="boolean",input_type="bool"-True或False切换 - 文件上传:
field_type="media",input_type="string"-上传图像或文件 - 整数字段:
field_type="number",input_type="int"-仅限整数 - 十进制字段:
field_type="number",input_type="double"-十进制数 - GeoPoint油田:
field_type="geo",input_type="geo"-纬度和经度 - 对象架构:
field_type="object",input_type="object",is_object_field=true-具有多个字段的单个对象 - 数组架构:
field_type="repeated",input_type="repeated",is_object_field=true-具有多个字段的对象列表
示例-简单字段:
{
"model_name": "dentalAssessment",
"field_label": "Date",
"field_type": "date",
"input_type": "string"
}示例-下拉字段:
{
"model_name": "dentalAssessment",
"field_label": "Status",
"field_type": "list",
"field_sub_type": "dropdown",
"input_type": "string",
"validation": {
"fixed_list_elements": ["active", "inactive", "pending"],
"fixed_list_element_type": "string"
}
}示例-嵌套对象字段:
{
"model_name": "dentalAssessment",
"field_label": "Chief Complaint",
"field_type": "object",
"input_type": "object",
"is_object_field": true
}然后添加嵌套字段 parent_field="chief_complaint":
{
"model_name": "dentalAssessment",
"field_label": "Complaint",
"field_type": "text",
"input_type": "string",
"parent_field": "chief_complaint"
}update_field
更新模型中的现有字段。
论据:
model_name(必填):型号名称field_name(必填):要更新的字段的标识符field_label(必填):字段的新标签field_type(可选):新字段类型input_type(可选):新输入类型field_description(可选):新描述validation(可选):更新的验证规则
rename_field
重命名模型中的字段。
论据:
model_name(必填):型号名称field_name(必填):当前字段标识符new_name(必填):新字段标识符parent_field(可选):父字段名称(如果这是嵌套字段)
delete_field
从模型中删除字段。
论据:
model_name(必填):型号名称field_name(必填):要删除的字段标识符parent_field(可选):父字段名称(如果这是嵌套字段)
delete_model
从项目中删除模型。这也将删除模型中的所有数据。
论据:
model_name(必填):要删除的模型名称
list_models
列出当前项目中的所有模型。
论据: 无
get_model_schema
获取模型的完整模式,包括所有字段及其类型。
论据:
model_name(必需):要获取架构的模型的名称
get_project_query_structure
获取Apito项目GraphQL查询结构:每个模型存在哪些操作。Apito使用一致的命名约定:用于模型 Task 有 task(_id), taskList, taskListCount, createTask, updateTask, deleteTask, upsertTaskList. CamelCase很重要 --模型名称转换为camelCase作为操作名称。
当您需要知道查询或修改项目数据时需要调用哪些GraphQL操作时,请使用此工具。每个项目的模式都是动态的,因此请尽早调用此模式以发现可用的操作。
论据: 无
退货: 每个模型与其操作的映射:
- 查询:
{singular}(_id)(单个ID),{singular}List(分页列表),{singular}ListCount(计数) - 突变:
create{Model},update{Model},delete{Model},upsert{Model}List
add_relation
在两个模型之间创建关系。关系定义了模型之间的连接方式(例如,一个患者有多个牙科评估,或者一个牙科评估属于一个患者)。
论据:
from_model(必填):源模型名称(将具有关系字段的模型)to_model(必填):目标型号名称(与之相关的型号)forward_connection_type(必填):从源到目标的转发关系类型。有效值:"has_many"(一对多)或"has_one"(一对一)reverse_connection_type(必填):将关系类型从目标反向到源。有效值:"has_many"(一对多)或"has_one"(一对一)known_as(可选):此关系的可选替代标识符(关系字段的自定义名称)
例子:
{
"tool": "add_relation",
"arguments": {
"from_model": "dentalAssessment",
"to_model": "patient",
"forward_connection_type": "has_many",
"reverse_connection_type": "has_one",
"known_as": "assessments"
}
}这将创建:
- 向前地:
dentalAssessment有很多patient - 反向:
patient有一个dentalAssessment
upsert_data
在模型中创建或更新记录。地图到Apito's upsertModelData 系统突变。
论据:
model_name(必填):型号名称payload(必填):创建/更新字段值的JSON对象_id(可选):用于更新的文档ID(创建时省略)status(可选):文档状态:"draft"或"published"(默认值:"published")local(可选):本地化内容的区域设置(默认值:"en")connect(可选):JSON用于连接关系--{"author_id": "uuid"}对于has_one,{"tag_ids": ["uuid1","uuid2"]}对于has_manydisconnect(可选):JSON用于断开关系
关系连接模式: 钥匙使用 {modelName}_id 对于has_one和 {modelName}_ids 对于has_many(其中 modelName 相关型号名称或 known_as).
get_data
使用可选的过滤器、分页和搜索从模型中查询或列出记录。地图到Apito's getModelData 系统查询。
论据:
model_name(必填):型号名称page(可选):页码(默认:1)limit(可选):每页记录数(默认值:10)where(可选):JSON过滤对象status(可选):按状态筛选:"all","draft",或"published"search(可选):文本搜索查询
delete_data
按ID删除记录。映射到Apito的 deleteModelData 系统突变。
论据:
model_name(必填):型号名称_id(必填):要删除的文档ID
duplicate_data
按ID复制记录。返回新记录ID。映射到Apito的ID duplicateModelData 系统突变。
论据:
model_name(必填):型号名称_id(必填):要复制的文档ID
示例:创建一个类别并将一篇文章连接到该类别
{
"tool": "upsert_data",
"arguments": {
"model_name": "Category",
"payload": {
"name": "Technology",
"slug": "technology"
}
}
}返回新类别 id。然后创建一篇与该类别相关的文章:
{
"tool": "upsert_data",
"arguments": {
"model_name": "Article",
"payload": {
"title": "My First Post",
"slug": "my-first-post"
},
"connect": {
"category_id": ""
}
}
}MCP资源
模型模式和查询结构指南作为具有URI的资源公开:
apito://project-query-guide-Apito查询结构: 响应形状 (id、数据、元数据), 多行/地理/媒体子选择 (内容{html}、位置{lat-lon}、缩略图{url})、命名、,where过滤器、连接、分页、突变apito://model/{modelName}-以JSON格式访问模型模式
字段类型参考
可用字段类型
text-单行文本输入multiline-带格式的多行编辑器number-数字字段(使用int或double输入类型)date-日期和时间输入boolean-True或False切换media-文件上传object-具有多个字段的单个对象repeated-具有多个字段的对象数组list-列表字段(必填field_sub_type)geo-GeoPoint(纬度和经度)
可用输入类型
string-字符串值int-整数double-十进制数bool-布尔值geo-地理坐标object-对象结构repeated-数组结构
查询子选择(对于多行、地理、媒体、对象、重复至关重要)
查询这些字段时,您 必须 使用子选项。裸露的选择会导致GraphQL错误“必须有一个子选择”:
- 多行 →
content { html }或bio { text }(选择html,text,或markdown) - 地理 →
location { lat lon } - 媒体 →
thumbnail { url }或image { url }(或其他子字段) - 对象 / 重复的 → 选择嵌套字段
列出字段子类型
使用时 field_type="list",您必须指定 field_sub_type:
dynamicList-动态数组(允许多个项目的灵活列表)dropdown-下拉菜单(预定义的单选列表)
- 要求: validation.fixed_list_elements 和 validation.fixed_list_element_type="string"
multiSelect-多复选框选择器(允许选择多个选项)
- 要求: validation.fixed_list_elements 和 validation.fixed_list_element_type="string"
示例:创建牙科评估模型
MCP服务器提供基本的CRUD操作。LLM应该解析模式定义并调用适当的工具。以下是LLM如何创建牙科评估模型:
- 创建模型:
{
"tool": "create_model",
"arguments": {
"model_name": "dentalAssessment"
}
}- 逐一添加字段:
{
"tool": "add_field",
"arguments": {
"model_name": "dentalAssessment",
"field_label": "Date",
"field_type": "date",
"input_type": "string"
}
}- 添加对象字段:
{
"tool": "add_field",
"arguments": {
"model_name": "dentalAssessment",
"field_label": "Chief Complaint",
"field_type": "object",
"input_type": "object",
"is_object_field": true
}
}- 添加嵌套字段:
{
"tool": "add_field",
"arguments": {
"model_name": "dentalAssessment",
"field_label": "Complaint",
"field_type": "text",
"input_type": "string",
"parent_field": "chief_complaint"
}
}发展
# Type check
npm run typecheck
# Build
npm run build
# Development mode (Cloudflare)
npm run dev错误处理
服务器提供详细的错误消息,包括:
- GraphQL错误代码和路径
- 验证错误
- 网络错误
- 字段类型模糊警告
所有错误都会记录到stderr(对STDIO服务器很重要)。
最佳实践
- 型号名称:避免保留名称(
list,user,system,function) - 显式类型:始终指定
field_type和input_type明确-不要依赖自动检测 - 列表字段:对于下拉菜单和多选,请始终提供
validation.fixed_list_elements和validation.fixed_list_element_type - 嵌套字段:设置
is_object_field=true为了object和repeated字段类型 - 父字段:使用
parent_field向对象或重复字段添加嵌套字段时的参数 - API密钥:对于远程部署,API密钥依赖于项目,必须根据请求提供,而不是存储为Cloudflare机密
- 关系:使用
add_relation在模型之间创建双向关系
与MCP客户端一起使用
Cursor IDE
添加 ~/.cursor/mcp.json:
本地(STDIO):
{
"mcpServers": {
"apito": {
"command": "npx",
"args": [
"tsx",
"/Users/your-username/Projects/apito/apito-mcp/src/index.ts"
],
"env": {
"APITO_API_KEY": "your-api-key-here",
"APITO_GRAPHQL_ENDPOINT": "https://api.apito.io/system/graphql"
}
}
}
}远程(Cloudflare Workers):
{
"mcpServers": {
"apito-production": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://apito-mcp.apito.workers.dev/sse",
"--header",
"X-Apito-Key:${APITO_API_KEY}"
],
"env": {
"APITO_API_KEY": "your-api-key-here"
}
}
}
}备注:API密钥通过 X-Apito-Key 标题使用 --header 旗帜。这 env.APITO_API_KEY 环境变量将自动替换为 mcp-remote.
配置后重新启动Cursor。
VS Code
安装 MCP扩展 并在设置中配置:
{
"mcp.servers": {
"apito": {
"command": "npx",
"args": ["tsx", "/path/to/apito-mcp/src/index.ts"],
"env": {
"APITO_API_KEY": "your-api-key-here"
}
}
}
}克劳德桌面版
添加 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%/Claude/claude_desktop_config.json (Windows):
{
"mcpServers": {
"apito": {
"command": "npx",
"args": ["tsx", "/path/to/apito-mcp/src/index.ts"],
"env": {
"APITO_API_KEY": "your-api-key-here",
"APITO_GRAPHQL_ENDPOINT": "https://api.apito.io/system/graphql"
}
}
}
}ChatGPT/OpenAI
ChatGPT不直接支持MCP,但您可以通过HTTP/SSE使用远程Cloudflare Workers端点。您需要使用MCP代理或客户端库。
其他MCP客户端
任何兼容MCP的客户端都可以连接到:
- 本地:通过STDIO传输
npx tsx src/index.ts - 远程:通过SSE运输
https://apito-mcp.apito.workers.dev/sse(要求mcp-remote代理)
环境变量
对于远程部署(Cloudflare Workers):
API密钥是 不 存储为Cloudflare Worker机密。它必须由MCP客户端在每个请求中提供。这允许同一个工人为多个项目服务。
可选:如果需要覆盖默认值,请设置GraphQL端点机密:
# Set GraphQL endpoint (optional, defaults to https://api.apito.io/system/graphql)
npx wrangler secret put APITO_GRAPHQL_ENDPOINT --env production对于本地部署(STDIO):
在MCP客户端配置中设置环境变量(见上面的示例)。
测试连接
您可以使用MCP检查器或检查客户端中是否有可用的工具来测试MCP服务器连接。服务器应公开:
create_modeladd_fieldupdate_fieldrename_fielddelete_fielddelete_modellist_modelsget_model_schemaget_project_query_structureadd_relationupsert_dataget_datadelete_dataduplicate_data
许可证
麻省理工学院
