Declarations
The YAML declaration format that paso uses to generate MCP tools.
What is a paso declaration?
A paso declaration is a usepaso.yaml file that describes an API and exposes specific capabilities as MCP tools. You declare what your API can do, and paso generates a standards-compliant MCP server from it.
Declaration: A YAML file (usepaso.yaml) that describes a service, its capabilities, and its permissions. One file per API.
Service: The API being declared. Contains the name, base URL, and auth configuration.
Capability: A single action an agent can take. Maps to one API endpoint with specific inputs and outputs.
Permission tier: A classification (read, write, admin) that controls the risk level of a capability. See Permissions & Safety.
File Structure
The declaration has four sections:
version: "1.0"
service:
name: string
description: string
base_url: string
auth:
type: string
header: string
prefix: string
capabilities:
- name: string
description: string
method: string
path: string
permission: string
consent_required: boolean
inputs: object
output: object
constraints: array
permissions:
read: [capability_names]
write: [capability_names]
admin: [capability_names]
forbidden: [capability_names]
Top-Level Fields
version (required)
Spec version. Must be "1.0".
version: "1.0"
service (required)
Metadata about the API. See Service Object below.
capabilities (required)
List of actions agents can take. See Capabilities below.
permissions (optional)
Groups capabilities into permission tiers. See Permissions.
Service Object
service.name (required)
Human-readable service name. Used in logs and tool registration.
service:
name: Sentry
service.description (required)
What the service does. Agents use this for discovery.
service:
description: Error monitoring and performance tracking for software teams
service.base_url (required)
The root URL of the API. All capability paths are appended to this.
service:
base_url: https://sentry.io/api/0
service.version (optional)
API version string.
service:
version: "0"
service.auth (optional)
Authentication configuration. If omitted, the server runs without authentication.
service:
auth:
type: bearer
Supported auth types: bearer, api_key, oauth2, none.
The auth token is always provided at runtime via the USEPASO_AUTH_TOKEN environment variable. The type field determines how that token is sent in requests.
Bearer Token
auth:
type: bearer
Sends: Authorization: Bearer <USEPASO_AUTH_TOKEN>
API Key
auth:
type: api_key
header: X-API-Key
Sends the token in the specified header. If header is omitted, defaults to Authorization.
Custom Prefix
auth:
type: api_key
prefix: Token
Sends: Authorization: Token <USEPASO_AUTH_TOKEN>
No Auth
auth:
type: none
No authentication header is sent.
Capabilities
Each capability represents one action an agent can take.
name (required)
Machine-readable identifier. Must be snake_case.
- name: list_issues
description (required)
What this action does. Agents read this to decide whether to call it. Write clear, specific descriptions.
description: List issues (errors) in a project, optionally filtered by status
method (required)
HTTP method: GET, POST, PUT, PATCH, DELETE.
method: GET
path (required)
API path relative to base_url. Must start with /. Use {param} for path variables.
path: /projects/{organization_slug}/{project_slug}/issues/
permission (required)
One of read, write, admin. See Permissions & Safety.
permission: read
consent_required (optional)
If true, the agent must confirm with the user before executing. Default: false.
consent_required: true
inputs (optional)
Parameters the agent sends. Keys are parameter names, values describe the parameter.
inputs:
organization_slug:
type: string
required: true
description: The organization slug
in: path
query:
type: string
description: "Search query (e.g., 'is:unresolved')"
in: query
sort:
type: enum
values: [date, new, freq, priority]
default: date
description: Sort order for results
in: query
Input Fields
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | string, integer, number, boolean, enum, array, object |
required | boolean | No | Default: false |
description | string | Yes | What this parameter does |
values | array | For enum | Allowed values |
default | any | No | Default value |
in | string | No | Where the param goes: query, path, body, header. Default: body for POST/PUT/PATCH, query for GET/DELETE |
output (optional)
Describes what the API returns. Keys are field names.
output:
issues:
type: array
description: List of issue objects with id, title, status, count
Output Fields
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | string, integer, number, boolean, object, array |
description | string | No | What this field contains |
constraints (optional)
Business rules and limits. Array of constraint objects.
constraints:
- max_per_hour: 100
description: Bulk status changes are rate-limited
See Permissions & Safety for all constraint types.
Complete Example
version: "1.0"
service:
name: Sentry
description: Error monitoring and performance tracking for software teams
base_url: https://sentry.io/api/0
auth:
type: bearer
capabilities:
- name: list_issues
description: List issues (errors) in a project, optionally filtered by status
method: GET
path: /projects/{organization_slug}/{project_slug}/issues/
permission: read
inputs:
organization_slug:
type: string
required: true
description: The organization slug
in: path
project_slug:
type: string
required: true
description: The project slug
in: path
query:
type: string
description: "Search query (e.g., 'is:unresolved')"
in: query
output:
issues:
type: array
description: List of issue objects
- name: resolve_issue
description: Mark an issue as resolved
method: PUT
path: /issues/{issue_id}/
permission: write
consent_required: true
inputs:
issue_id:
type: string
required: true
description: The issue ID
in: path
status:
type: enum
required: true
values: [resolved, unresolved, ignored]
description: New status for the issue
constraints:
- max_per_hour: 100
description: Bulk status changes are rate-limited
permissions:
read:
- list_issues
write:
- resolve_issue
Validation
Check your declaration:
usepaso validate
This verifies:
- All required fields are present
versionis"1.0"service.nameis non-emptyservice.base_urlis a valid URL- Each capability name is unique and snake_case
- Path parameters (e.g.,
{issue_id}) have matching inputs within: path enumtype inputs havevaluesdefined- Permission tier references match declared capabilities
Your declaration is complete.
You now know every field in a usepaso.yaml file.
Next, you might want to:
- Quick Start. create your first declaration
- Permissions & Safety. understand tiers and constraints
- CLI Commands. reference for all commands
From the blog:
- How to Create an MCP Server. side-by-side comparison of manual vs. paso
- paso vs Writing MCP Servers by Hand. why 30 lines of YAML beats 200 lines of TypeScript