---
title: Bring an existing agent
description: Move a Claude Code or similar agent project into a Hub file by file, or keep your assistant and connect it to a Hub through MCP.
canonical_url: https://hubzoid.com/docs/guides/existing-agents
last_updated: 2026-09-27
---

# Bring an existing agent

Move a Claude Code or similar agent project into a Hub file by file, or keep your assistant and connect it to a Hub through MCP.

You may already have an agent that works for you: a Claude Code project with a `CLAUDE.md`, a few skills, an MCP server and some scripts. There are two ways to take it to your team with Hubzoid, and they combine well.

| Route | What happens | Choose it when |
| --- | --- | --- |
| **Move it into a Hub** | The instructions, skills, sub-agents, connectors and scripts become Hub files. The agent then runs in the web chat, Slack and other channels, on schedules and in workflows, for everyone you grant access. | Teammates who do not use your assistant should get the result, or the work should run unattended. |
| **Keep your assistant, connect it** | The Hub serves its tools, knowledge and skills over MCP. You and others keep using Claude Code, Cursor or another MCP client, with your own model. | People already work in an assistant and want shared context and tools inside it. |

The move is manual and quick for a typical project. Hubzoid has no converter, because most of the work is deciding what the shared agent should know and do.

## How the pieces map

| In a Claude Code project | In a Hub | Notes |
| --- | --- | --- |
| `CLAUDE.md` or `.claude/CLAUDE.md` (or `AGENTS.md`) | `AGENTS.md` | The body is the system prompt. Keep the parts about the work, drop the parts about the coding environment. |
| `@path` imports in `CLAUDE.md` | Inline text, or `knowledge/*.md` | Hubzoid does not expand imports. Reference material fits best in `knowledge/`. |
| `.claude/skills/<name>/SKILL.md` | `skills/<name>/SKILL.md` | Same file. `name` and `description` are read, other keys are ignored. |
| `.claude/commands/<name>.md` | `skills/<name>.md` or `schedule/<name>.md` | A reusable prompt becomes a skill. A prompt you run on a timer becomes a markdown task. |
| `.claude/agents/<name>.md` | `agents/<name>.md` | Rewrite `tools:` as a YAML list of Hubzoid tool names, and `model:` as a Hubzoid model id. |
| `.mcp.json` | `connectors/.mcp.json` | Same `mcpServers` map. HTTP servers need `transport` instead of `type`. |
| Scripts the agent runs | `tools_local/*.py` | A function decorated with `@function_tool`. A script that should run on a timer without the agent can be a `run:` task. |
| Data files the agent reads | `knowledge/` or `raw_data/` | Short curated documents go in `knowledge/`. Large source material to search goes in `raw_data/`. |
| Secrets in your shell | `<hub>/.env` | Secrets for restricted tools go in `restricted/.env`. |
| Permission settings in `.claude/settings.json` | `restricted/` tools and grants | Who may use a tool is decided in code and the Console, not by the model. |

## A worked example

An operations lead has a Claude Code project that prepares a daily report for a home goods retailer with four stores: open supplier orders, stock alerts and anything that needs escalating.

```text title="Before: ops-briefing (Claude Code)"
ops-briefing/
├── CLAUDE.md
├── .mcp.json
├── .claude/
│   ├── skills/daily-reports/SKILL.md
│   ├── skills/daily-reports/template.md
│   ├── agents/supplier-research.md
│   └── commands/weekly-review.md
├── scripts/open_orders.py
├── data/orders.csv
└── docs/escalation-policy.md
```

After the move, the same project is a Hub:

```text
ops-briefing/
  AGENTS.md
  .env
  skills/
    daily-reports/
      SKILL.md
      template.md
    weekly-review.md
  agents/
    supplier-research.md
  knowledge/
    escalation-policy.md
  tools_local/
    orders.py
  raw_data/
    orders.csv
  connectors/
    .mcp.json
  schedule/
    daily-reports.md
  evals/
    briefing-uses-orders.md
```

