MCP & Tools

Tools give your agent capabilities beyond conversation. They are declared under the tools key in your agent YAML, each identified by a name you choose.

Omnigent supports MCP servers, built-in tools, Python functions, sub-agents, and inherited tools.

MCP servers

MCP (Model Context Protocol) servers expose tools over a standard protocol.

On a shared session, the servers an uploaded agent declares can also be managed from the web UI's Agent info panel — but only by the session's owner. Edit collaborators see the list read-only. See Only the owner can change the agent.

On a server that publishes an administrator-managed MCP registry, you can also turn on server-configured services for a single session from the new-chat composer's MCPs control, without declaring them in the agent YAML; credentials stay on the server. See Choose MCP services before launch.

Custom servers

For MCP servers not in the bundled set, declare them in your agent YAML. Transport is inferred: use command for local stdio servers, url for remote HTTP/SSE servers.

Local command (stdio):

tools:
  my-server:
    type: mcp
    command: node
    args: [dist/server.js]
    env:
      API_KEY: ${MY_API_KEY}          # env vars expanded at runtime

Remote URL (HTTP/SSE):

tools:
  docs-api:
    type: mcp
    url: https://example.com/mcp
    headers:
      Authorization: "Bearer ${API_TOKEN}"   # env vars expanded at runtime

The optional tools list filters which MCP tools are exposed to the agent. It works the same on both transports — list the tool names you want to allow, and only those are surfaced to the model:

tools:
  github:
    type: mcp
    command: npx
    args: [-y, server-github]
    tools: [search_issues, get_pull_request]   # only these two are exposed

Omit tools to expose everything the server provides.

Sidecar MCP files

Instead of declaring an MCP server inline under tools in config.yaml, you can keep it in its own file under the agent's tools/mcp/ directory. Omnigent discovers every tools/mcp/*.yaml at load time. A sidecar file names the server and its transport explicitly (transport: stdio with command/args, or transport: http with url) and accepts the same optional tools allow-list as the inline form:

# tools/mcp/github.yaml
name: github
transport: stdio
command: npx
args: [-y, server-github]
tools: [search_issues, get_pull_request]   # only these two are exposed
# tools/mcp/docs.yaml
name: docs
transport: http
url: https://mcp.example.com/sse
tools: [search_docs]

The tools allow-list is enforced identically whether the server is declared inline or in a sidecar file: only the listed tool names are advertised to the model, omitting tools exposes everything the server provides, and a tools value that is not a list is rejected at load time with an error naming the file.

Authentication

As shown in the examples above, custom MCP servers accept credentials through:

tools:
  internal-api:
    type: mcp
    url: https://my-workspace.databricks.com/mcp
    auth:
      type: databricks
      profile: my-profile

Built-in tools

Omnigent ships a set of built-in tools you can enable by name under tools.builtins, without writing any code.

web_search

A unified web search tool whose backend is determined by your agent spec:

Supported backends:

search_providerAPI keyNotes
duckduckgoKeylessNo api_key required
keenableOptionalKeyless by default; supply api_key to lift rate limits
googleRequiredAlso requires engine_id
perplexityRequired
nimbleRequired
tavilyRequired

Keyless backends run out of the box; keyed backends need credentials for a sturdier, higher-rate service.

tools:
  builtins:
    - name: web_search
      search_provider: duckduckgo   # a keyless backend, as an example
      # api_key: ${PERPLEXITY_API_KEY}   # required for keyed backends

Keenable

Keenable is keyless by default. With no api_key in the spec it calls the keyless public endpoint and runs out of the box; supplying an api_key switches to the authenticated endpoint and lifts rate limits. Set the optional max_results to control how many results are returned (1–20, default 5):

tools:
  builtins:
    - name: web_search
      search_provider: keenable
      # api_key is optional — omit it to use the keyless free tier:
      # api_key: ${KEENABLE_API_KEY}
      # max_results: 5            # 1-20 (default 5)

Hindsight long-term memory

Three built-in tools give an agent memory that survives across runs and sessions, backed by Hindsight, an open-source agent-memory system. Unlike conversation history — which is lost between sessions — anything an agent retains stays available in every future run.

