Skip to content
Star -

Linting

Related Topics: Validation (structural checks) | Testing (functional tests) | Endpoints (definition best practices) | Common Tasks (quick how-to)

The MXCP linter checks your endpoint metadata quality, ensuring AI tools can understand and use your endpoints effectively.

Terminal window
# Lint all endpoints
mxcp lint
# Show only warnings (skip suggestions)
mxcp lint --severity warning
# JSON output for automation
mxcp lint --json-output
# Debug mode
mxcp lint --debug

Note: The linter checks all endpoints at once. It does not support filtering by specific endpoint.

  • Tool/resource description present and meaningful
  • Parameter descriptions present
  • Return type descriptions present
  • Minimum description length
  • Parameters have examples
  • Examples are realistic
  • Multiple examples for clarity
  • Endpoints have tags
  • Tags are categorized
  • Consistent tag naming
  • Behavioral hints set (readOnlyHint, destructiveHint)
  • Title provided
  • Appropriate hints for operation type
  • Parameter naming conventions
  • Return type completeness
  • Sensitive field marking
Terminal window
mxcp lint
🔍 Lint Results
Checked 2 endpoint files
🎉 All endpoints have excellent metadata!
Terminal window
mxcp lint
🔍 Lint Results
Checked 3 endpoint files
2 files with suggestions
5 warnings
📄 tools/get_user.yml
⚠️ tool.description
Tool is missing a description
💡 Add a 'description' field to help LLMs understand what this endpoint does
⚠️ tool.tests
Tool has no tests defined
💡 Add at least one test case to ensure the endpoint works correctly
ℹ️ tool.parameters[0].examples
Parameter 'user_id' has no examples
💡 Consider adding an 'examples' array to help LLMs understand valid inputs
📄 tools/delete_user.yml
ℹ️ tool.tags
Tool has no tags
💡 Consider adding tags to help categorize and discover this endpoint
ℹ️ tool.annotations
Tool has no behavioral annotations
💡 Consider adding annotations like readOnlyHint, idempotentHint to help LLMs use the tool safely
📚 Why this matters:
Descriptions help LLMs understand your endpoints better
Examples show LLMs how to use parameters correctly
Tests ensure your endpoints work as expected
Good metadata = better LLM performance!

Severity levels:

  • ⚠️ Warning - Important issues (missing description, missing tests)
  • ℹ️ Info - Suggestions for improvement (missing examples, tags, annotations)
Terminal window
mxcp lint --json-output
{
"status": "ok",
"result": [
{
"severity": "warning",
"path": "tools/get_user.yml",
"location": "tool.description",
"message": "Tool is missing a description",
"suggestion": "Add a 'description' field to help LLMs understand what this endpoint does"
},
{
"severity": "info",
"path": "tools/get_user.yml",
"location": "tool.parameters[0].examples",
"message": "Parameter 'user_id' has no examples",
"suggestion": "Consider adding an 'examples' array to help LLMs understand valid inputs"
}
]
}

Fields:

  • status: Command execution status (ok or error)
  • result: Array of lint issues
    • severity: Issue severity (warning or info)
    • path: Path to endpoint file
    • location: YAML path to the problematic field
    • message: Description of the issue
    • suggestion: Recommended fix

Note: Structural errors (invalid types, missing required fields) are caught by mxcp validate, not the linter. The linter focuses on metadata quality.

