Docs/SDK and API/Go SDK/Tools & Surface

Tools & Surface

This page is the practical Go SDK tutorial for the runtime-owned action layer. It shows how to inspect the built-in tool inventory, shape a workflow-specific session surface, attach governance, add MCP tools, and understand what is and is not a clean public customization path today.

What This Page Covers

Boundary

This page is about the action layer: built-in tools, session shaping, permission-sensitive execution, and MCP extensions. Provider setup, OAuth, capability-provider auth, and Codex login flows belong in Providers & Auth.

If you need provider setup, continue with Providers & Auth. If you want the architectural why behind the separation, continue with Tools & Providers.

Integration Patterns

Read-only analysis worker

Keep the built-in inventory, then remove file mutation and shell tools for audit, review, or architecture analysis workflows.

Coding worker

Keep edit and shell tools enabled, but add permission mode and pre-tool governance so mutating actions still flow through host policy.

External-tool worker

Attach MCP servers to pull GitHub, issue tracker, CRM, or domain-specific tools into the same runtime loop.

Task-shaped session

Use one shared client and create multiple session profiles by changing permission mode and unregistering tools per workflow.

The Host Workflow

For Go hosts, the clean path is simple: create one client, inspect what exists, apply workflow-specific trimming per session, then extend or govern the surface where needed. You do not need to fight the runtime to keep the host in control.

Runtime Inventory
Built-in Registry

Filesystem, shell, browser, planning, memory, notebook, agent, and multimedia tools are registered locally in one canonical inventory.

Primary tool catalog
Extensions
MCP + Deferred Tools

External tools can be injected through MCP and lower-priority tools can stay deferred until the runtime explicitly discovers them.

Expandable action layer
Governance
Permission Gate

Permission mode, read-only metadata, destructive checks, shell hooks, and surface profiles decide what the session may actually execute.

Host-controlled execution
Session API
Visible Tool Surface

The host can inspect the surface, unregister tools for one session, and let the model work only with the final filtered set.

Per-session shaping
Go Host Contract
Create once, inspect once, shape per session

The clean host pattern is straightforward: create the client, inspect the inventory, define workflow-specific session policies, attach governance, and then let the runtime execute one governed loop.

Discovery Path
Deferred tools keep prompts smaller

Deferred tools stay out of the initial surface and are discovered only when the runtime needs them.

Hot Reload
MCP servers can be reloaded

The host can refresh external MCP integrations without rebuilding the whole client surface from scratch.

1. Create the client

Pick the model, permission mode, and optional MCP servers for the host app.

2. Inspect the inventory

Use ToolNames() and BuildToolSurface() to see what the runtime is about to expose.

3. Trim the session

Remove risky tools or change permission mode for one workflow before sending the turn.

4. Stream and observe

Use runtime events and chunk callbacks to keep your UI or backend worker observable.

5. Extend with MCP

Bring in external tools and refresh them later without tearing down the whole process.

6. Execute one governed loop

The runtime still owns prompt, tool calls, permissions, memory, and session persistence coherently.

Step 1: Inspect The Inventory

Start by checking what the runtime already exposes. client.ToolNames() returns the registered primary names. client.BuildToolSurface(ctx) shows the filtered external surface the runtime would expose after registry-level rules are applied.

Inspecting tools
client, err := sdk.NewClient(&sdk.ClientConfig{
    Model: sdk.ModelIdentifier{
        Provider: sdk.APIProviderAnthropic,
        Model:    "claude-sonnet-4-20250514",
    },
    APIKey:         os.Getenv("ANTHROPIC_API_KEY"),
    PermissionMode: sdk.PermissionModeOnRequest,
})
if err != nil {
    log.Fatal(err)
}
defer client.Close()

fmt.Println(client.ToolNames())

surface, err := client.BuildToolSurface(ctx)
if err != nil {
    log.Fatal(err)
}
for _, tool := range surface.Tools {
    fmt.Println(tool.Name)
}

Step 2: Create A Workflow-Specific Session

