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:
env: environment variables passed to stdio server processes (e.g.,API_KEY: ${MY_API_KEY})headers: HTTP headers for remote servers, with${...}env var expansion (e.g.,Authorization: "Bearer ${API_TOKEN}")auth:withtype: databricks: resolves an OAuth token from a profile in your~/.databrickscfg.databricksis the only supportedauthtype; inside it,profileis required. Other servers don't useauth:— they authenticate viaenvorheadersabove:
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:
- OpenAI models — passes through to OpenAI's native
web_search_preview(server-side, using the LLM API key). Nosearch_providerneeded. - Other models (Anthropic, Llama, Databricks-hosted, etc.) — set
search_providerto name the engine explicitly. There is no default and no env var fallback, so the engine that runs is always explicit; with nosearch_providerset, the tool returns an error naming the options.
Supported backends:
search_provider | API key | Notes |
|---|---|---|
duckduckgo | Keyless | No api_key required |
keenable | Optional | Keyless by default; supply api_key to lift rate limits |
google | Required | Also requires engine_id |
perplexity | Required | |
nimble | Required | |
tavily | Required |
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.
| Tool | What it does |
|---|---|
hindsight_retain | Persist a durable fact, preference, or decision to memory. Takes a content string. |
hindsight_recall | Search memory for relevant facts before answering. Takes a query string. |
hindsight_reflect | Synthesize 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:
| Key | Purpose |
|---|---|
api_key | Hindsight API key (typically ${HINDSIGHT_API_KEY}). |
api_url | API base URL. Defaults to https://api.hindsight.vectorize.io. |
bank_id | Memory bank to read/write. Defaults to the agent id, then the conversation id. |
budget | Recall/reflect budget level — low, mid (default), or high. |
max_tokens | Max tokens for recall results (default 4096). |
tags | Comma-separated tags applied on hindsight_retain. |
recall_tags | Comma-separated tags to filter hindsight_recall. |
recall_tags_match | How 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:
- Server-side Python or TypeScript source-file tools (for example, files under
tools/python/). - Server-side callable tools (
type: functionwith acallable). type: functionpolicies whosehandleris not a registered policy handler.- Absolute working directories, or working directories that escape the workspace.
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:
- Expose its custom tools through an MCP server and replace the
source-file or callable tool entries with
type: mcpentries. Update nested agents too. - Register custom policy handlers on the server, and change working directories to relative paths inside the workspace.
- 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. - 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:
hindsight_retain— persist a durable fact across runs.hindsight_recall— retrieve relevant memories before answering.hindsight_reflect— reason over everything stored in the bank.
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