ToolWhat it does
hindsight_retainPersist a durable fact, preference, or decision to memory. Takes a content string.
hindsight_recallSearch memory for relevant facts before answering. Takes a query string.
hindsight_reflectSynthesize a reasoned summary from memory, rather than returning raw facts. Takes a query string.

The Hindsight client SDK is an optional dependency. Install the memory extra and provide an API key:

pip install 'omnigent[memory]'
export HINDSIGHT_API_KEY=hsk_...    # https://ui.hindsight.vectorize.io

Enable the tools by name under tools.builtins:

tools:
  builtins:
    - name: hindsight_recall
      api_key: ${HINDSIGHT_API_KEY}
    - name: hindsight_retain
      api_key: ${HINDSIGHT_API_KEY}
    - name: hindsight_reflect
      api_key: ${HINDSIGHT_API_KEY}

Config keys

api_key is required; every other key is optional:

KeyPurpose
api_keyHindsight API key (typically ${HINDSIGHT_API_KEY}).
api_urlAPI base URL. Defaults to https://api.hindsight.vectorize.io.
bank_idMemory bank to read/write. Defaults to the agent id, then the conversation id.
budgetRecall/reflect budget level — low, mid (default), or high.
max_tokensMax tokens for recall results (default 4096).
tagsComma-separated tags applied on hindsight_retain.
recall_tagsComma-separated tags to filter hindsight_recall.
recall_tags_matchHow recall_tags are matched — any (default), all, any_strict, or all_strict.

Memory is scoped by the resolved bank. With no bank_id, the bank defaults to the agent id, so each agent gets an isolated memory bank out of the box. Pin a fixed bank_id to share one human-readable bank across runs (or several agents):

tools:
  builtins:
    - name: hindsight_retain
      api_key: ${HINDSIGHT_API_KEY}
      bank_id: remy          # stable, easy to inspect in Hindsight

Because these tools only persist and recall when the model actually calls them, prompt the agent to recall before answering and to retain durable facts as it learns them — see the remy example agent for a worked prompt.

Nimble web research and extraction

Two builtins reach the live web through Nimble. nimble_research hands a research task to a Nimble Web Search Agent and returns a cited answer with a confidence signal for each claim. Use nimble_extract when you have a Nimble extract template to run against a page; it returns the parsed result as structured JSON.

nimble_research needs the optional nimble extra:

pip install 'omnigent[nimble]'

Enable them in your agent's config.yaml, under tools.builtins:

tools:
  builtins:
    - name: nimble_research
      api_key: ${NIMBLE_API_KEY}
    - name: nimble_extract
      api_key: ${NIMBLE_API_KEY}
      template: my_template_name   # one of your account's extract templates

Nimble is also a web_search provider for quick lookups that don't need a research run. For the full config reference (polling, agent instances, extract templates, and where to get an API key), see Nimble's Omnigent connector docs.

Python function tools

Expose any Python callable as a tool. The function is referenced by its fully qualified import path:

tools:
  summarize_file:
    type: function
    description: Summarize a local text file.
    callable: my_package.tools.summarize_file
    parameters:
      type: object
      properties:
        path:
          type: string
      required: [path]

The JSON Schema under parameters is optional. If you omit it, Omnigent auto-generates the schema from the function's type annotations and signature.

Python function tools run in the server process, so they only work for agents the server operator registers. Agent bundles uploaded over HTTP cannot use them — see Uploaded agents.

Uploaded agents

Agent bundles uploaded over HTTP — to create a session, replace a session's agent (PUT /v1/sessions/{id}/agent), or install an agent — are validated before any of their code is imported. An uploaded bundle cannot declare:

These checks also apply to terminals and nested agents in the bundle. They run on multi-user servers and, starting in 0.19.0, on local single-user servers too, including bundles that omnigent run uploads. Loopback requests can come from agents as well as the operator, so a local server doesn't treat them as trusted.

An invalid upload is rejected with HTTP 400. Existing uploaded agents that use these features also fail validation when you add, update, or delete their MCP server settings. A rejected edit leaves the stored bundle unchanged. The agent configuration read and patch endpoints apply the same validation to older bundles.

