Enables LLMs to interact with Apito's system GraphQL API to create models, manage fields, and build schemas programmatically.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Apito MCP Servercreate a Blog model and add a rich text field for content"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Apito MCP Server
A Model Context Protocol (MCP) server for Apito - an API builder and headless CMS. This server enables LLMs like Claude to interact with Apito's system GraphQL API to create models, manage fields, and build schemas.
Features
Model Management: Create, list, query, and delete models in your Apito project
Field Management: Add, update, rename, and delete fields with explicit type specification
Relation Management: Create relations between models (has_one, has_many)
Full Field Type Support: All Apito field types including text, multiline, number, date, boolean, media, object, repeated, list (with sub-types), and geo
Resources: Expose model schemas as MCP resources for easy access
Error Handling: Comprehensive error handling with detailed messages
Cloudflare Workers: Deploy as a remote MCP server for use with any MCP client
Project-Dependent API Keys: API keys are passed per-request, allowing different projects to use the same worker
Installation
Configuration
Local (STDIO) Mode
Set the following environment variables:
APITO_API_KEYorAPITO_AUTH_TOKEN(required): Your Apito API key (starts withak_)APITO_GRAPHQL_ENDPOINT(optional): GraphQL endpoint (defaults tohttps://api.apito.io/system/graphqlfor system queries)
Remote (Cloudflare Workers) Mode
The API key is not stored as a Cloudflare Worker secret. Instead, it must be passed per-request via:
Authorization: Bearer <key>headerX-Apito-Key: <key>header?api_key=<key>query parameter
The APITO_GRAPHQL_ENDPOINT is optional and defaults to https://api.apito.io/system/graphql. It can be set as a Cloudflare Worker secret if you need to override the default.
Usage
STDIO Mode (Local)
Run the server locally using stdio transport:
Or with environment file:
Cloudflare Workers (Remote)
Deploy to Cloudflare Workers for remote access:
Important: The APITO_API_KEY is not stored as a Cloudflare Worker secret. It must be provided by the MCP client in each request via headers or query parameters. This allows the same worker to serve multiple projects with different API keys.
MCP Tools
create_model
Create a new model in Apito.
Arguments:
model_name(required): Name of the modelsingle_record(optional): Whether this is a single-record model
add_field
Add a field to an existing model. You must specify field_type and input_type explicitly.
Arguments:
model_name(required): Name of the modelfield_label(required): Label/name of the fieldfield_type(required): Field type (see valid combinations below)input_type(required): Input type (see valid combinations below)field_sub_type(optional): Required forlistfields. Valid values:dynamicList,dropdown,multiSelectparent_field(optional): Parent field name for nested fieldsis_object_field(optional): Whether this field can contain nested fields (auto-set forobjectandrepeatedtypes)field_description(optional): Field descriptionvalidation(optional): Validation rules (see below for requirements)serial(optional): Serial number for field ordering
Valid Field Type Combinations:
Text Field:
field_type="text",input_type="string"- Single line text inputRich Text Field:
field_type="multiline",input_type="string"- Multiline editor with formattingDateTime Field:
field_type="date",input_type="string"- Date & Time inputDynamic Array:
field_type="list",field_sub_type="dynamicList",input_type="string"- Flexible list allowing multiple itemsDropdown Menu:
field_type="list",field_sub_type="dropdown",input_type="string"- Predefined list for single selectionREQUIRES:
validation.fixed_list_elements(array of strings) andvalidation.fixed_list_element_type="string"
Multi-Checkbox Selector:
field_type="list",field_sub_type="multiSelect",input_type="string"- Allows selecting multiple optionsREQUIRES:
validation.fixed_list_elements(array of strings) andvalidation.fixed_list_element_type="string"
Boolean Field:
field_type="boolean",input_type="bool"- True or False toggleFile Upload:
field_type="media",input_type="string"- Upload images or filesInteger Field:
field_type="number",input_type="int"- Whole numbers onlyDecimal Field:
field_type="number",input_type="double"- Decimal numbersGeoPoint Field:
field_type="geo",input_type="geo"- Latitude & LongitudeObject Schema:
field_type="object",input_type="object",is_object_field=true- Single object with multiple fieldsArray Schema:
field_type="repeated",input_type="repeated",is_object_field=true- List of objects with multiple fields
Example - Simple Field:
Example - Dropdown Field:
Example - Nested Object Field:
Then add nested fields with parent_field="chief_complaint":
update_field
Update an existing field in a model.
Arguments:
model_name(required): Name of the modelfield_name(required): Identifier of the field to updatefield_label(required): New label for the fieldfield_type(optional): New field typeinput_type(optional): New input typefield_description(optional): New descriptionvalidation(optional): Updated validation rules
rename_field
Rename a field in a model.
Arguments:
model_name(required): Name of the modelfield_name(required): Current field identifiernew_name(required): New field identifierparent_field(optional): Parent field name if this is a nested field
delete_field
Delete a field from a model.
Arguments:
model_name(required): Name of the modelfield_name(required): Field identifier to deleteparent_field(optional): Parent field name if this is a nested field
delete_model
Delete a model from the project. This will also delete all data in the model.
Arguments:
model_name(required): Name of the model to delete
list_models
List all models in the current project.
Arguments: None
get_model_schema
Get the complete schema for a model including all fields and their types.
Arguments:
model_name(required): Name of the model to get schema for
add_relation
Create a relation between two models. Relations define how models are connected (e.g., a Patient has many DentalAssessments, or a DentalAssessment belongs to one Patient).
Arguments:
from_model(required): Source model name (the model that will have the relation field)to_model(required): Target model name (the model being related to)forward_connection_type(required): Forward relation type from source to target. Valid values:"has_many"(one-to-many) or"has_one"(one-to-one)reverse_connection_type(required): Reverse relation type from target back to source. Valid values:"has_many"(one-to-many) or"has_one"(one-to-one)known_as(optional): Optional alternate identifier for this relation (custom name for the relation field)
Example:
This creates:
Forward:
dentalAssessmenthas manypatientReverse:
patienthas onedentalAssessment
MCP Resources
Model schemas are exposed as resources with URIs:
apito://model/{modelName}- Access model schema as JSON
Field Type Reference
Available Field Types
text- Single line text inputmultiline- Multiline editor with formattingnumber- Number field (useintordoubleinput_type)date- Date & Time inputboolean- True or False togglemedia- File uploadobject- Single object with multiple fieldsrepeated- Array of objects with multiple fieldslist- List field (requiresfield_sub_type)geo- GeoPoint (latitude & longitude)
Available Input Types
string- String valueint- Integer numberdouble- Decimal numberbool- Boolean valuegeo- Geographic coordinatesobject- Object structurerepeated- Array structure
List Field Sub Types
When using field_type="list", you must specify field_sub_type:
dynamicList- Dynamic Array (flexible list allowing multiple items)dropdown- Dropdown Menu (predefined list for single selection)Requires:
validation.fixed_list_elementsandvalidation.fixed_list_element_type="string"
multiSelect- Multi-Checkbox Selector (allows selecting multiple options)Requires:
validation.fixed_list_elementsandvalidation.fixed_list_element_type="string"
Example: Creating a Dental Assessment Model
The MCP server provides basic CRUD operations. The LLM should parse schema definitions and call the appropriate tools. Here's how an LLM would create a dental assessment model:
Create the model:
Add fields one by one:
Add object field:
Add nested fields:
Development
Error Handling
The server provides detailed error messages including:
GraphQL error codes and paths
Validation errors
Network errors
Field type ambiguity warnings
All errors are logged to stderr (important for STDIO servers).
Best Practices
Model Names: Avoid reserved names (
list,user,system,function)Explicit Types: Always specify
field_typeandinput_typeexplicitly - don't rely on automatic detectionList Fields: For dropdown and multiSelect, always provide
validation.fixed_list_elementsandvalidation.fixed_list_element_typeNested Fields: Set
is_object_field=trueforobjectandrepeatedfield typesParent Fields: Use
parent_fieldparameter when adding nested fields to object or repeated fieldsAPI Keys: For remote deployments, API keys are project-dependent and must be provided per-request, not stored as Cloudflare secrets
Relations: Use
add_relationto create bidirectional relationships between models
Using with MCP Clients
Cursor IDE
Add to ~/.cursor/mcp.json:
Local (STDIO):
Remote (Cloudflare Workers):
Option 1: Using Header (Recommended if mcp-remote supports env var substitution):
Option 2: Using Query Parameter (More reliable):
Option 3: Hardcode in Header (If env var substitution doesn't work):
Note: If mcp-remote doesn't support environment variable substitution in the --header flag, use Option 2 (query parameter) or Option 3 (hardcoded header). The env section in Option 1 may not be used if substitution isn't supported.
Restart Cursor after configuration.
VS Code
Install the MCP extension and configure in settings:
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%/Claude/claude_desktop_config.json (Windows):
ChatGPT / OpenAI
ChatGPT doesn't directly support MCP, but you can use the remote Cloudflare Workers endpoint via HTTP/SSE. You'll need to use an MCP proxy or client library.
Other MCP Clients
Any MCP-compatible client can connect to:
Local: STDIO transport via
npx tsx src/index.tsRemote: SSE transport via
https://apito-mcp.apito.workers.dev/sse(requiresmcp-remoteproxy)
Environment Variables
For Remote Deployments (Cloudflare Workers):
The API key is not stored as a Cloudflare Worker secret. It must be provided by the MCP client in each request. This allows the same worker to serve multiple projects.
Optional: Set GraphQL endpoint secret if you need to override the default:
For Local Deployments (STDIO):
Set environment variables in your MCP client configuration (see examples above).
Testing the Connection
You can test the MCP server connection using the MCP Inspector or by checking if tools are available in your client. The server should expose:
create_modeladd_fieldupdate_fieldrename_fielddelete_fielddelete_modellist_modelsget_model_schemaadd_relation
License
MIT