Hubzoid
Concepts

The Hub

The Hub is the shared foundation behind every Hubzoid agent. Learn what it holds, how context is assembled for each run, and how to scope one or many.

Context takes effort to build. The Hub is where that effort lives: the instructions, knowledge, skills, agent definitions and authorized tools needed to do one product's, team's or company's work. You write it once as a folder in Git, and every surface that uses the Hub (chat, scheduled work, and assistants connected over MCP) builds on the same files.

"Provide context once" does not mean everyone sees everything. Each surface has its own history and its own access rules, and restricted tools run only for the people and workflows granted them.

What a Hub holds

Read as one agent, a Hub is a definition with two sides: what the agent knows and what it can reach. Hubzoid supplies the surfaces and services around it.

What it knows

  • Knowledge

    knowledge/raw_data/

    Reference documents read on demand, and raw material searched as text.

  • Skills

    skills/

    Procedures loaded when a request matches their description.

Definition

AGENTS.mdagents/

Who the agent serves, its job and its rules, plus any sub-agents.

What it can reach

  • Tools

    tools_local/

    Your Python functions, beside the built-in tools.

  • Connections

    connectors/restricted/

    Live systems through MCP servers, and restricted tools that run only with a permission.

What Hubzoid provides

Surfaces
  • Web chat
  • Slack
  • WhatsApp
  • Telegram
  • OpenAI-compatible API
  • MCP
  • Webhooks
Services
  • Built-in tools
  • Workflow engine
  • Sign-in and grants
  • Activity log
  • The Console
  • Evals
