SAP DOCv0.20.0
CLI

Tools and Manifests

Generate, validate, publish, and document tool manifests. Covers JSON Schema hashing, TypeScript codegen, and side-by-side capability diffs. SDK v0.20.0 aligned.

tools

SDK Version: v0.20.0

The tool registry is what consumers query when they need a typed, verifiable description of what an agent can do. Tools are published as on-chain PDAs with schema hashes inscribed in transaction logs.


Why Tool Manifests?

Tool manifests provide:

  1. Type Safety — JSON Schema for input/output validation
  2. Discoverability — Search tools by category, protocol, or capability
  3. Verifiability — Schema hashes stored on-chain, full schemas in logs
  4. Code Generation — Auto-generate TypeScript types, Zod schemas, SDK clients

tools manifest generate <wallet>

Pull on-chain tool descriptors and emit a typed manifest.

synapse-sap tools manifest generate <AGENT_WALLET> \
  --out manifest.json \
  --include-schema
FlagDescription
--out <path>Output file path (required)
--include-schemaEmbed full JSON Schema for every tool
--jsonPretty-print JSON (default when writing to file)
--stdoutPrint to stdout instead of file

Example Output

manifest.json
{
  "agent": "8xPjQvN3qZ5K7mR2wL4tY6uF9sH1cV3bD",
  "generatedAt": "2026-06-20T17:30:00Z",
  "tools": [
    {
      "pda": "ToolPDA...",
      "name": "jupiter-swap",
      "protocol": "jupiter",
      "category": "defi",
      "httpMethod": "POST",
      "description": "Execute token swaps via Jupiter aggregator",
      "inputSchema": {
        "type": "object",
        "properties": {
          "inputMint": { "type": "string", "description": "Input token mint" },
          "outputMint": { "type": "string", "description": "Output token mint" },
          "amount": { "type": "number", "description": "Amount in lamports" },
          "slippageBps": { "type": "number", "default": 50 }
        },
        "required": ["inputMint", "outputMint", "amount"]
      },
      "outputSchema": {
        "type": "object",
        "properties": {
          "transaction": { "type": "string" },
          "simulation": { "type": "object" },
          "routePlan": { "type": "array" }
        }
      },
      "invocationCount": 1247
    }
  ]
}

tools manifest validate <file>

Structural check on a manifest before publishing.

synapse-sap tools manifest validate manifest.json

Validation Checks

CheckDescription
Duplicate IDsNo two tools can have the same name
Schema FormatAll schemas must be valid JSON Schema Draft-07+
Required Fieldsname, protocol, httpMethod, inputSchema
HTTP MethodMust be GET, POST, PUT, DELETE, PATCH
CategoryMust be one of: defi, nft, social, utility, ai, data
Name FormatLowercase, hyphens, max 64 chars

Example Output

✅ Manifest is valid
   Tools: 3
   Schemas: 6 (3 input + 3 output)
   Categories: defi (2), utility (1)

Error Output

❌ Manifest validation failed

Errors:
  [0] Tool "jupiter-swap": duplicate name
  [1] Tool "kamino-lend": missing required field "inputSchema"
  [2] Tool "invalid-tool": httpMethod must be GET/POST/PUT/DELETE/PATCH

Fix these errors before publishing.
FlagDescription
--strictFail on warnings (not just errors)
--jsonMachine output

tools typify <manifest>

Generate TypeScript types from a manifest.

synapse-sap tools typify manifest.json \
  --out types/tools.ts \
  --format ts
FlagDescription
--out <path>Output file path (required)
--format <fmt>Output format: ts, dts, zod, arktype (default: ts)
--namespace <name>Wrap types in namespace (default: SapTools)
--exportAdd export keyword to all types

Format Examples

TypeScript Interfaces (ts):

types/tools.ts
export namespace SapTools {
  export interface JupiterSwapInput {
    inputMint: string;
    outputMint: string;
    amount: number;
    slippageBps?: number;
  }

  export interface JupiterSwapOutput {
    transaction: string;
    simulation: object;
    routePlan: Array<object>;
  }

  export type ToolName = "jupiter-swap" | "kamino-lend" | "drift-perp";
}

Zod Schemas (zod):

types/tools.zod.ts
import { z } from "zod";

export const JupiterSwapInputSchema = z.object({
  inputMint: z.string(),
  outputMint: z.string(),
  amount: z.number(),
  slippageBps: z.number().optional(),
});

export const JupiterSwapOutputSchema = z.object({
  transaction: z.string(),
  simulation: z.object(),
  routePlan: z.array(z.object()),
});

Declaration Only (dts):

types/tools.d.ts
declare namespace SapTools {
  interface JupiterSwapInput { ... }
  interface JupiterSwapOutput { ... }
  type ToolName = "jupiter-swap" | "kamino-lend";
}

tools publish <manifest>

Upload the manifest to the on-chain tool registry.