1. **Create the Hub**

   ```bash
   hubzoid init ops-briefing
   ```

   Run it in a new folder, outside your existing project. It writes a runnable Hub with one example of each file type and a `.env` with a random bridge key. Delete the examples you will not use, then copy your files in as below. See [quickstart](https://hubzoid.com/docs/getting-started/quickstart) for installing Hubzoid and choosing a model.

2. **Turn CLAUDE.md into AGENTS.md**

   Copy the parts of `CLAUDE.md` that describe the work: the goal, the rules, the tone, when to use what. Leave out build commands and coding conventions that only mattered to you in an editor. Add frontmatter for the name the team will see and a few starter prompts.

   ```markdown title="AGENTS.md"
   ---
   name: ops-briefing
   description: Daily Reports and supplier follow-up for the operations lead.
   suggestions:
     - Prepare today's daily report
     - Which supplier orders are late?
   ---

   You prepare the operations lead's daily report for a home goods retailer
   with four stores (north, south, east, west).

   - Use the daily-reports skill for the daily briefing.
   - Get open orders from the open_orders tool. Never estimate a quantity.
   - Escalate according to the escalation-policy knowledge document.
   - For questions about a supplier's record, use the supplier-research agent.
   ```

   Replace `@docs/escalation-policy.md` style imports with a sentence that names the knowledge document, and move the document to `knowledge/escalation-policy.md`. The agent sees a menu of knowledge documents and reads one with `read_knowledge` when it needs it.

3. **Move skills and commands**

   Copy `.claude/skills/daily-reports/` to `skills/daily-reports/`. The `SKILL.md` frontmatter works unchanged. Supporting files are not loaded with the skill, so point to them by their path from the Hub root:

   ```markdown title="skills/daily-reports/SKILL.md"
   ---
   name: daily-reports
   description: Build the daily report for the operations lead.
   ---

   1. Read the layout in skills/daily-reports/template.md with read_file.
   2. Call open_orders and list orders due today or overdue, by store.
   3. Apply the escalation policy and put anything that needs a decision first.
   ```

   A command such as `.claude/commands/weekly-review.md` becomes `skills/weekly-review.md` with `name` and `description` frontmatter. Hubzoid does not substitute `$ARGUMENTS`, so write the command as instructions that use whatever the person asked.

4. **Move sub-agents**

   Copy `.claude/agents/supplier-research.md` to `agents/supplier-research.md` and adjust two keys:

   ```markdown title="agents/supplier-research.md"
   ---
   name: supplier-research
   description: When the user asks about a supplier's delivery record or recent news.
   model: claude-local/opus
   tools: [web_search, http_get, read_knowledge]
   ---

   Research the supplier with web_search and http_get and reply with a short,
   sourced summary of delivery issues and news from the last 90 days.
   ```

   - `tools:` must be a YAML list of Hubzoid tool names. A comma-separated string such as `Read, Grep` stops the Hub from building, and Claude Code tool names do not exist in Hubzoid.
   - `model:` must be a Hubzoid model id, or be removed. Claude Code aliases such as `sonnet`, `opus` or `inherit` are not Hubzoid ids. A sub-agent whose model differs from the Hub's on the same engine runs on its own model as a delegate. Otherwise it is loaded into the main agent as a skill, and its `tools:` list is ignored.

5. **Move MCP servers**

   Move `.mcp.json` to `connectors/.mcp.json`. Local (stdio) servers work as they are. For an HTTP server, replace `"type": "http"` with `"transport": "streamable-http"`, because a server with a `url` and no `transport` is treated as SSE. Hubzoid expands `${NAME}` but not `${NAME:-default}`, so set every variable in the Hub's `.env`.

   ```json title="Before: .mcp.json"
   {
     "mcpServers": {
       "inventory": {
         "type": "http",
         "url": "${INVENTORY_MCP_URL:-https://mcp.example.com/mcp}",
         "headers": { "Authorization": "Bearer ${INVENTORY_TOKEN}" }
       }
     }
   }
   ```

   ```json title="After: connectors/.mcp.json"
   {
     "mcpServers": {
       "inventory": {
         "transport": "streamable-http",
         "url": "${INVENTORY_MCP_URL}",
         "headers": { "Authorization": "Bearer ${INVENTORY_TOKEN}" }
       }
     }
   }
   ```

   In a Hub, everyone who uses the agent shares the connector's credential. If each person should act with their own account, see [per-user MCP servers](https://hubzoid.com/docs/guides/tools-and-connectors#per-user-mcp-servers).

6. **Turn scripts into tools**

   In Claude Code the agent ran `python scripts/open_orders.py` in a shell. A Hub agent has no shell, so move the logic into a tool:

   ```python title="tools_local/orders.py"
   """Open supplier orders, moved from scripts/open_orders.py."""
   from __future__ import annotations

   import csv
   import json
   from pathlib import Path

   from agents import function_tool

   ORDERS = Path(__file__).resolve().parent.parent / "raw_data" / "orders.csv"


   @function_tool
   def open_orders(supplier: str = "") -> str:
       """Open supplier orders with their store and due date.

       Args:
           supplier: Only this supplier. Leave empty for all suppliers.

       Returns:
           JSON list of open orders.
       """
       with ORDERS.open(newline="", encoding="utf-8") as f:
           rows = [r for r in csv.DictReader(f) if r["status"] == "open"]
       if supplier:
           rows = [r for r in rows if r["supplier"].lower() == supplier.lower()]
       return json.dumps(rows)
   ```

   Tool files are loaded one by one rather than as a package, so a tool cannot import a sibling file from `tools_local/`. Keep each tool file self-contained, or install shared code as a package. See [tools and connectors](https://hubzoid.com/docs/guides/tools-and-connectors).

7. **Schedule the briefing**

   What you started by hand each morning can now run on its own. Scheduled tasks are Markdown files:

   ```markdown title="schedule/daily-reports.md"
   ---
   schedule: "30 7 * * 1-6"
   write: ["briefings/"]
   ---

   Prepare today's daily report with the daily-reports skill and save it
   to briefings/today.md.
   ```

   The task runs at 07:30 server time from Monday to Saturday with the same agent, skills and tools as chat. See [markdown tasks](https://hubzoid.com/docs/guides/markdown-tasks).

8. **Check it**

   Add an eval that proves the briefing uses real order data, then run the checks:

   ```markdown title="evals/briefing-uses-orders.md"
   ---
   expect_tools: [open_orders]
   ---
   ## Prompt
   Prepare today's daily report.

   ## Criteria
   Lists overdue orders by store from the tool result. Does not invent quantities.
   ```

   ```bash
   hubzoid doctor ./ops-briefing
   hubzoid test ./ops-briefing --prompt "Which supplier orders are late?"
   hubzoid eval run ./ops-briefing
   hubzoid run ./ops-briefing
   ```

## What changes when an agent moves

- **No coding tools.** On the `claude-local` backend, Claude Code's own tools (shell, file editing, its search and web fetch) are switched off. The agent has Hubzoid's [built-in tools](https://hubzoid.com/docs/reference/built-in-tools), such as `read_file`, `list_files`, `grep_data`, `http_get` and `write_artifact`, plus your own. Instructions that say "run this command" must name a tool instead.
- **Only Hub files count.** Hubzoid reads `AGENTS.md`, not `CLAUDE.md` or anything under `.claude/`. Imports, hooks, permission settings and auto memory do not carry over.
- **Many people, one agent.** In chat, each person has their own conversations and their own identity. Tools and connectors share the Hub's credentials unless you use restricted tools or per-user connections. Decide who may use what in the Console. See [identity and access](https://hubzoid.com/docs/concepts/identity-and-access).
- **Checks that must always run belong in code.** A rule the model is only asked to follow can be missed. Put anything that must hold every time in a tool, a [restricted tool](https://hubzoid.com/docs/guides/restrict-tools) or a [code workflow](https://hubzoid.com/docs/guides/code-workflows) step.
- **Memory is explicit.** Conversation history stays with each chat. Shared knowledge changes when you edit `knowledge/`, or when a person with the `curator` permission asks the agent to remember something. See [memory and history](https://hubzoid.com/docs/concepts/memory-and-history).

## Keep your assistant and connect it

If you and your teammates prefer to stay in Claude Code or Cursor, turn the Hub into an MCP server instead of, or as well as, moving the agent.

```bash title=".env"
MCP_SERVER=true
```

Each person creates a personal API key in the web chat and adds the Hub to their assistant:

```bash
claude mcp add --transport http ops-briefing https://hub.example.com/mcp \
  --header "Authorization: Bearer <your-api-key>"
```

The assistant then receives the Hub's tools (including `list_skills`, `load_skill`, `list_knowledge` and `read_knowledge`) and, when it connects, the Hub's instructions from `AGENTS.md` or its `mcp_instructions` frontmatter. Restricted tools follow the same permissions as chat, and every restricted call is audited. The MCP server leaves out the chat-only tools, delegates and the Hub's own connectors, because the assistant brings its own model and environment. The full setup is in [connect an assistant](https://hubzoid.com/docs/guides/connect-an-assistant).

A common pattern uses both: builders keep working in their assistant against the Hub, and everyone else uses the same Hub in chat and on schedules.

## Next steps

- [Hub files](https://hubzoid.com/docs/reference/hub-files): Every file and frontmatter key a Hub reads.
- [Tools and connectors](https://hubzoid.com/docs/guides/tools-and-connectors): Python tools, MCP servers and per-user connections.
- [Connect an assistant](https://hubzoid.com/docs/guides/connect-an-assistant): Serve the Hub to Claude Code, Cursor and other MCP clients.
- [Evals](https://hubzoid.com/docs/guides/evals): Prove the moved agent still does its job.