Do not destroy the shared client inventory just because one workflow is stricter than another. The practical pattern is to create the session, set the right permission mode, unregister the tools that do not belong in that workflow, and only then submit the task.

Read-only review session
session, err := client.CreateSession(ctx)
if err != nil {
    log.Fatal(err)
}
defer session.Close()

session.SetPermissionMode(sdk.PermissionModeOnRequest)

for _, blocked := range []string{"bash", "write_file", "edit_file", "apply_patch"} {
    _ = session.UnregisterTool(blocked)
}

fmt.Println(session.GetToolNames())

resp, err := session.SubmitMessage(ctx, "Audit the repository and report findings only.")
if err != nil {
    log.Fatal(err)
}

fmt.Println(resp.StopReason)
Reusable host-side session profile
type WorkerProfile struct {
    Name           string
    PermissionMode sdk.PermissionMode
    RemoveTools    []string
}

func NewWorkerSession(ctx context.Context, client *sdk.Client, profile WorkerProfile) (*sdk.Session, error) {
    session, err := client.CreateSession(ctx)
    if err != nil {
        return nil, err
    }

    session.SetPermissionMode(profile.PermissionMode)
    for _, toolName := range profile.RemoveTools {
        _ = session.UnregisterTool(toolName)
    }

    return session, nil
}

reviewSession, err := NewWorkerSession(ctx, client, WorkerProfile{
    Name:           "review",
    PermissionMode: sdk.PermissionModeOnRequest,
    RemoveTools:    []string{"bash", "write_file", "edit_file", "apply_patch"},
})

Step 3: Add Governance For Mutating Tools

Shaping the visible surface is only one half of host control. Execution still goes through permission mode and optional pre-tool hooks. That is the clean SDK-level place to block, rewrite, or strictly review high-risk calls like shell execution and file mutation.

Pre-tool governance
client, err := sdk.NewClient(&sdk.ClientConfig{
    Model: sdk.ModelIdentifier{
        Provider: sdk.APIProviderAnthropic,
        Model:    "claude-sonnet-4-20250514",
    },
    APIKey:         os.Getenv("ANTHROPIC_API_KEY"),
    PermissionMode: sdk.PermissionModeOnRequest,
    PreToolHooks: []sdk.PreToolHookConfig{
        {
            Matcher: "bash|write_file|edit_file|apply_patch",
            Command: "./scripts/pre_tool_guard.sh",
            Timeout: 5,
        },
    },
})
  • PermissionMode decides the runtime approval posture for the session.
  • PreToolHooks let the host allow, deny, halt, or rewrite tool calls before they execute.
  • session.SetPermissionMode(...) lets one session become stricter or looser than the client default.

Step 4: Extend The Surface With MCP

When built-ins are not enough, MCP is the clean extension path. You can register servers when the client starts, and later refresh them with client.ReloadMCPServers(ctx, ...) if the external tool surface changes.

MCP integration
servers := []sdk.MCPServerConfig{
    {
        Name:      "github",
        Transport: sdk.MCPTransportStdio,
        Command:   "npx",
        Args:      []string{"-y", "@modelcontextprotocol/server-github"},
    },
}

client, err := sdk.NewClient(&sdk.ClientConfig{
    Model: sdk.ModelIdentifier{
        Provider: sdk.APIProviderAnthropic,
        Model:    "claude-sonnet-4-20250514",
    },
    APIKey:     os.Getenv("ANTHROPIC_API_KEY"),
    MCPServers: servers,
})
if err != nil {
    log.Fatal(err)
}
defer client.Close()

if err := client.ReloadMCPServers(ctx, servers); err != nil {
    log.Fatal(err)
}

Custom Tool Boundary Today

The public SDK already exposes client.RegisterTool(...), client.RegisterTools(...), and session.RegisterTool(...). But there is an important boundary to understand before you build on that.