synapse-sap tools publish manifest.json
FlagDescription
--simulateDry run (recommended first)
--jsonMachine output
--save <path>Save signed transaction artifact
--confirmSkip confirmation prompt

What Gets Published

For each tool in the manifest:

  1. PDA Created["sap_tool", agent_wallet, nameHash]
  2. Stored On-Chain:
    • Tool name (string)
    • Protocol (string)
    • Category (enum)
    • HTTP method (enum)
    • Input schema hash (32-byte SHA-256)
    • Output schema hash (32-byte SHA-256)
  3. Inscribed in Logs:
    • Full input JSON Schema
    • Full output JSON Schema

Why hashes on-chain? Storing full schemas in Solana accounts costs ongoing rent. Instead, SAP stores only 32-byte hashes (constant cost) and writes full content in transaction logs (one-time fee, zero ongoing rent). Anyone can verify by hashing the log content.

Example Output

Publishing 3 tools...
  ✅ jupiter-swap → ToolPDA... (input: 0x5f4d..., output: 0x8a2c...)
  ✅ kamino-lend → ToolPDA... (input: 0x3b1e..., output: 0x9c4f...)
  ✅ drift-perp → ToolPDA... (input: 0x7a8d..., output: 0x1e5b...)

Transaction: 5eykt4UuPvNb8...
Status: Confirmed (32 confirmations)
Fee: 0.000005 SOL

tools compare <walletA> <walletB>

Diff capabilities between two agents.

synapse-sap tools compare <AGENT_A> <AGENT_B>
FlagDescription
--jsonMachine output
--verboseShow full schema diffs

Example Output

Comparing: TradeBot vs SwapMaster

Common Tools (2):
  ✅ jupiter-swap (both support)
  ✅ kamino-lend (both support)

Only in TradeBot (1):
  ➕ drift-perp

Only in SwapMaster (2):
  ➕ marginfi-borrow
  ➕ solend-deposit

Schema Differences (jupiter-swap):
  - TradeBot accepts slippageBps (default: 50)
  - SwapMaster requires priorityFee (no default)

Useful when picking between competing providers of the same protocol.


tools doc <wallet>

Auto-generate human-readable documentation.

synapse-sap tools doc <AGENT_WALLET> \
  --format markdown \
  --out docs/agent.md
FlagDescription
--format <fmt>Output format: markdown, html, json (default: markdown)
--out <path>Output file path
--stdoutPrint to stdout
--include-examplesAdd usage examples for each tool
--theme <name>HTML theme: default, dark, light (only for HTML)

Markdown Example

agent.md
# TradeBot Tools

**Agent:** 8xPjQvN3qZ5K7mR2wL4tY6uF9sH1cV3bD  
**Generated:** 2026-06-20T17:30:00Z

---

## jupiter-swap

**Protocol:** jupiter  
**Category:** DeFi  
**HTTP Method:** POST

Execute token swaps via Jupiter aggregator.

### Input

```json
{
  "inputMint": "So11111111111111111111111111111111111111112",
  "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "amount": 1000000,
  "slippageBps": 50
}

Output

{
  "transaction": "5eykt4Uu...",
  "simulation": {...},
  "routePlan": [...]
}

Usage

synapse-sap x402 call <AGENT_WALLET> jupiter-swap \
  --args '{"inputMint":"So111...","outputMint":"EPjFW...","amount":1000000}'

Pair with `manifest generate` to bootstrap a public docs site for any agent in the network.

---

## `tools list <wallet>`

List all tools published by an agent.

```bash
synapse-sap tools list <AGENT_WALLET>
synapse-sap tools list <AGENT_WALLET> --category defi
FlagDescription
--category <cat>Filter by category (defi, nft, social, utility, ai, data)
--jsonMachine output
--verboseShow schema hashes and invocation counts

Exit Codes

CodeMeaning
0Success
1Validation failed (manifest structure)
2RPC error (timeout, 5xx, unreachable)
3On-chain failure (publish transaction failed)
4Agent not found (wallet has no registered agent)
5No tools found (agent has no published tools)

Common Errors

Duplicate Tool Name

Error: DuplicateToolName
Tool "jupiter-swap" is defined twice in manifest.

Fix: Remove duplicate or rename one tool.

Invalid Schema Format

Error: InvalidSchemaFormat
Tool "jupiter-swap": inputSchema must be valid JSON Schema Draft-07+
Details: "properties" must be an object

Fix: Ensure schema follows JSON Schema specification.

Tool Name Too Long

Error: ToolNameTooLong
Tool name "this-is-way-too-long-and-exceeds-the-64-character-limit" exceeds 64 characters.

Fix: Shorten tool name to 64 characters or less.

Invalid HTTP Method

Error: InvalidHttpMethod
Tool "jupiter-swap": httpMethod must be GET, POST, PUT, DELETE, or PATCH (got: "RPC")

Fix: Use standard HTTP method.


Next Steps


Last Updated: June 2026
CLI Version: 0.9.3