The four parts of an agent around its definition, on the services every Hub gets.
PartFilesHow it reaches the agent
InstructionsAGENTS.mdThe body is the system prompt for every run.
Knowledgeknowledge/**/*.mdListed by name and description in the system prompt. Read in full with read_knowledge when relevant.
Skillsskills/*.md, skills/<name>/SKILL.mdListed in the system prompt. Loaded with load_skill when a request matches.
Agent definitionsagents/*.md, agents/<name>/AGENTS.mdLoaded as skills, or called as delegate agents on their own model.
ToolsBuilt-in tools, tools_local/*.py, connectors/.mcp.jsonOffered to the model as callable tools.
Restricted toolsrestricted/*.pyOffered only to callers with the matching permission. Checked again at call time.
Unstructured dataraw_data/Searched with grep_data and read with read_file.
Recurring workschedule/*.md, workflows/<name>/*.pyRun on the workflow engine with the same context.
People and permissionsidentity/Rosters for messaging surfaces and labels for permissions in the Console.
Quality checksevals/*.mdRun against the same agent with hubzoid eval run.

Project structure lists the exact file names and formats.

How context is assembled for a run

Chat uses the agent the bridge builds from the Hub folder when it starts. Scheduled tasks and hub.call_agent build it again for each run, so they pick up Hub edits without a restart.

  1. AGENTS.md body
  2. Runtime addendum
  3. Tool registry
  4. Access guard
  5. Model call
What the model receives, in order.
  1. Instructions. The AGENTS.md body is the start of the system prompt.
  2. Runtime addendum. Hubzoid appends a section with the Hub name, backend, model and date, the menu of knowledge documents and skills (name and description only), any delegate agents, guidance for searching raw_data/ when that folder exists, a reminder about restricted tools when restricted/ exists, and rules for reading uploaded files. Set auto_addendum: false in the AGENTS.md frontmatter to send the body alone.
  3. Tool registry. Built-in tools, then your tools_local/ tools (a local tool with a built-in's name replaces it), then restricted tools, which win any name conflict. MCP servers from connectors/.mcp.json are added beside them.
  4. Access guard. Each restricted tool is wrapped so that a caller without the permission is refused at call time, with the decision recorded. On every runtime the tool is also hidden from that caller.
  5. The turn itself. The conversation arrives as one prompt. With claude-local and codex-local, Hubzoid also adds a short note naming the signed-in person, so the model does not mistake the local CLI's login for the user.

Knowledge and skill bodies are not in the system prompt. The model sees the menus and loads what it needs, which keeps prompts small as a Hub grows. read_knowledge and list_knowledge read the folder from disk on every call, so an edited or newly learned document is available immediately. In chat, the menus in the system prompt refresh when the Hub restarts.

Instructions

AGENTS.md is written for the model: who it serves, what it is responsible for, how to use the Hub's knowledge and tools, and what to refuse. Keep facts that change in knowledge/ and procedures in skills/, and point to them by name from the instructions.

AGENTS.md
---
name: stock-desk
description: Answers stock questions for the operations team and flags drift between locations.
---

You help the operations team with stock across our four locations.

- For thresholds and definitions, read the drift-thresholds knowledge document.
- For the weekly review, load the weekly-drift-review skill and follow it.
- Answer with numbers and name the location. Say when data is older than a day.

Knowledge

A knowledge document is Markdown with optional name and description frontmatter. The description is what the model sees in the menu, so write it as a statement of when the document is useful. Subfolders are fine: every *.md under knowledge/ is loaded, and the name defaults to the file name.

Use knowledge/ for reference material the agent should read and quote. Use raw_data/ for large or unedited material, such as exports and code checkouts, that the agent should search with grep_data rather than read whole.

Skills

A skill is a named procedure with a name and a description. The model loads it with load_skill(name) when a request matches the description, then follows it. Skills come from three places, and a name defined in an earlier place wins:

  1. skills/ in the Hub.
  2. Sub-agents in agents/ that run as skills.
  3. Skills shipped with Hubzoid. The dashboard skill, which builds a single-file HTML dashboard and saves it with write_artifact, is available to every Hub's chat agent.

Tools

Every Hub has these built-in tools. tools_local/ adds your own Python tools, and connectors/.mcp.json adds MCP servers.

ToolsPurpose
read_file, list_filesRead and list files inside the Hub folder. Paths outside the Hub and under restricted/ are refused.
grep_dataSearch file contents, raw_data/ by default.
list_knowledge, read_knowledgeThe knowledge menu and documents.
list_skills, load_skillThe skill menu and skill bodies.
write_artifact, list_artifactsSave a file for the person in this chat and return a signed download link.
read_upload, read_upload_fullRead files attached in this chat.
render_jinjaRender a Jinja2 template.
http_get, web_searchFetch a URL (limited to HTTP_ALLOWLIST hosts when set) and search the web. HUBZOID_DISABLE_HTTP_GET and HUBZOID_DISABLE_WEB_SEARCH remove them.
current_timeThe current time in an IANA time zone.
rememberSave learned knowledge. Available only to callers with the Save shared knowledge (curator) capability. See memory and history.
call_jevExperimental typed decisions from TypeSafe's Jev. Available only to callers with the Call Jev (jev) capability, granted to nobody by default.

The built-in tools reference lists every argument. Tools and connectors shows how to write a local tool and add an MCP server.

Whatever their source, tools are written once and join one registry. Each runtime and the Hub's own MCP server offer that same registry in their own form.

Where tools come from

  • Built-in tools

    Files, knowledge, skills, search and the web.

  • Your tools

    tools_local/*.py

    A tool with the name of a built-in replaces it.

  • Restricted tools

    restricted/*.py

    Wrapped in the access guard. They win any name conflict.

One tool registry

Name, description, arguments and code, written once.

How each caller sees it

  • OpenAI Agents SDK

    Function tools on the agent.

  • Claude Agent SDK

    mcp__hubzoid__<name>

    One in-process MCP server.

  • Local Codex

    Dynamic tools that Hubzoid runs for Codex.

  • Connected assistants

    /mcp

    The same tools without the chat-only ones.

Beside the registry

connectors/.mcp.jsonHUBZOID_BROWSER

MCP servers and the shared browser, used by the Hub agent in chat, tasks, workflows and evals. They are not passed on to connected assistants.

Registry tools run inside the bridge process, where the access guard checks every restricted call.

The model only ever asks for a tool. Architecture follows one call through the bridge.

Restricted tools

Put a tool in restricted/ when only some people or workflows should run it. The file name is the permission: every tool in restricted/ledger.py needs the ledger permission. Hubzoid enforces this in code, outside the model:

  • Every call is checked when it runs, on all three runtimes, and refused unless the caller holds the permission on a surface allowed to reach restricted tools.
  • On every runtime and over MCP, the tool is also hidden from callers who lack the permission.
  • Every allow and deny decision is recorded before the call runs. A call whose decision cannot be recorded does not run.
  • Secrets for these tools go in restricted/.env. They are loaded into the process environment, and the agent's file tools cannot read the folder.

Grants are made in the Console or with hubzoid grant. See restrict tools and identity and access.

The same Hub on every surface

SurfaceWhat it uses from the Hub
Chat (web, Slack, WhatsApp, Telegram, API)The full agent: instructions, menus, all tools, delegates and the dashboard skill.
Markdown tasksThe same agent and model, plus tools that exist only for scheduled runs: run_git for Git checkouts inside the Hub, write_hub_file, which writes only under the paths the task declares, and publish_artifact and send_email when the task opts in.
Code workflowshub.call_agent runs the full agent. hub.call_llm is one model call with no tools and no Hub instructions.
MCP clientsThe built-in, local and restricted tools except those tied to a chat, including the knowledge and skill tools, plus the AGENTS.md body as server instructions. The client's own model does the reasoning.

Scoping a Hub

A Hub can serve one product, one team or a whole company. Scope it by the context and access that belong together:

  • One Hub per team or function when each team has its own knowledge, tools and people, for example finance and operations.
  • One Hub per product when several teams need the same product knowledge and tools.
  • One company Hub for shared questions such as policies and company figures, alongside team Hubs for sensitive work.

Each Hub is independent: its own .env and model, knowledge, tools, schedules and chat history. Its folder name is its access domain, so permissions granted in one Hub do not apply in another.

Many Hubs under a gateway

hubzoid gateway puts several Hubs behind one sign-in, one chat app and one Console:

hubzoid gateway ./finance ./operations ./company --data-dir ./gateway-data

Each Hub keeps its own instructions, tools, knowledge, schedules and model, and runs in its own bridge. People sign in once and see only the agents they are granted. Organization administrators manage every Hub from one Console, and an agent administrator (manage_access in one Hub) manages only that Hub. See gateway.

Next steps

Read this page as Markdown

Choose which cookies Hubzoid can use. You can change this at any time from Cookie settings in the footer. Read the Cookie Policy for details.