TypeScript SDK Reference
This page documents the public API of @syntic/agent-sdk, the TypeScript distribution of the Syntic Agent SDK. All exports connect to Amara on the Syntic model through api.syntic.ai. Install with npm install @syntic/agent-sdk and import from the package root.
import {
query,
tool,
createSdkMcpServer,
type Options,
type SdkMessage,
} from "@syntic/agent-sdk";query()
query() is the single entry point for running an agent. It accepts a prompt and options and returns an async iterable of messages that stream as Amara reasons, calls tools, and produces a result.
function query(input: {
prompt: string | AsyncIterable<UserMessage>;
options?: Options;
}): AsyncIterable<SdkMessage>;The prompt may be a plain string for a one-shot request, or an async iterable of user messages for a live, multi-turn streaming session. Iterating the returned value drives the agent loop forward; the loop completes when a result message is emitted.
for await (const message of query({
prompt: "Refactor utils.ts to remove duplication.",
options: { cwd: process.cwd(), permissionMode: "acceptEdits" },
})) {
if (message.type === "assistant") process.stdout.write(message.text ?? "");
if (message.type === "result") console.log("\nDone:", message.result);
}The returned iterable also exposes control methods on long-running sessions, including interrupt() to stop the current turn and setModel() to switch models mid-session.
Options
Options configures the agent’s environment, model, and governance. Every field is optional; sensible defaults apply.
| Field | Type | Description |
|---|---|---|
cwd | string | Working directory the agent operates in. |
model | string | Syntic model identifier to run Amara on. |
systemPrompt | string | { preset: string; append?: string } | Replace or extend the default system prompt. |
permissionMode | "default" | "acceptEdits" | "plan" | "bypassPermissions" | How tool calls are gated. |
allowedTools | string[] | Whitelist of tool names Amara may use. |
disallowedTools | string[] | Tools to exclude from the session. |
mcpServers | Record<string, McpServerConfig> | MCP servers to connect, including in-process SDK servers. |
canUseTool | CanUseTool | Callback invoked before each tool call for approval. |
hooks | HookConfig | Lifecycle hook callbacks. |
maxTurns | number | Upper bound on agent loop iterations. |
resume | string | Session id to resume a persisted conversation. |
Messages
The iterable yields a discriminated union, SdkMessage, keyed on type.
type | Meaning |
|---|---|
system | Session initialization and metadata. |
assistant | Text or tool-call content produced by Amara. |
user | User or tool-result content fed back into the loop. |
result | Terminal message with the final result string, usage, and cost. |
Narrow on message.type to handle each case. The result message carries usage (token counts) and total_cost_usd, which you can log for cost tracking.
tool() and createSdkMcpServer()
Define in-process tools with tool() and expose them through an SDK-backed MCP server with createSdkMcpServer(). Schemas are declared with Zod, giving Amara typed inputs.
import { z } from "zod";
const getWeather = tool(
"get_weather",
"Return the current weather for a city.",
{ city: z.string() },
async ({ city }) => ({
content: [{ type: "text", text: `Sunny in ${city}.` }],
}),
);
const server = createSdkMcpServer({ name: "weather", tools: [getWeather] });Pass the server through options.mcpServers. The CanUseTool callback type — (name: string, input: unknown) => Promise<PermissionResult> — lets you approve, deny, or modify each call. See Custom tools and Permissions for usage patterns.