Tool Servers
Where you turn TypeScript code into Convilyn tools — defineTool (Zod), ToolServer, ToolResult, and the manifest / data-store / context / config primitives.
Install
npm install @convilyn/sdk-authorNode 18+ (uses node:crypto). Ships ESM + CJS + type declarations, with zero runtime dependencies. zod is a peerDependency — install it alongside and import { z } from 'zod' yourself.
defineTool (Zod)
defineTool declares a tool from a Zod schema — the single source of truth for the manifest input_schema, the handler argument types, and runtime validation of inbound calls.
import { defineTool, ToolResult } from "@convilyn/sdk-author";
import { z } from "zod";
const echo = defineTool({
name: "echo",
description: "Echo the input text back.",
input: z.object({ text: z.string().min(1) }),
idempotent: true,
handler: (args) =>
ToolResult.ok({ echoed: args.text }, `Echoed ${args.text.length} chars`),
});The handler receives args typed from the Zod schema; the gateway-supplied input is validated against that schema before your handler runs.
ToolServer
ToolServer owns a tool registry. Register the tools you defined, then hand the server to the runtime (serve) or the local harness (invokeTool).
import { ToolServer } from "@convilyn/sdk-author";
const server = new ToolServer({
name: "echo-server",
version: "1.0.0",
description: "demo",
});
server.register(echo);ToolResult
Tools return { ref_id, summary } so the agent's context stays small and the full data is fetched by ref_id later. Build the envelope with ToolResult.ok(...) / ToolResult.fail(...).
import { ToolResult, InMemoryDataStore } from "@convilyn/sdk-author";
const store = new InMemoryDataStore();
const refId = await store.store({ large: "payload" }); // → "td_<12-hex>"
const result = ToolResult.ok({ refId, summary: "Weather for Taipei" });| Helper | Use |
|---|---|
ToolResult.ok(data, summary?) | Successful result; data is stashed and surfaced by ref_id, summary is a short human line for the agent |
ToolResult.fail(...) | Failed result the agent can reason about |
Manifest
ConvilynManifest describes your server and its tools. Save it to disk for synth / publishing.
import { ConvilynManifest } from "@convilyn/sdk-author";
const manifest = new ConvilynManifest(
{ name: "weather", version: "1.0.0", description: "Weather tools" },
{
tools: [
{
name: "get_weather",
description: "Get current weather",
inputSchema: {
type: "object",
properties: { location: { type: "string" } },
},
idempotent: true,
},
],
},
);
await manifest.save("convilyn.manifest.json");Data store
InMemoryDataStore stashes large payloads off the LLM context and returns a reference ID.
import { InMemoryDataStore } from "@convilyn/sdk-author";
const store = new InMemoryDataStore();
const refId = await store.store({ large: "payload" }); // → "td_<12-hex>"Config
SDKConfig.fromEnv() reads the CONVILYN_* environment variables (HMAC secret, port, …) so the runtime and platform client pick up their settings without hardcoding.
import { SDKConfig } from "@convilyn/sdk-author";
const config = SDKConfig.fromEnv(); // reads CONVILYN_* env varsWhere to go next
Run the JSON-RPC /mcp server, verify inbound HMAC, and test in-process.
Scaffold, run, synth, and test with convilyn-author.
Register + publish your tool server with ConvilynClient (Developer
Portal).
Back up to the Author SDK landing page.