Agent Integration¶
Contio publishes a set of machine-readable artifacts alongside the Partner API docs so that coding agents and LLM toolchains can discover and call the API without hand-coding the integration.
Artifacts¶
| Artifact | URL | Purpose |
|---|---|---|
llms.txt | /partner-api/llms.txt | Human- and LLM-readable index of every Partner API operation. Drop this URL into an agent's context window for a quick overview of available endpoints. |
operations.json | /partner-api/agent/operations.json | Structured per-operation metadata (parameters, request/response schemas, auth surface) enriched with hand-written sidecars. |
mcp.json | /partner-api/agent/mcp.json | Model Context Protocol tool manifest for building MCP servers. |
Quick start
Give your coding agent the llms.txt URL and it will have enough context to explore the API, select the right endpoints, and construct valid requests:
Pointing a coding agent at the API¶
Paste the URL into the agent's prompt or context window:
Fetch operations.json for enriched per-operation metadata:
Using llms.txt¶
The llms.txt file follows the llms.txt standard — a convention for providing LLM-readable context about a site or API. It serves as a human-readable index that coding agents can quickly parse to understand available operations.
What's in llms.txt¶
The file contains:
- Header — Links to related resources (OpenAPI spec,
operations.json,mcp.json) - Authentication summary — Operation counts per auth surface
- Operations by category — Every operation grouped by domain (Meetings, Action Items, etc.)
Each operation entry includes:
Using with Coding Agents¶
Cursor, Windsurf, Copilot, and similar IDE agents:
Add the URL to your project's context or paste it at the start of a conversation:
@https://docs.contio.ai/partner-api/llms.txt
List all meetings for the current user and show their summaries.
Claude, ChatGPT, and similar chat agents:
Include the URL in your prompt:
Read https://docs.contio.ai/partner-api/llms.txt
Help me integrate with the Contio API to:
1. Create a meeting from a calendar event
2. Get the meeting summary when it's ready
3. Create action items for follow-ups
Programmatic context injection:
Fetch and inject into your agent's system prompt:
const llmsTxt = await fetch("https://docs.contio.ai/partner-api/llms.txt").then(r => r.text());
const systemPrompt = `You are an API integration assistant.
Here is the Partner API reference:
${llmsTxt}
Use this information to help the user integrate with the Contio API.`;
When to Use llms.txt vs Other Artifacts¶
| Use Case | Recommended Artifact |
|---|---|
| Quick exploration with a coding agent | llms.txt |
| Building an HTTP client or code generator | operations.json |
| Building an MCP server | mcp.json |
| Full schema validation or SDK generation | OpenAPI spec |
| Pre-built TypeScript/JavaScript client | Partner SDK |
| Manual API testing and exploration | Postman collection |
llms.txt is for discovery, not execution
llms.txt gives agents enough context to understand what the API can do and select the right operations. For how to call them (schemas, parameter types, auth details), agents should fetch operations.json or the OpenAPI spec.
Using operations.json¶
The operations.json file provides structured metadata for every Partner API operation, designed for programmatic consumption by HTTP clients, code generators, and agent toolchains.
Structure¶
Each operation is keyed by its operationId (e.g., listMeetings, createActionItem) and contains:
| Field | Type | Description |
|---|---|---|
id | string | Operation identifier (same as the key) |
method | string | HTTP method (GET, POST, PUT, DELETE, etc.) |
path | string | URL path with parameter placeholders (e.g., /v1/partner/user/meetings/{id}) |
summary | string | Short description of what the operation does |
description | string | Detailed explanation of behavior and requirements |
auth | object | Authentication requirements (see below) |
idempotency | object | Whether Idempotency-Key header is supported |
request | object | Request parameters (path, query, header, body) |
responses | object | Response status codes and their descriptions |
flags | array | Internal flags (e.g., no_sidecar, missing_idempotency_key) |
Authentication Surfaces¶
The auth.surface field indicates which authentication method the operation requires:
| Surface | Auth Header | Description |
|---|---|---|
admin | X-API-Key | Partner Admin API operations (manage your integration) |
user-oauth | Authorization: Bearer <token> | Partner User API operations (access user data) |
public | None | Public endpoints (OAuth flows, discovery, health checks) |
For user-oauth operations, auth.scopes lists required OAuth scopes:
Building an HTTP Client¶
Use operations.json to dynamically construct API requests:
import operations from "./operations.json" assert { type: "json" };
async function callPartnerApi(
operationId: string,
params: Record<string, any>,
auth: { apiKey?: string; accessToken?: string }
) {
const op = operations[operationId];
if (!op) throw new Error(`Unknown operation: ${operationId}`);
// Build URL with path parameters
let url = `https://api.contio.ai${op.path}`;
for (const param of op.request?.parameters ?? []) {
if (param.in === "path") {
url = url.replace(`{${param.name}}`, params[param.name]);
}
}
// Build headers based on auth surface
const headers: Record<string, string> = { "Content-Type": "application/json" };
if (op.auth.surface === "admin" && auth.apiKey) {
headers["X-API-Key"] = auth.apiKey;
} else if (op.auth.surface === "user-oauth" && auth.accessToken) {
headers["Authorization"] = `Bearer ${auth.accessToken}`;
}
// Add idempotency key for mutations if supported
if (op.idempotency?.supported && op.method !== "GET") {
headers["Idempotency-Key"] = crypto.randomUUID();
}
// Build query string and body
const queryParams = new URLSearchParams();
let body: string | undefined;
for (const param of op.request?.parameters ?? []) {
if (param.in === "query" && params[param.name] !== undefined) {
queryParams.set(param.name, params[param.name]);
}
if (param.in === "body") {
body = JSON.stringify(params[param.name]);
}
}
const queryString = queryParams.toString();
const fullUrl = queryString ? `${url}?${queryString}` : url;
const response = await fetch(fullUrl, { method: op.method, headers, body });
return response.json();
}
// Usage
const meetings = await callPartnerApi("listMeetings", {}, { accessToken: "..." });
Idempotency Support¶
Operations with idempotency.supported: true accept an Idempotency-Key header for safe retries. The response includes:
Idempotent-Replayed: trueheader when returning a cached response422withidempotency_key_reuseif the key was used with different parameters409withRetry-Afterheader for concurrent requests with the same key
Relationship to Other Artifacts¶
| Artifact | Use Case |
|---|---|
operations.json | Build HTTP clients, code generators, or agent tool implementations |
mcp.json | Build MCP servers (includes tool schemas derived from this data) |
llms.txt | Quick context injection for coding agents (human-readable) |
| OpenAPI spec | Full request/response JSON schemas, validation, and SDK generation |
| Partner SDK | Pre-built TypeScript/JavaScript client with high-level resource abstractions |
| Postman collection | Interactive API testing, exploration, and request prototyping |
When to use operations.json vs OpenAPI vs SDK
Use operations.json when you need a flat, operation-centric view with pre-computed auth and idempotency metadata. Use the OpenAPI spec when you need full JSON schemas for request validation or response typing. Use the Partner SDK when you want a batteries-included TypeScript client without building your own HTTP layer.
Using MCP with the Partner API¶
The Model Context Protocol (MCP) enables AI agents to call tools through a standardized interface. To expose Partner API operations as MCP tools, you build an MCP server that translates tool calls into API requests.
Understanding mcp.json¶
The mcp.json file is a tool manifest containing 120+ tool definitions—one for each Partner API operation. Each tool includes:
name— The operation identifier (e.g.,listMeetings,createActionItem)description— What the tool doesinputSchema— JSON Schema 2020-12 defining the parametersannotations— Behavioral hints per the MCP specification:readOnlyHint— Tool only reads data (safe to call without side effects)destructiveHint— Tool may delete or modify data irreversiblyidempotentHint— Repeated calls with same input produce same result
Tool manifest, not server config
mcp.json defines what tools exist, not how to connect to a server. MCP clients expect a server configuration (URL, command, etc.), not a raw tool list. Use mcp.json as input when building your MCP server.
Building an MCP Server¶
To serve Partner API operations via MCP, implement a server that:
- Responds to
tools/list— Return the tools frommcp.json - Handles
tools/call— Map the tool name to a Partner API endpoint, execute the HTTP request, and return the result
Refer to these MCP resources:
- Server Concepts — Architecture overview
- Tools — Tool definition format and annotations
- TypeScript SDK — Reference implementation
- Python SDK — Alternative implementation
Example: Minimal TypeScript server structure
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import tools from "./mcp.json" assert { type: "json" };
const server = new Server({ name: "contio-partner", version: "1.0.0" }, {
capabilities: { tools: {} }
});
// Return all tools from the manifest
server.setRequestHandler("tools/list", async () => ({ tools: tools.tools }));
// Execute tool calls by mapping to Partner API endpoints
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;
// Map tool name to endpoint, make HTTP request, return result
const result = await executePartnerApiCall(name, args);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
});
const transport = new StdioServerTransport();
await server.connect(transport);
Server Configuration¶
Once you've built and deployed your MCP server, configure your MCP client to connect to it. The configuration format depends on the transport:
Local stdio server:
Remote HTTP/SSE server:
Authentication¶
Agents still need valid credentials. See the Authentication guide for how to obtain API keys (admin operations) or OAuth tokens (user operations).