LocationMessage
tool.descriptionTool is missing a description
tool.testsTool has no tests defined
resource.descriptionResource is missing a description
LocationMessage
*.parameters[n].examplesParameter has no examples
*.parameters[n].defaultParameter has no default value
*.tagsEndpoint has no tags
*.annotationsEndpoint has no behavioral annotations
# Before (warning: tool.description)
mxcp: 1
tool:
name: get_user
parameters:
- name: user_id
type: integer
description: User ID
source:
code: "SELECT * FROM users WHERE id = $user_id"
# After (fixed)
mxcp: 1
tool:
name: get_user
description: Retrieve user information by their unique identifier
parameters:
- name: user_id
type: integer
description: User ID
source:
code: "SELECT * FROM users WHERE id = $user_id"
# Before (warning: tool.tests)
mxcp: 1
tool:
name: get_user
description: Get user by ID
# ... no tests defined
# After (fixed)
mxcp: 1
tool:
name: get_user
description: Get user by ID
# ...
tests:
- name: get_existing_user
arguments:
- key: user_id
value: 1
result_contains:
id: 1
# Before (info: tool.parameters[0].examples)
parameters:
- name: status
type: string
description: User status filter
enum: ["active", "inactive", "pending"]
# After (fixed)
parameters:
- name: status
type: string
description: User status filter
enum: ["active", "inactive", "pending"]
examples: ["active", "pending"]
# Before (info: tool.tags)
tool:
name: get_user
description: Get user by ID
# After (fixed)
tool:
name: get_user
description: Get user by ID
tags: ["users", "read"]
# Before (info: tool.annotations)
tool:
name: delete_user
description: Delete a user permanently
# After (fixed)
tool:
name: delete_user
description: Delete a user permanently
annotations:
title: "Delete User"
readOnlyHint: false
destructiveHint: true
idempotentHint: false

Mark fields containing sensitive data:

return:
type: object
properties:
ssn:
type: string
sensitive: true
password_hash:
type: string
sensitive: true

Good:

tool:
name: get_customer_orders
description: |
Retrieves order history for a specific customer.
Returns orders sorted by date (newest first).
Includes order items, totals, and shipping information.

Bad:

tool:
name: get_data
description: "Gets data"

Good:

parameters:
- name: status
type: string
description: "Order status filter"
examples: ["pending", "shipped", "delivered", "cancelled"]
enum: ["pending", "shipped", "delivered", "cancelled"]
- name: date_from
type: string
format: date
description: "Start date for filtering orders (inclusive)"
examples: ["2024-01-01", "2024-06-15"]

Bad:

parameters:
- name: limit
type: integer
description: "The limit"

Describe complex return types thoroughly:

return:
type: object
description: "Customer order details"
properties:
order_id:
type: string
description: "Unique order identifier"
items:
type: array
description: "List of items in the order"
items:
type: object
description: "Individual order item"
properties:
sku:
type: string
description: "Product SKU"
quantity:
type: integer
description: "Number of units ordered"
price:
type: number
description: "Unit price at time of order"

Use annotations to help AI understand tool behavior:

annotations:
readOnlyHint: true # Tool doesn't modify data

Use for: GET operations, searches, reports

annotations:
destructiveHint: true # Tool permanently changes/deletes data

Use for: DELETE, DROP, permanent modifications

annotations:
idempotentHint: true # Multiple calls have same effect

Use for: Updates, upserts, idempotent operations

annotations:
openWorldHint: true # Tool accesses external systems

Use for: API calls, external services

GitHub Actions (Complete Quality Workflow)

Section titled “GitHub Actions (Complete Quality Workflow)”
name: MXCP Quality Checks
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install mxcp
- name: Validate Endpoints
run: mxcp validate
- name: Run Tests
run: mxcp test
- name: Lint Endpoints
run: mxcp lint --severity warning
name: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- run: pip install mxcp
- name: Run linter
run: mxcp lint --json-output > lint-results.json
- name: Check for warnings
run: |
if jq -e '.result[] | select(.severity == "warning")' lint-results.json > /dev/null; then
echo "Lint warnings found"
exit 1
fi
#!/bin/bash
# Block on too many warnings
RESULT=$(mxcp lint --json-output)
WARNINGS=$(echo "$RESULT" | jq '[.result[] | select(.severity == "warning")] | length')
INFO=$(echo "$RESULT" | jq '[.result[] | select(.severity == "info")] | length')
echo "Warnings: $WARNINGS, Info: $INFO"
if [ "$WARNINGS" -gt 0 ]; then
echo "Lint warnings found - please fix before merging"
exit 1
fi
if [ "$INFO" -gt 20 ]; then
echo "Too many suggestions - consider improving metadata"
exit 1
fi

Warnings indicate important metadata gaps that affect LLM comprehension.

Info-level suggestions improve AI understanding significantly.

Generic descriptions don’t help AI understand your tools.

Examples help AI understand expected input formats.

Tags help organize and categorize endpoints.

Behavioral hints prevent AI from misusing tools.