To migrate an existing uploaded agent:

  1. Expose its custom tools through an MCP server and replace the source-file or callable tool entries with type: mcp entries. Update nested agents too.
  2. Register custom policy handlers on the server, and change working directories to relative paths inside the workspace.
  3. Replace the session's bundle through PUT /v1/sessions/{id}/agent, or upload the corrected bundle and start a new session. Installing a new agent version on its own does not change existing sessions.
  4. Make later MCP configuration changes on the migrated agent. Removing an MCP server from an old agent does not get it past validation.

For trusted in-process tools, register the agent as the operator instead of uploading it:

omnigent server --agent ./my-agent           # operator-registered agent
omnigent run ./my-agent --no-session         # dedicated local server, trusted startup registration

omnigent run ./my-agent --no-session starts a dedicated local server that registers the agent at startup and creates its session from that registration, so nothing is uploaded over HTTP. Changing a tool's declared runtime alone is not a migration: client tools need a client-provided implementation.

Sub-agent tools

Declare agents as tools so a supervisor agent can delegate work to them. You can define a sub-agent inline, or keep it in its own directory and reference it by name.

Inline definition

Define the sub-agent's full spec directly in the tools block:

tools:
  reviewer:
    type: agent
    description: Review proposed code changes.
    prompt: |
      You are a careful code reviewer. Focus on correctness,
      tests, security, and maintainability.
    executor:
      harness: claude-sdk
      model: claude-sonnet-4-6
    os_env: inherit
    pass_history: true
    max_sessions: 2

External directory

For a sub-agent that is complex, shared across parents, or maintained independently, give it its own directory under the parent's agents/ folder and list it by name under tools.agents. Omnigent discovers every agents/<name>/config.yaml at load time:

# Parent config.yaml
tools:
  agents:
    - reviewer

# agents/reviewer/config.yaml — a standard agent config
spec_version: 1
name: reviewer
description: Review proposed code changes.
prompt: |
  You are a careful code reviewer. Focus on correctness,
  tests, security, and maintainability.
executor:
  type: omnigent
  config:
    harness: claude-sdk
  model: claude-sonnet-4-6

Entries under tools.agents are just names (strings) matching a subdirectory of agents/. Each referenced file is a full agent config that can define its own tools, skills, harness, and policies.

A sub-agent (inline or external) can have its own harness, model, tools, and policies. On an inline sub-agent the pass_history flag controls whether the parent's conversation history is forwarded, and max_sessions limits concurrent invocations.

Tool inheritance

Use inherit to pass one of the parent's tools down to a sub-agent:

tools:
  researcher:
    type: agent
    prompt: Research and summarize.
    tools:
      word_count: inherit    # gets word_count from parent

The sub-agent receives the same tool definition the parent has, with no duplication.

Use spec: self for a sub-agent that clones the entire parent spec. It gets the same tools, prompt, and configuration as the parent agent.

Hindsight integration

Omnigent ships Hindsight integration that gives an agent long-term memory. Three tools are available:

These tools ship in an optional extra. Install it and set your Hindsight API key before declaring them:

pip install 'omnigent[hindsight]'
export HINDSIGHT_API_KEY=hsk_...        # https://ui.hindsight.vectorize.io

Declare them by their reserved names under builtins, passing the API key and an optional bank_id (omit bank_id and the memory bank defaults to the agent id):

tools:
  builtins:
    - name: hindsight_recall
      api_key: ${HINDSIGHT_API_KEY}
      bank_id: my-agent
    - name: hindsight_retain
      api_key: ${HINDSIGHT_API_KEY}
      bank_id: my-agent
    - name: hindsight_reflect
      api_key: ${HINDSIGHT_API_KEY}
      bank_id: my-agent

Combine tool types

A single agent can mix all tool types. The tools block is a flat map of names to definitions:

tools:
  github:
    type: mcp
    command: uv
    args: [run, python, -m, my_package.github_mcp]

  summarize_file:
    type: function
    callable: my_package.tools.summarize_file

  reviewer:
    type: agent
    config: agents/reviewer.yaml