Current public boundary
// Public SDK surface today:
// - client.ToolNames()
// - client.BuildToolSurface(ctx)
// - client.RegisterTool(...)
// - session.RegisterTool(...)
// - session.UnregisterTool(...)
// - client.ReloadMCPServers(...)
// - ClientConfig.PreToolHooks
//
// Practical guidance:
// Start with built-in tools + MCP + session shaping first.
// Custom tools are possible, but their implementation still follows the
// underlying runtime tool contract rather than a simplified SDK-only builder.
Pragmatic Guidance

If you are integrating Seshat into a product today, start with built-in tools, session shaping, permission governance, and MCP. Custom tools are possible, but the implementation contract still mirrors the runtime tool interface more closely than a dedicated SDK-first builder API.

Inventory Snapshot

These counts come from the current runtime registry: builtin tools first, then the extra agent tools that are only registered once the live engine instance exists.

102Known tool entries

Builtin registry entries plus engine-wired agent tools.

99Builtin registry tools

The initial runtime inventory before later engine-specific additions.

77Builtin tools enabled

Disabled entries are usually waiting for credentials, capability config, or fuller implementation.

3Engine-wired agent tools

Registered later because they depend on the live engine instance, not only on the builtin registry.

Tool State Semantics

The raw inventory only becomes useful once you understand how the runtime filters it. SurfaceBuilder asks the registry for a candidate surface, then applies permission checks, category filters, read-only or destructive filters, deferred-loading rules, and surface-profile visibility.

Runtime flagMeaningComes fromEffect on the surface
enabledThe tool is active in the registry and can participate in the runtime surface.tool.IsEnabled()The tool may appear in the model-visible surface once the other filters pass.
disabledThe tool is registered conceptually but intentionally not active yet.tool.IsEnabled() == falseThe tool is skipped before prompt exposure and execution.
read-onlyThe tool does not modify state for that specific invocation path.Definition.IsReadOnly plus IsReadOnly(input)Surface builders and plan mode can treat it differently from mutating tools.
requires_permissionThe tool enters the permission pipeline before execution.Definition.RequiresPermissionThe user or policy layer may allow, deny, or rewrite access before the call runs.
deferredThe tool should stay out of the initial surface and be discovered later.Definition.ShouldDefer or Definition.IsMCPWhen tool search surface mode is enabled, deferred tools stay out of the initial surface and are discovered through tool_search.
always-loadThe tool should never be hidden by deferred loading.Definition.AlwaysLoadThe tool remains visible even when deferred loading is active. tool_search is the canonical example.
surface profileThe tool may be limited to mono_run or another specific runtime surface.Definition.Metadata.surface_profilesA tool can exist in the registry but still be hidden from a given session profile.

One important detail is deferred loading. When tool search mode is active, deferred tools stay out of the initial model-visible surface and must be discovered through tool_search. If a tool is marked AlwaysLoad, that rule wins and the tool stays visible.

Tool Families And Exact Runtime Flags

The tables below reflect the current runtime metadata for each tool: whether it is enabled, whether it is read-only, and whether it enters the permission pipeline. This is the useful developer view because it follows the actual registry state, not a simplified marketing list.

Filesystem & Process Surface

This is the local execution layer: file reads and writes, patching, shell execution, background jobs, directory traversal, and long-running process monitoring.

ToolCategoryStateRead-onlyPermissionNotes
apply_patchfilesystemenablednorequired
bashfilesystemenablednorequiredShell execution surface with permission gating and mono-run focus.
create_directoryfilesystemenablednorequired
edit_filefilesystemenablednorequired
get_file_metadatafilesystemenabledyesnot required
globfilesystemenabledyesrequired
grepfilesystemenabledyesrequired
job_killfilesystemenablednonot required
job_outputfilesystemenablednonot required
list_directoryfilesystemenabledyesnot required
monitorprocessenablednonot requiredSession-level process monitoring for background execution.
read_document_urlfilesystemenabledyesrequired
read_filefilesystemenabledyesrequired
remove_filefilesystemenablednorequired
write_filefilesystemenablednorequired
write_stdinfilesystemenablednonot required

