Documentation/omnitron/MCP + Knowledge base
In this section

MCP + knowledge base

Omnitron ships a Model Context Protocol server that exposes two surfaces to AI agents (Claude, IDE assistants, CI bots, code-review agents):

  1. Knowledge base — semantic + full-text search across the codebase, plus structured access to API surfaces, modules, patterns, and gotchas.

  2. Management plane — apps, infra, monitoring, secrets, backups, deploys and pipelines through the implemented MCP tool catalog. CLI-only operations remain CLI-only.

Verified against apps/omnitron/src/mcp/ and apps/omnitron/src/commands/kb.ts.

The current stdio management server connects through the daemon owner’s administrative Unix socket. It is suitable only for a trusted local agent host. Filtering visible tools in that host is not server-side delegation. See Agents and delegated operations before embedding an agent in a multi-user Console.

Starting the server

omnitron kb mcp

That's it. The server runs on stdio (the MCP wire format) and keeps running until the client closes the stream. Agent host configuration typically wires it as:

{
  "mcpServers": {
    "omnitron": {
      "command": "omnitron",
      "args":    ["kb", "mcp"]
    }
  }
}

The exact config varies by host (Claude Desktop, IDE plugins, custom agents).

What the agent sees

Two surfaces, registered conditionally on what's available:

Tool groupRequiresWhen unavailable
kb.*KB indexed (omnitron kb index)"Run omnitron kb index first"
apps.*Daemon running"Run omnitron up to start the daemon"
infra.*Daemon running(same)
monitoring.* / health.* / metrics.* / logs.* / alerts.*Daemon running(same)
stack.* / secret.* / backup.* / deploy.* / cluster.* / fleet.* / k8s.* / project.* / pipeline.*Daemon running(same)

When a dependency is unavailable, the corresponding tool names remain visible as UNAVAILABLE stubs. Calling one returns an error explaining how to start the daemon or index the KB. Missing data is not presented as a successful empty result.

KB tools

ToolPurpose
kb.querySemantic + full-text hybrid search over code knowledge. Open-ended questions.
kb.get_apiAPI surface of a class / interface / type — signatures, decorators, members, inheritance
kb.get_moduleModule info: overview, specs, dependencies, dependents, gotchas
kb.repo_mapCompressed architecture map (2-5K tokens). Start here for orientation.
kb.get_patternOne named development pattern with code
kb.list_patternsAll available patterns
kb.get_gotchasKnown pitfalls and critical warnings (essential before modifying unfamiliar code)
kb.search_symbolsSearch for classes / interfaces / types by name or kind
kb.dependenciesDependency graph for a module — depends-on + dependents
kb.indexTrigger an (incremental or full) reindex from the agent
kb.statusIndex health, entry counts, last-indexed timestamp

Agents typically lead with kb.repo_map (orient), then kb.query (find), then kb.get_api (verify signature) before making changes.

Management tools — apps

ToolEffect
apps.listInventory of managed apps
apps.startStart an app by name
apps.stopStop an app (graceful + optional force)
apps.restartStop + start
apps.statusDaemon-wide overview
apps.logsTail logs (lines + level + grep)
apps.scaleResize the explicit process pool in name to count instances until restart
apps.inspectDeep diagnostics for an app

apps.scale requires all three fields: name, process, and a positive integer count. It changes only an existing declared pool; classic applications and singletons refuse. The returned ProcessInfoDto.processes contains the selected pool's observed size. Configuration remains unchanged, restart restores its initial size, and automatic scaling can subsequently adjust it. The current owner must support processPoolResize@1; a backend-only update does not upgrade that owner. If an RPC outcome is unknown, inspect the process before retrying.

Management tools — infra

ToolEffect
infra.statusFull infrastructure state: containers, images, ports, health
infra.containersManaged container inventory
infra.connectionResolved host / port / credentials for a logical service
infra.start / infra.stopStart or stop one managed container
infra.logsTail one container's logs
infra.log_statsLog ingestion counters (stored, dropped, buffered)

There is no infra.psql or infra.redis. Both were listed here and both called RPCs that do not exist; there is no service that executes an arbitrary SQL statement or Redis command, and adding one reachable by whoever the agent talks to is a decision for an operator rather than a gap to fill. Use omnitron infra psql on the host, where the blast radius is the person typing it.

Provisioning (infra.up / infra.down) is likewise CLI-only: it starts and stops containers for a whole stack, which is not something to hand an agent by default.

Management tools — monitoring

ToolEffect
monitoring.snapshotBounded metrics, alert summary and ingestion-loss evidence; partial sources are explicit
metrics.seriesExplicit apps/metric names and a bounded historical window
alerts.activeRead up to 100 firing alerts without acknowledging them
health.checkActive probes for one app, or the whole platform when app is omitted
metrics.getAggregate metric snapshot
metrics.appPer-app metrics
logs.queryStored logs. Full-text filter is search; page with limit / offset
logs.tailThe most recent entries, oldest-first — poll for near-real-time
logs.statsExact stored record counts; may scan a large archive, so avoid frequent polling

Management tools — control plane

ToolEffect
stack.list / stack.status / stack.start / stack.stopStack lifecycle
project.list / project.scan / project.appsProject registry
secret.list / secret.get / secret.setSecret management
backup.create / backup.list / backup.restore / backup.schedulesDatabase backup
deploy.historyRetained legacy app-operation records; deploy through stack.start with an explicit release
fleet.status / fleet.summaryFleet nodes and counts
k8s.pods / k8s.scaleKubernetes pods + scaling
pipeline.list / pipeline.run / pipeline.statusAdministrator Xec automation; run requires expectedRevision from the reviewed definition

Not offered, and deliberately: stack.create (stack creation is omnitron stack create, and getting it wrong strands infrastructure), deploy.build, cluster.status, fleet.health, and the two webapp.* tools — the console is managed by a CLI command that runs Docker locally, with no service behind it.

Use the registered tools/list response as the live catalog. It depends on the daemon and KB services available to this process. The typed handlers call existing RPC methods rather than assuming every CLI command has a service endpoint.

See bounded monitoring evidence and Xec automation for limits, authority and cancellation behavior.

KB index lifecycle

omnitron kb index              # incremental reindex (default)
omnitron kb index --full       # full reindex (ignore manifest cache)
omnitron kb status             # index health, entry counts, last-indexed timestamp
omnitron kb query "<question>" # one-shot query (test the index)

The index lives at ~/.omnitron/kb.db (SurrealKV). Schema:

  • Symbols — classes, interfaces, types, functions, enums

  • Modules — packages with overview, dependencies, gotchas

  • Patterns — canonical development recipes

  • Gotchas — known pitfalls per module

  • Docs — long-form markdown indexed alongside symbols

Hybrid search combines:

  • Full-text BM25 on names + docs

  • Semantic embeddings (when available) for "open-ended question" flavour

Both indexes update during omnitron kb index.

Indexing strategy for a monorepo

Reindexing is incremental by default (manifest-cached), so a plain omnitron kb index after a batch of edits is cheap — wire it into a pre-commit hook or run it manually when you've changed public surfaces. For CI / production reads:

omnitron kb index --full       # fresh, in case manifests drifted
omnitron kb status             # verify entry counts look right

The full reindex is idempotent and bounded — typically minutes even on large codebases.

OMNITRON_ROOT env var picks the indexed root (default cwd). Useful when running the MCP server from outside the project directory.

Tool authoring (extend MCP)

Tools live under apps/omnitron/src/mcp/tool-groups/. Each group exports a factory:

// apps/omnitron/src/mcp/tool-groups/my-tools.ts
import type { IMcpToolDef } from '../types.js';

export function createMyTools(daemonClient: any): IMcpToolDef[] {
  return [{
    name: 'mything.do',
    description: 'Do the thing. Use when X.',
    inputSchema: {
      type: 'object',
      properties: {
        target: { type: 'string', description: 'What to target' },
      },
      required: ['target'],
    },
    // Return a raw value — the bridge wraps it into the
    // MCP { content: [{ type: 'text', text }] } envelope for you.
    handler: async ({ target }) => {
      return daemonClient.someService.someMethod({ target });
    },
  }];
}

