Drive MANTYX agents from your code.
MANTYX runs the full agent loop, workspace tools, memory, and observability. These SDKs connect your process to that runtime so you can mixremote tools withlocal handlers in one loop.
Pick your stack
Same wire protocol, three first-party clients.
A one-shot run, in any language
Same call shape across all three SDKs — pick the tab for your stack.
import { MantyxClient, defineLocalTool } from "@mantyx/sdk";import { z } from "zod";import { readFile } from "node:fs/promises";
const client = new MantyxClient({ apiKey: process.env.MANTYX_API_KEY!, workspaceSlug: "acme-corp",});
const result = await client.runAgent({ systemPrompt: "You are a helpful filesystem assistant.", prompt: "Read /etc/hostname and tell me what it says.", tools: [ defineLocalTool({ name: "read_file", parameters: z.object({ path: z.string() }), execute: ({ path }) => readFile(path, "utf8"), }), ],});console.log(result.text);package main
import ( "context" "encoding/json" "fmt" "log" "os"
mantyx "github.com/mantyx-io/mantyx-sdk/go")
type readFileArgs struct { Path string `json:"path" jsonschema:"description=Path to read"`}
func main() { client := mantyx.NewClient(mantyx.Options{ APIKey: os.Getenv("MANTYX_API_KEY"), WorkspaceSlug: "acme-corp", })
tool := mantyx.LocalTool(mantyx.LocalToolSpec{ Name: "read_file", Parameters: &readFileArgs{}, Execute: func(ctx context.Context, raw json.RawMessage) (string, error) { var args readFileArgs if err := json.Unmarshal(raw, &args); err != nil { return "", err } b, err := os.ReadFile(args.Path) return string(b), err }, })
result, err := client.RunAgent(context.Background(), mantyx.RunSpec{ SystemPrompt: "You are a helpful filesystem assistant.", Prompt: "Read /etc/hostname.", Tools: []mantyx.ToolRef{tool}, }) if err != nil { log.Fatal(err) } fmt.Println(result.Text)}import osfrom pathlib import Pathfrom pydantic import BaseModelfrom mantyx import MantyxClient, define_local_tool
class ReadFileArgs(BaseModel): path: str
client = MantyxClient( api_key=os.environ["MANTYX_API_KEY"], workspace_slug="acme-corp",)
result = client.run_agent( system_prompt="You are a helpful filesystem assistant.", prompt="Read /etc/hostname and tell me what it says.", tools=[ define_local_tool( name="read_file", parameters=ReadFileArgs, execute=lambda args: Path(args.path).read_text(), ), ],)print(result.text)Plan-only runs
Get a structured multi-step checklist with runPlan — no agent loop, no tools. The final checklist lives on result.plan.
import { MantyxClient } from "@mantyx/sdk";
const client = new MantyxClient({ apiKey: process.env.MANTYX_API_KEY!, workspaceSlug: process.env.MANTYX_WORKSPACE_SLUG!,});
const result = await client.runPlan({ systemPrompt: "You break complex work into ordered steps.", prompt: "Migrate billing tables from Postgres 14 to 16 and backfill rows.",});
for (const step of result.plan?.steps ?? []) { console.log(`[${step.status}] ${step.title}`);}out, err := client.RunPlan(ctx, mantyx.RunPlanSpec{ RunSpec: mantyx.RunSpec{ SystemPrompt: "You break complex work into ordered steps.", Prompt: "Migrate billing tables from Postgres 14 to 16.", },})if err != nil { log.Fatal(err) }for _, step := range out.Plan.Steps { fmt.Printf("[%s] %s\n", step.Status, step.Title)}result = client.run_plan( system_prompt="You break complex work into ordered steps.", prompt="Migrate billing tables from Postgres 14 to 16 and backfill rows.",)for step in (result.plan or {}).get("steps", []): print(f"[{step['status']}] {step['title']}")