Skip to content
Star -

Endpoints

Related Topics: Type System (parameter/return types) | YAML Schemas (complete field reference) | SQL Endpoints (SQL tutorial) | Python Endpoints (Python tutorial)

MXCP supports three types of MCP endpoints, each serving different purposes. Understanding when to use each type helps you design better AI integrations.

TypePurposeIdentified ByImplementation
ToolActions and queriesnameSQL or Python
ResourceData accessuri templateSQL or Python
PromptMessage templatesnameJinja2 messages

Tools are functions that AI can call to perform actions or retrieve data. They’re the most common endpoint type.

  • Data queries - Fetch information from databases
  • Calculations - Perform computations
  • Actions - Create, update, or delete data
  • Integrations - Call external APIs
mxcp: 1
tool:
name: get_sales_report
description: Get sales report for a date range
enabled: true
tags: ["sales", "reporting"]
annotations:
title: "Sales Report"
readOnlyHint: true
destructiveHint: false
idempotentHint: true
openWorldHint: false
parameters:
- name: start_date
type: string
format: date
description: Start date (YYYY-MM-DD)
examples: ["2024-01-01"]
- name: end_date
type: string
format: date
description: End date (YYYY-MM-DD)
examples: ["2024-12-31"]
- name: region
type: string
description: Region to filter by
enum: ["North", "South", "East", "West"]
default: "North"
return:
type: object
description: Sales report summary
properties:
total_sales:
type: number
description: Total sales amount
transaction_count:
type: integer
description: Number of transactions
average_sale:
type: number
description: Average sale amount
language: sql
source:
file: ../sql/sales_report.sql
tests:
- name: basic_report
description: Test basic report generation
arguments:
- key: start_date
value: "2024-01-01"
- key: end_date
value: "2024-01-31"
- key: region
value: "North"
result_contains:
total_sales: 15420.50
transaction_count: 42

Annotations help LLMs understand tool behavior:

AnnotationDescription
titleHuman-readable title
readOnlyHintTool doesn’t modify data
destructiveHintTool may delete/modify data permanently
idempotentHintMultiple calls produce same result
openWorldHintTool interacts with external systems

The tests block defines test cases that run with mxcp test. See Testing for details.

SQL Tools - Best for:

  • Database queries
  • Data aggregations
  • Simple transformations

Python Tools - Best for:

  • Complex business logic
  • External API calls
  • ML model inference
  • File processing
  • Database queries with complex logic (via db.execute())

Resources are data sources that can be read by AI. They use URI templates to identify specific data.

  • Static data - Configuration, reference data
  • Document access - Read files or documents
  • Hierarchical data - Data organized by path/ID
mxcp: 1
resource:
uri: "employee://{employee_id}/profile"
description: Employee profile information
mime_type: application/json
tags: ["hr", "employee"]
parameters:
- name: employee_id
type: string
description: Employee ID
examples: ["EMP001"]
return:
type: object
properties:
id:
type: string
name:
type: string
department:
type: string
hire_date:
type: string
format: date
language: sql
source:
file: ../sql/employee_profile.sql

Resource URIs support parameter substitution:

users://{user_id} # Single parameter
orders://{customer_id}/{order_id} # Multiple parameters
reports://sales/{year}/{month} # Hierarchical

Parameters are extracted from the URI and available in your SQL or Python code.

Prompts are reusable message templates for AI conversations. They support Jinja2 templating.

  • Consistent instructions - Standard analysis prompts
  • Complex workflows - Multi-step conversations
  • Parameterized templates - Dynamic prompt generation
mxcp: 1
prompt:
name: data_analysis
description: Prompt for structured data analysis
tags: ["analysis", "reporting"]
parameters:
- name: data_type
type: string
description: Type of data to analyze
enum: ["sales", "inventory", "customers"]
- name: time_period
type: string
description: Time period for analysis
examples: ["Q1 2024", "Last 30 days"]
messages:
- role: system
prompt: |
You are a data analyst specializing in {{ data_type }} data.
Provide clear, actionable insights.
- role: user
prompt: |
Analyze the {{ data_type }} data for {{ time_period }}.
Focus on:
1. Key trends
2. Anomalies
3. Recommendations

