Menu

Programmatic Usage

Use paso as a library to parse declarations and generate MCP servers programmatically.

Can I use paso as a library instead of the CLI?

Yes. paso exports a programmatic API in both Node.js and Python. Use it to parse declarations, validate them, build requests, or generate MCP servers from your own code.

parseFile / parse_file: Load and parse a usepaso.yaml file into a structured object.

validate: Check a parsed declaration against the spec. Returns errors and warnings.

generateMcpServer / generate_mcp_server: Generate a running MCP server from a parsed declaration.

buildRequest / build_request: Construct an HTTP request from a capability name and parameters.

Install

Node.js:

npm install usepaso

Python:

pip install usepaso

Parse a Declaration

Read and parse a usepaso.yaml file into a typed object.

Node.js:

import { parseFile, parseString } from 'usepaso';

// From a file
const decl = parseFile('./usepaso.yaml');

// From a string
const yaml = `
version: "1.0"
service:
  name: MyAPI
  description: My API service
  base_url: https://api.example.com
capabilities: []
`;
const decl2 = parseString(yaml);

Python:

from usepaso import parse_file, parse_string

# From a file
decl = parse_file('./usepaso.yaml')

# From a string
yaml_content = """
version: "1.0"
service:
  name: MyAPI
  description: My API service
  base_url: https://api.example.com
capabilities: []
"""
decl2 = parse_string(yaml_content)

Validate

Check a parsed declaration against the spec. Returns a list of errors and warnings.

Node.js:

import { parseFile, validate } from 'usepaso';

const decl = parseFile('./usepaso.yaml');
const results = validate(decl);

const errors = results.filter(r => r.level !== 'warning');
const warnings = results.filter(r => r.level === 'warning');

if (errors.length > 0) {
  for (const err of errors) {
    console.error(`${err.path}: ${err.message}`);
  }
}

Python:

from usepaso import parse_file, validate

decl = parse_file('./usepaso.yaml')
results = validate(decl)

errors = [r for r in results if getattr(r, 'level', 'error') != 'warning']
warnings = [r for r in results if getattr(r, 'level', 'error') == 'warning']

if errors:
    for err in errors:
        print(f"{err.path}: {err.message}")

Parse and Validate in One Step

A convenience function that parses and validates together. Throws if validation fails. Returns the declaration and any warnings.

Node.js:

import { parseFileAndValidate } from 'usepaso';

try {
  const { declaration, warnings } = parseFileAndValidate('./usepaso.yaml');
  console.log(`Loaded ${declaration.service.name} with ${declaration.capabilities.length} capabilities`);
} catch (err) {
  console.error(err.message);
}

Python:

from usepaso import parse_file_and_validate

try:
    result = parse_file_and_validate('./usepaso.yaml')
    print(f"Loaded {result.declaration.service.name} with {len(result.declaration.capabilities)} capabilities")
except ValueError as err:
    print(err)

There’s also parseAndValidate / parse_and_validate for parsing from a YAML string instead of a file.

Generate an MCP Server

Create an MCP server from a declaration. The server uses stdio transport.

Node.js:

import { parseFileAndValidate, generateMcpServer } from 'usepaso';

const { declaration } = parseFileAndValidate('./usepaso.yaml');
const server = generateMcpServer(declaration);

The returned McpServer object is from the @modelcontextprotocol/sdk package. Each capability becomes an MCP tool with a typed schema and HTTP handler.

Python:

from usepaso import parse_file_and_validate, generate_mcp_server

result = parse_file_and_validate('./usepaso.yaml')
server = generate_mcp_server(result.declaration)

Logging

Pass a callback to log requests:

Node.js:

const server = generateMcpServer(declaration, (capName, result, decl) => {
  console.error(`${capName} → ${result.request.method} ${result.request.url} ← ${result.status}`);
});

Build and Execute Requests

Build HTTP requests from a capability without running a server. Useful for testing or custom integrations.

Node.js:

import { parseFileAndValidate, buildRequest, executeRequest } from 'usepaso';

const { declaration } = parseFileAndValidate('./usepaso.yaml');
const cap = declaration.capabilities.find(c => c.name === 'list_issues');

const authToken = process.env.USEPASO_AUTH_TOKEN;
const req = buildRequest(cap, { organization_slug: 'my-org', project_slug: 'my-project' }, declaration, authToken);

console.log(`${req.method} ${req.url}`);
// GET https://sentry.io/api/0/projects/my-org/my-project/issues/

// Execute it
const result = await executeRequest(req);
console.log(result.status, result.body);

Python:

import os
from usepaso import parse_file_and_validate, build_request, execute_request

result = parse_file_and_validate('./usepaso.yaml')
cap = next(c for c in result.declaration.capabilities if c.name == 'list_issues')

auth_token = os.environ.get('USEPASO_AUTH_TOKEN')
req = build_request(cap, {'organization_slug': 'my-org', 'project_slug': 'my-project'}, result.declaration, auth_token)

print(f"{req.method} {req.url}")

# Execute it
res = execute_request(req)
print(res.status, res.body)

Types

The SDK exports all declaration types for use in your own code.

Node.js:

import type {
  PasoDeclaration,
  PasoService,
  PasoAuth,
  PasoCapability,
  PasoInput,
  PasoOutput,
  PasoConstraint,
  PasoPermissions,
  ValidationError,
} from 'usepaso';

Key Types

TypeDescription
PasoDeclarationTop-level object: version, service, capabilities, permissions
PasoServiceService metadata: name, description, base_url, auth
PasoAuthAuth config: type (api_key, bearer, oauth2, none), header, prefix
PasoCapabilityA single capability: name, method, path, permission, inputs, output, constraints
PasoInputInput parameter: type, required, description, values, default, in
PasoOutputOutput field: type, description
PasoConstraintConstraint: max_per_hour, max_per_request, max_value, requires_field
PasoPermissionsPermission tiers: read, write, admin, forbidden (arrays of capability names)
ValidationErrorValidation result: path, message, level (error or warning)

API Reference

FunctionDescription
parseFile / parse_fileParse a YAML file into a PasoDeclaration
parseString / parse_stringParse a YAML string into a PasoDeclaration
validateValidate a declaration, returns ValidationError[]
parseAndValidate / parse_and_validateParse string + validate. Throws on errors.
parseFileAndValidate / parse_file_and_validateParse file + validate. Throws on errors.
generateMcpServer / generate_mcp_serverGenerate an MCP server from a declaration
buildRequest / build_requestBuild an HTTP request from a capability + args
executeRequest / execute_requestExecute a built request, returns status + body
formatError / format_errorFormat an error response with contextual help
generateFromOpenApiConvert an OpenAPI spec object to a YAML declaration (Node.js only)

Your code, your server.

The CLI is the fastest path. The programmatic API is for when you need more control.

Next, you might want to: