> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orchagent.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Publishing

> How to publish your agent or skill to orchagent

Publish your agent or skill to make it available on the platform.

## Prerequisites

1. orchagent account with API key
2. CLI installed and authenticated
3. For agents: `orchagent.json` manifest in your directory
4. For skills: `SKILL.md` file in your directory

## Quick Start

```bash theme={null}
# Navigate to your agent directory
cd my-agent

# Publish your agent
orch publish
```

## Publishing Skills

Skills use a different workflow from agents. Instead of `orchagent.json`, skills are defined as a single `SKILL.md` file with YAML frontmatter.

### Step 1: Create the Skill

Use `orch skill create` to scaffold a new skill:

```bash theme={null}
# Create a skill in the current directory
orch skill create my-coding-standards

# Or create manually — just make a SKILL.md file
```

This creates a `SKILL.md` file with the template structure.

### Step 2: Write Your SKILL.md

The `SKILL.md` file has two parts: YAML frontmatter (metadata) and markdown body (the skill content).

```markdown theme={null}
---
name: react-best-practices
description: React optimization patterns for code review
license: MIT
metadata:
  author: yourname
---

## React Best Practices

### Component Design
- Use functional components over class components
- Memoize expensive computations with useMemo
- Use useCallback for event handlers passed to child components

### Performance
- Avoid creating objects/arrays in render
- Use React.memo for components that render often with the same props
- Lazy-load routes and heavy components with React.lazy
```

**Frontmatter fields:**

| Field         | Required | Description                                                                 |
| ------------- | -------- | --------------------------------------------------------------------------- |
| `name`        | Yes      | Skill name (lowercase, hyphens allowed)                                     |
| `description` | Yes      | What this skill teaches — also used as the trigger description for AI tools |
| `license`     | No       | License identifier (e.g., `MIT`, `Apache-2.0`)                              |
| `metadata`    | No       | Arbitrary key-value pairs (author, version notes, etc.)                     |

The markdown body is the actual skill content — instructions, rules, examples, and guidelines that get injected into agent prompts at runtime.

### Step 3: Publish

```bash theme={null}
orch publish
```

The CLI auto-detects `SKILL.md` (no `orchagent.json` needed) and publishes as a skill.

### Skills vs Agents: Key Differences

|                     | Skills                                   | Agents                                         |
| ------------------- | ---------------------------------------- | ---------------------------------------------- |
| **Config file**     | `SKILL.md` (YAML frontmatter + markdown) | `orchagent.json` + `prompt.md` + `schema.json` |
| **What it is**      | Passive knowledge injected into prompts  | Active executor that runs code or calls LLMs   |
| **Create command**  | `orch skill create <name>`               | `orch init <name>`                             |
| **Install command** | `orch skill install org/name`            | `orch install org/name`                        |
| **Runnable**        | No — skills teach, agents do             | Yes — `orch run org/name`                      |

<Warning>
  **Do not mix formats.** If your directory has an `orchagent.json` with `type: "skill"`, the CLI will reject it. Skills must use the `SKILL.md` format. Use `orch skill create` to set up the correct structure.
</Warning>