Web & Browser Surface

Seshat separates URL fetching from full browser control. Web fetch/search cover discovery and extraction, while browser_* tools expose a stateful browser session with page, network, and interaction primitives.

ToolCategoryStateRead-onlyPermissionNotes
browser_clickbrowserenablednorequired
browser_close_pagebrowserenablednonot required
browser_extractbrowserenabledyesnot required
browser_get_network_policybrowserenabledyesnot required
browser_list_downloadsbrowserenabledyesnot required
browser_list_pagesbrowserenabledyesnot required
browser_navigatebrowserenablednorequired
browser_network_listbrowserenabledyesnot required
browser_openbrowserenablednorequired
browser_pressbrowserenablednorequired
browser_screenshotbrowserenabledyesnot required
browser_scrollbrowserenabledyesnot required
browser_search_contentbrowserenabledyesnot required
browser_select_pagebrowserenablednonot required
browser_set_network_policybrowserenablednonot required
browser_snapshotbrowserenabledyesnot required
browser_typebrowserenablednorequired
browser_waitbrowserenabledyesnot required
web_fetchwebenabledyesnot requiredTargeted extraction once the runtime already knows the page to inspect.
web_searchwebenabledyesrequiredUses the configured web-search provider and goes through the permission pipeline.

Code, Notebooks & IDE Hooks

These tools cover code completion, LSP-assisted inspection, and full notebook lifecycle operations from creation to execution and kernel control.

ToolCategoryStateRead-onlyPermissionNotes
code_completecodedisablednonot requiredFill-in-the-middle style code completion surface; disabled until a completer backend is configured.
lspcode_intelligenceenablednonot required
notebook_createnotebookenablednorequired
notebook_editnotebookenablednorequired
notebook_executenotebookenablednorequired
notebook_kernelnotebookenablednorequired
notebook_readnotebookenabledyesnot required
notebook_runnotebookenablednorequired
notebook_writenotebookenablednorequired

Planning, Tasks & Runtime Control

These tools control how the agent works: ask-user pauses, plan mode transitions, task objects, goal tracking, permission requests, and the meta discovery surface.

ToolCategoryStateRead-onlyPermissionNotes
ask_user_questioninteractionenabledyesnot required
create_goalgoalenablednonot required
enter_plan_modeplanningenabledyesrequired
exit_plan_modemodeenablednorequired
get_goalgoalenabledyesnot required
request_permissionspermissionsenablednorequired
submit_planmodedisablednonot required
task_createtaskenablednonot required
task_gettaskenablednonot required
task_listtaskenablednonot required
task_stoptaskenablednonot required
task_updatetaskenablednonot required
tool_searchmetadisabledyesnot requiredSpecial discovery helper. It is marked AlwaysLoad in the registry even though runtime enablement is optimistic.
update_goalgoalenablednonot required

Memory & Retrieval

Long-term memory and retrieval are explicit tools, not hidden side effects. The runtime can write to knowledge-graph memory or query indexed corpora through the RAG surface.

ToolCategoryStateRead-onlyPermissionNotes
memory_add_observationsmemorydisablednonot requiredBacked by the LongTermMemory service rather than by raw prompt stuffing.
memory_create_entitiesmemorydisablednonot requiredBacked by the LongTermMemory service rather than by raw prompt stuffing.
memory_open_nodesmemorydisabledyesnot requiredBacked by the LongTermMemory service rather than by raw prompt stuffing.
memory_search_nodesmemorydisabledyesnot requiredBacked by the LongTermMemory service rather than by raw prompt stuffing.
rag_ingestragdisablednorequiredBacked by the configured RAG service and corpus index.
rag_searchragdisabledyesnot requiredBacked by the configured RAG service and corpus index.

Skills, MCP & Worktree Extensions

This family covers runtime extensibility: generic MCP access, installed Seshat skills, the skill execution tool, and isolated worktree helpers.