Register in the kb mcp command (apps/omnitron/src/commands/kb.ts):

bridge.registerTools(createMyTools(daemonClient));

The tool definition interface is IMcpToolDef (in apps/omnitron/src/mcp/types.ts); the existing group factories (createKbTools, createAppsTools, …) all take the relevant client/service as a loosely-typed any. Handlers return a raw object or string — McpBridge JSON.stringifys it and wraps it in the { content: [...] } envelope; don't build that envelope yourself or you'll double-encode.

The description field is what the agent reads to decide whether to call the tool. Make it specific.

Best practices for agent-callable tools

  • Atomic operations. One tool, one outcome — don't bundle "deploy + scale + restart" into one tool.

  • Idempotent where possible. Agents retry on transient failures; non-idempotent tools cause double-spend bugs.

  • Strict input schemas. JSON schema with required and enum constraints — narrows the agent's failure modes.

  • Descriptive errors. When a tool fails, return a clear message so the agent can recover (e.g., "App not found. Available: api, worker, scheduler.").

  • Read-then-write pattern. Expose a list / status for every do — agents check before acting.

  • Cap dangerous side-effects. Tools that destroy data (infra.down --volumes, backup.restore) should require explicit confirmation flags.

Auth model

The MCP server inherits the local Unix-socket trust. The kb mcp command takes no connection flags — it always builds a local daemon client (createDaemonClient()) that talks to ~/.omnitron/daemon.sock. If the agent process can reach that socket, it runs as admin (same model as the CLI). A different process running as a different OS user → different daemon → different scope.

There is no remote/TCP MCP transport today. kb mcp has no --daemon-url or --token option; the server cannot point at a remote daemon. To drive a remote host, run the MCP server on that host (over an SSH session or inside its container) so it reaches the local socket there, and scope the agent's OS-level access accordingly.

Match agent power to its expected scope. Because local-socket access is effectively admin, the strongest control is where you run the MCP server and which host's daemon it can reach.

Common agent workflows

"What does X do?"

  1. kb.repo_map → orient

  2. kb.query "X" → find relevant entries

  3. kb.get_api "X" or kb.get_module "X" → details

  4. Agent answers from results

"Is the platform healthy?"

  1. apps.status → daemon overview

  2. health.check → composite health

  3. metrics.get → CPU/memory aggregate

  4. apps.logs → recent error filter

  5. Agent summarises

"Fix this failing deploy"

  1. deploy.status <runId> → what failed

  2. apps.logs <appName> --level error --grep deploy → context

  3. kb.get_gotchas <appName> → known issues

  4. apps.inspect <appName> → live state

  5. Agent proposes fix; operator confirms

"Scaffold a new app"

  1. kb.get_pattern "new-app-bootstrap" → canonical scaffold

  2. kb.get_module "<related-app>" → similar example

  3. Agent generates files; operator reviews

Cost and latency

  • Tool calls to the daemon are essentially free (Unix socket RPC).

  • KB queries with semantic search load embedding models — cold start adds 1-2s; subsequent queries are sub-second.

  • The MCP server itself is lightweight (~50-100 MB resident).

Run it as a long-lived companion to your agent session; restarting on every prompt adds noticeable latency.

Anti-patterns

  • Running the MCP server next to a production daemon socket without thinking. Local-socket access is admin — keep the server on dev/staging hosts, or gate destructive tools behind operator confirmation, since there is no per-token role scoping for the MCP surface today.

  • Skipping kb index in CI before MCP-based code review. Stale KB makes agents confidently wrong.

  • Tools that perform multiple actions atomically. The agent can't retry partial successes; the daemon ends up with half-applied state.

  • Tools that mutate without listing first. Agents work better when they can see current state before acting.

  • Generic "execute SQL" / "run command" tools. Wide blast radius, hard to audit, hard for the agent to use correctly. Narrow domain-specific tools win.

See also