Skip to content

Getting Started

Install the SDK, decorate one function, run platools doctor, and connect to the platform. Five minutes, zero boilerplate.

Install

Python

Terminal window
# From PyPI (when published)
pip install platools
# Or from source inside the monorepo
pip install -e packages/platools-py

Python 3.10+ is required. See packages/platools-py/pyproject.toml for the full dependency list.

TypeScript

Terminal window
# From npm (when published)
pnpm add @platools/sdk zod
# Or workspace-link inside the monorepo
pnpm add @platools/sdk@workspace:* zod

Node.js 20+ is required. zod is a peer dependency - you pass Zod schemas directly to platools.tool().

Decorate your first tool (Python)

my_app/tools.py
from typing import Annotated
from platools import Platools
from pydantic import BaseModel, Field
platools = Platools() # reads PLATOS_URL / PLATOS_SECRET from env
class RefundResult(BaseModel):
refund_id: str
amount_cents: int
_USER = {"x-user-providable": True}
@platools.tool(auth="user", roles=["support", "admin"])
def process_refund(
order_id: Annotated[
str,
Field(description="The order ID to refund.", json_schema_extra=_USER),
],
reason: Annotated[
str,
Field(
description="Reason for the refund, surfaced in the audit log.",
json_schema_extra=_USER,
),
],
) -> RefundResult:
"""Process a refund for an order."""
# ... your real refund logic here ...
return RefundResult(refund_id="rf_123", amount_cents=4999)

The decorator introspects process_refund, builds an MCP-compliant input schema from the type hints, and registers the tool with the Platools instance. The function itself is returned unchanged, so unit tests can still call it directly.

Decorate your first tool (TypeScript)

my_app/tools.ts
import { z } from "zod";
import { Platools } from "@platools/sdk";
export const platools = new Platools();
const RefundResult = z.object({
refundId: z.string(),
amountCents: z.number().int(),
});
export const processRefund = platools.tool(
{
name: "process_refund",
description: "Process a refund for an order",
input: z.object({
orderId: z.string(),
reason: z.string(),
}),
output: RefundResult,
auth: "user",
roles: ["support", "admin"],
},
async ({ orderId, reason }) => {
// ... your real refund logic here ...
return { refundId: "rf_123", amountCents: 4999 };
},
);

Same mental model as the Python SDK: a single registration call, the handler is returned untouched, and the SDK stores a ToolDef on the Platools instance’s registry.

Run the ship gate

Terminal window
# Python
platools doctor my_app.tools
# TypeScript - point at the *built* barrel module that imports your tools
pnpm exec platools doctor ./dist/registry.js

platools doctor imports your tool module, walks every Platools instance it finds, and statically analyzes the registry:

  • Every parameter has a type hint + description
  • Auth levels match the sensitivity of the operation
  • Output schemas exist (so agents know what they’re getting)
  • No unreachable / shadowed parameters
  • No destructive tools missing annotations

Doctor exits non-zero on any error-severity finding. Wire it into CI.

Connect to the platform

When you’re ready to expose tools to a real agent:

import asyncio
from my_app.tools import platools
asyncio.run(platools.connect()) # opens outbound WebSocket, runs forever
import { platools } from "./tools.js";
await platools.connect();

The client opens a WebSocket to ${PLATOS_URL}/ws/sdk, sends the JWT from PLATOS_SECRET, registers the tool schemas, and starts dispatching calls. Heartbeat every 30s, exponential-backoff reconnect on drop. No open ports required on your side.

Local MCP mode (no platform)

Test with Claude Desktop or Cursor without deploying Platos:

Terminal window
platools serve --module my_app.tools

This starts a local MCP server on stdio that exposes your registry to any MCP client. See Local mode for the full walkthrough.

Next steps

  • Python SDK - full decorator API, schema generation, client lifecycle, CLI commands.
  • TypeScript SDK - Zod-native tool factory, client, doctor.
  • Examples - runnable reference integrations you can clone and modify.
  • Local mode - develop tools locally with Claude Desktop or Cursor.