ToolCategoryStateRead-onlyPermissionNotes
enter_worktreeworktreeenablednorequired
exit_worktreeworktreeenablednorequired
mcpmcpenabledyesrequiredGateway tool for configured MCP servers. Separate MCP-loaded tools can also appear as runtime-discovered surface entries.
seshat_list_skillsruntime-specificenabledyesnot requiredSkill package introspection helpers used to list, read, or validate installed Seshat skills.
seshat_read_skillruntime-specificenabledyesnot requiredSkill package introspection helpers used to list, read, or validate installed Seshat skills.
seshat_validate_skillruntime-specificenabledyesnot requiredSkill package introspection helpers used to list, read, or validate installed Seshat skills.
skillruntime-specificenablednonot requiredExecutes a resolved skill directly inside the main conversation loop.

Agents & Delegation

Agent control is split between builtin coordination tools and engine-wired delegation tools that are only registered once the live engine instance exists.

ToolCategoryStateRead-onlyPermissionNotes
agentagentenablednorequiredRegistered later in sdk.NewClient because it needs the live engine instance.
close_agentagentsenablednonot required
list_agentsagentsenabledyesnot required
resume_agentagentsenablednonot requiredRegistered later in sdk.NewClient because it needs the live engine instance.
send_agent_messageagentsenablednonot required
spawn_agentagentsenablednonot requiredRegistered later in sdk.NewClient because it needs the live engine instance.
wait_agentagentsenabledyesnot required

Media & Multimodal Capabilities

These tools are capability-provider driven. They are usually disabled until the matching image or audio backend is configured.

ToolCategoryStateRead-onlyPermissionNotes
generate_imagecreativedisablednonot requiredEnabled only when an image-generation provider is configured.
speech_to_textaudiodisablednonot requiredEnabled only when the corresponding audio provider is configured.
text_to_speechaudiodisablednonot requiredEnabled only when the corresponding audio provider is configured.

Math & Analysis Helpers

Fast deterministic helpers for calculation, units, statistics, and financial analysis. These tools stay cheap, local, and read-only.

ToolCategoryStateRead-onlyPermissionNotes
calculatormathenabledyesnot required
financial_calcmathenabledyesnot required
statisticsmathenabledyesnot required
unit_convertmathenabledyesnot required

VCS, Social & Notification Integrations

This family mixes community data tools, outbound messaging tools, and VCS helpers. Several entries are present in the surface design but remain disabled until implementation or credentials are ready.

ToolCategoryStateRead-onlyPermissionNotes
devto_articlesocialenabledyesnot required
devto_feedsocialenabledyesnot required
devto_publishsocialenablednorequired
discord_sendnotificationsdisablednorequiredCompiled into the surface design, but disabled until credentials and/or implementation are ready.
email_sendnotificationsdisablednorequiredCompiled into the surface design, but disabled until credentials and/or implementation are ready.
git_branchvcsdisablednonot requiredPresent in the runtime inventory, but currently disabled in the builtin surface.
git_commitvcsdisablednorequiredPresent in the runtime inventory, but currently disabled in the builtin surface.
git_diffvcsdisablednonot requiredPresent in the runtime inventory, but currently disabled in the builtin surface.
git_logvcsdisablednonot requiredPresent in the runtime inventory, but currently disabled in the builtin surface.
git_statusvcsdisablednonot requiredPresent in the runtime inventory, but currently disabled in the builtin surface.
hn_itemsocialenabledyesnot required
hn_searchsocialenabledyesnot required
hn_storiessocialenabledyesnot required
slack_sendnotificationsdisablednorequiredCompiled into the surface design, but disabled until credentials and/or implementation are ready.
telegram_sendnotificationsdisablednorequiredCompiled into the surface design, but disabled until credentials and/or implementation are ready.
whatsapp_sendsocialdisablednorequiredCompiled into the surface design, but disabled until credentials and/or implementation are ready.

Related Pages

Continue with Providers & Auth for provider setup, OAuth, and Codex. For the extensibility side, continue with Skills and MCP.