<Tip>
  Skills are composable — agents can declare `default_skills` in their manifest to automatically include skill content in their prompts. See [Manifest Format — Skill Composition](/building-agents/manifest-format#skill-composition) for details.
</Tip>

***

## Publishing Agents

### Step 1: Initialize Your Agent

Create a new agent project:

```bash theme={null}
# Create an agent (default: direct LLM, on-demand)
orch init my-agent

# Create a JavaScript agent
orch init my-agent --language javascript

# Create an agent for always-on deployment
orch init my-agent --run-mode always_on

# Create a JavaScript Discord bot from template
orch init my-bot --template discord-js

# Create a skill
orch init my-skill --type skill

cd my-agent
```

This creates a directory with the basic structure: `orchagent.json`, `prompt.md`, and `schema.json`. For tool types with `--language javascript`, it creates `main.js` and `package.json` instead. The manifest uses the specified type (defaulting to `"prompt"`) with canonical fields.

<Tip>
  The execution engine is determined by your `type` field: `prompt` → `direct_llm`, `tool` → `code_runtime`, `agent` → `managed_loop`. Explicit `runtime.command` or `loop` declarations override the type default. See [Manifest Format](/building-agents/manifest-format#behavior-fields) for details.
</Tip>

### Step 2: Configure Your Manifest

Edit `orchagent.json` with your agent's configuration:

```json theme={null}
{
  "name": "my-agent",
  "type": "prompt",
  "description": "What my agent does",
  "supported_providers": ["openai", "anthropic"],
  "required_secrets": ["ANTHROPIC_API_KEY"]
}
```

The `required_secrets` field declares which env vars your code needs at runtime. These are matched by name against your workspace secrets vault. See [Manifest Format](/building-agents/manifest-format) for all options.

### Step 3: Test Locally

Before publishing, test your agent locally:

```bash theme={null}
# For direct LLM agents
orch run . --input '{"text": "test input"}'

# For code runtime agents (Python or JavaScript)
orch run .
```

The CLI automatically detects `.py` or `.js` entrypoints and runs them with the correct interpreter (`python3` or `node`).

### Step 4: Publish

```bash theme={null}
orch publish
```

### Step 5: Deploy as a Service (Optional)

For agents with `runtime.command` or `loop` config that need to run continuously (Discord bots, webhook listeners, background workers), deploy as an always-on service:

```bash theme={null}
# Secrets are auto-resolved from the agent's required_secrets
orch service deploy yourorg/my-agent --env LOG_LEVEL=info
```

The platform reads `required_secrets` from the agent and injects them from your workspace vault. See [Always-On Services](/using-agents/services) for full documentation.

## What Happens on Publish

The platform runs several checks:

1. **Manifest validation** — verifies `orchagent.json` is valid
2. **Schema validation** — validates input/output schemas
3. **Secrets declaration** — tool and agent types must declare `required_secrets` (use `--no-required-secrets` to bypass)
4. **Secrets validation** — warns if any `required_secrets` are not yet set in the target workspace
5. **Dependency check** — verifies all dependencies exist (for orchestrators)
6. **Cycle detection** — ensures no circular dependencies

For **managed loop** agents (with `loop` config), the platform also:

1. Stores your `prompt.md` as the agent's system prompt
2. Stores `custom_tools` and `loop.max_turns` from your manifest
3. On each call, spins up an E2B sandbox with an agent runner
4. The runner gives the LLM your prompt, built-in tools, and custom tools
5. The LLM iterates until it calls `submit_result` or hits `max_turns`

For **code runtime** agents (with `runtime.command`), the platform also:

1. Creates a ZIP bundle of your code
2. Stores the bundle securely
3. On each call, spins up an E2B sandbox
4. Runs your command with input via stdin
5. Returns stdout as the response

## Versioning

Versions are **automatically assigned** by the server each time you publish. The first publish creates `v1`, the next creates `v2`, and so on.

```
https://api.orchagent.io/yourorg/my-agent/v1/analyze
https://api.orchagent.io/yourorg/my-agent/v2/analyze
```

### How It Works

* **Every `orch publish` creates a new version** - v1, v2, v3, etc.
* **Authors cannot control version numbers** - this is intentional for simplicity
* **All versions remain accessible** - old versions stay available indefinitely

### Running a Specific Version

Use the `@version` syntax to pin to a specific version:

```bash theme={null}
# Run the latest version
orch run yourorg/my-agent

# Run a specific version
orch run yourorg/my-agent@v1
orch run yourorg/my-agent@v2
```

Callers should pin to specific versions for stability in production environments.

## Source Available vs Server Only

Agents have two distribution modes that control what non-owners can see and do:

| Mode                           | Prompt/code visible? | `orch run --local`           | Badge              |
| ------------------------------ | -------------------- | ---------------------------- | ------------------ |
| **Source Available** (default) | Yes                  | Yes                          | "Source Available" |
| **Server Only** (default)      | No — redacted        | No — cloud only (`orch run`) | "Server Only"      |

**Server-only agents** (the default) redact the prompt, manifest, and skill files from public API responses. This protects your intellectual property while still letting users run the agent via `orch run` (cloud execution).

**Source-available agents** expose the full prompt and code. Users can inspect, run locally, and [fork](/using-agents/cli-commands#fork) into their own workspace. Use this for open/community agents where transparency builds trust.

## Code Bundling

For code runtime agents (those with `runtime.command`), the CLI automatically creates a ZIP bundle of your project.

### Auto-Detection

The CLI detects code runtime projects by looking for:

* Python files (`.py`) with `requirements.txt`
* JavaScript files (`.js`) with `package.json`

### Entrypoint Detection

The CLI looks for entrypoints in this order:

**Python:** `main.py`, `app.py`, `agent.py`, `run.py`, `__main__.py`

**JavaScript:** `main.js`, `index.js`, `agent.js`, `main.ts`, `index.ts`, `agent.ts`

Override in your manifest:

```json theme={null}
{
  "entrypoint": "sandbox_main.py"
}
```

### Bundle Exclusions

These files/directories are automatically excluded:

**Python:**

* `**/__pycache__/`, `**/*.pyc`, `**/*.pyo`, `**/*.egg-info/`
* `venv/`, `.venv/`, `env/`, `.env`
* `dist/`, `build/`, `.eggs/`
* `pyproject.toml`, `setup.py`, `setup.cfg`
* `.mypy_cache/`, `.pytest_cache/`, `.ruff_cache/`

**Node.js:**

* `node_modules/`
* `yarn.lock`, `bun.lockb`
* `tsconfig.json`

<Note>
  `package.json` and `package-lock.json` are **automatically included** when a JavaScript entrypoint is detected. They are excluded from Python-only bundles to prevent monorepo conflicts. This ensures `npm install` runs correctly in the sandbox.
</Note>

**Git & IDE:**

* `.git/`, `.gitignore`, `.gitattributes`
* `.idea/`, `.vscode/`, `.DS_Store`

**Documentation:**

* `README.md`, `CHANGELOG.md`, `LICENSE`
* `docs/`

**Docker & CI:**

* `Dockerfile`, `docker-compose.yml`, `.dockerignore`
* `.github/`, `.gitlab-ci.yml`, `.circleci/`

**Tests:**

* `tests/`, `test/`, `__tests__/`
* `*_test.py`, `test_*.py`, `*.test.js`, `*.spec.ts`
* `conftest.py`, `pytest.ini`, `coverage/`

**Other:**

* `orchagent.json` (read separately)
* `*.zip`, `bundle.zip`
* `scripts/`, `Makefile`

For custom exclusions, add a `bundle` section to your manifest:

```json theme={null}
{
  "name": "my-agent",
  "bundle": {
    "exclude": ["data/", "*.log"],
    "include": ["important.dat"]
  }
}
```

### Size Limits

* Maximum bundle size: **50MB**
* Keep bundles small for faster cold starts

### Dry Run

Preview your bundle and canonical fields without publishing:

```bash theme={null}
orch publish --dry-run
```

This shows:

* Files that will be included
* Total bundle size
* Detected entrypoint

## Web UI Upload

You can also upload code bundles through the web dashboard as an alternative to the CLI.

### Upload via Dashboard

1. Go to [orchagent Dashboard](https://orchagent.io/dashboard)
2. Navigate to **Agents** → **My Agents**
3. Click **Upload Bundle** on your agent card
4. Drag and drop your ZIP file or click to select

### Bundle Requirements

When uploading manually, ensure your ZIP contains:

* `orchagent.json` at the root
* Your entrypoint file (`main.py`, etc.)
* `requirements.txt` or `package.json` (if needed)

### Bundle Status

Agent cards show bundle status indicators:

* ✓ **Active** - Bundle uploaded and ready
* ⏳ **Processing** - Bundle being validated
* ✗ **Error** - Bundle validation failed (check logs)

## Service Keys

When you publish an agent that has dependencies, the platform issues a **service key**:

```json theme={null}
{
  "agent": { "...": "agent fields" },
  "service_key": "sk_agent_...",
  "service_key_prefix": "sk_agent_..."
}
```

<Warning>
  Store the service key securely. It's only shown once on registration. Your agent uses this key to call other agents.
</Warning>

Set it as an environment variable for your deployed agent:

```bash theme={null}
export ORCHAGENT_SERVICE_KEY="sk_agent_..."
```

## Publish Options

| Flag                  | Description                                                                                             |
| --------------------- | ------------------------------------------------------------------------------------------------------- |
| `--all`               | Publish all agents in subdirectories in dependency order                                                |
| `--dry-run`           | Validate and preview bundle without publishing                                                          |
| `--entrypoint <file>` | Override entrypoint for tools                                                                           |
| `--skills <list>`     | Default skills (comma-separated, e.g., `org/skill@v1,org/other@v1`)                                     |
| `--skills-locked`     | Lock default skills (callers cannot override via flags)                                                 |
| `--no-local-download` | Prevent users from downloading and running locally (server-only). Local download is enabled by default. |

## Distribution

By default, new agents allow **local download** — users can download and run them with `orch run --local`. To make an agent server-only (cloud execution only):

```bash theme={null}
# Publish as server-only (disables local download)
orch publish --no-local-download
```

<Note>
  Agent owners can always download their own agents regardless of this setting.
</Note>

<Tip>
  Use `orch pull` to reconstruct a local project from any published version. This is the reverse of `orch publish` — it downloads the manifest, prompt, schemas, and code bundle into a local directory. See [CLI Commands](/using-agents/cli-commands#pull) for details.
</Tip>

## Troubleshooting

### "Manifest validation failed"

Check your `orchagent.json` for:

* Valid JSON syntax
* Required fields present
* Correct field types

### "Dependency not found"

Verify all dependencies in your manifest exist:

* Check org/agent names are correct
* Ensure dependencies are published
* Verify version strings match

### "Bundle too large"

Tool bundles have a 50MB size limit. To reduce size:

* Check for large files that shouldn't be included
* Remove `node_modules/` or `venv/` directories
* Use `bundle.exclude` in your manifest to exclude files

### "Entrypoint not found"

The CLI auto-detects entrypoints: `main.py`, `app.py`, `agent.py`, `run.py` for Python; `main.js`, `index.js`, `agent.js` for JavaScript. If your entrypoint has a different name:

```json theme={null}
{
  "entrypoint": "sandbox_main.py"
}
```

## CI/CD Integration

### GitHub Actions

```yaml theme={null}
name: Publish Agent

on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install CLI
        run: npm install -g orchagent

      - name: Publish
        env:
          ORCHAGENT_API_KEY: ${{ secrets.ORCHAGENT_API_KEY }}
        run: orch publish
```

### Environment Variables

For CI/CD, use environment variables instead of config files:

| Variable            | Description                      |
| ------------------- | -------------------------------- |
| `ORCHAGENT_API_KEY` | Your API key                     |
| `ORCHAGENT_API_URL` | API URL (defaults to production) |

## Next Steps

<CardGroup cols={2}>
  <Card title="Orchestration" icon="diagram-project" href="/building-agents/orchestration">
    Build agents that call other agents
  </Card>

  <Card title="CLI Reference" icon="terminal" href="/using-agents/cli-commands">
    All CLI commands
  </Card>

  <Card title="Billing" icon="credit-card" href="/concepts/billing">
    Platform credits and usage
  </Card>
</CardGroup>