Prompts support full Jinja2 syntax:

prompt: |
{% if role == "admin" %}
You have full access to all data.
{% else %}
You have limited access.
{% endif %}
Available metrics:
{% for metric in metrics %}
- {{ metric }}
{% endfor %}
RoleDescription
systemSystem-level instructions
userUser message
assistantAssistant response

Tools and resources support source options for defining implementation code. Prompts use messages instead of source.

SQL endpoints support both inline code and external files:

Inline Code - Good for simple queries:

language: sql
source:
code: |
SELECT id, name, email
FROM users
WHERE id = $user_id

External File - Recommended for complex queries:

language: sql
source:
file: ../sql/get_user.sql

Python endpoints require external files - inline Python code is not supported:

language: python
source:
file: ../python/handler.py

The Python file must contain a function matching the endpoint name. Access runtime services via imports from mxcp.runtime:

python/handler.py
from mxcp.runtime import db, config
def get_user(user_id: int) -> dict:
"""Function parameters are the endpoint's defined parameters."""
result = db.execute(
"SELECT * FROM users WHERE id = $id",
{"id": user_id}
)
return result[0] if result else None

Available runtime imports:

  • db - Database access (db.execute())
  • config - Configuration and secrets (config.get_secret())
  • plugins - Access registered plugins
  • on_init, on_shutdown - Lifecycle hooks

External files are recommended for:

  • Complex logic - Better syntax highlighting and editor support
  • Reusable code - Share SQL/Python across multiple endpoints
  • Version control - Cleaner diffs when queries change
  • Testing - Easier to test Python modules independently

File paths are relative to the endpoint YAML file:

my-project/
├── tools/
│ └── get_user.yml # source.file: ../sql/get_user.sql
├── sql/
│ └── get_user.sql
└── python/
└── handlers.py

Use enabled to control whether an endpoint is loaded:

tool:
name: experimental_tool
enabled: false # Won't be loaded

This is useful for:

  • Work-in-progress endpoints
  • Feature flags
  • Environment-specific endpoints

Tags are string labels that help organize and categorize endpoints. All endpoint types (tools, resources, prompts) support tags.

tool:
name: sales_report
tags: ["sales", "reporting", "finance"]

LLM Context - Tags are included when endpoints are presented to AI models during evaluations (mxcp evals), helping LLMs understand endpoint categories and relationships.

Linting - mxcp lint warns if endpoints are missing tags, as they improve discoverability and organization.

Documentation - Tags provide metadata for organizing large projects and generating documentation.

  • Use single lowercase words: sales, admin, read
  • Combine multiple tags instead of compound words: ["users", "management"] not ["user-management"]
  • Keep tags short and descriptive
  • Use consistent categories across your project
  • Common patterns:
    • Domain: sales, inventory, customers, hr
    • Operation type: read, write, delete, search, create, list
    • Access level: admin, public, internal
# Consistent tagging across related endpoints
tools/get_user.yml: tags: ["users", "read"]
tools/create_user.yml: tags: ["users", "write"]
tools/delete_user.yml: tags: ["users", "delete", "admin"]
tools/list_users.yml: tags: ["users", "read", "search"]

Endpoints can define access control policies. See Policies for details.

tool:
name: get_employee
# ... parameters and return type ...
policies:
input:
- condition: "user.role != 'hr'"
action: deny
reason: "HR access required"
output:
- condition: "user.role != 'admin'"
action: filter_sensitive_fields
  • Use snake_case for names
  • Be descriptive but concise
  • Use consistent prefixes (e.g., get_, create_, update_)
  • Write clear, actionable descriptions
  • Include what the tool does, not how
  • Mention any side effects
  • Provide examples for all parameters
  • Use appropriate types and formats
  • Set sensible defaults for optional parameters
  • Define complete return schemas
  • Mark sensitive fields appropriately
  • Include descriptions for complex objects
  • Write tests for all endpoints
  • Test edge cases
  • Test with realistic data