Skip to content
Back to skills

Apx

ASecurity

APX CLI umbrella — routes operations to sub-skills (sessions, MCPs, routines, tasks, commitments, telegram, projects, agents, agent vault, profiles, runtimes). Activate on `apx`, the APX daemon, or coordinating/running/delegating agents. Not for `.apc/` alone (use apc-context). Triggers: 'apx', 'apx run', 'apx daemon', 'coordinate agents'.

  • 12 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
ai-agentsgoshellbashnodegit

Works with

  • claude code
  • cursor
  • terminal
  • cli
  • mcp

Security analysis

A100/100

Scanned September 27, 2026

npx -y skills add agentprojectcontext/apx --skill apx --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Apx?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Apx
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/agentprojectcontext-apx-apx/badge)](https://www.skillsdirectory.com/skills/agentprojectcontext-apx-apx)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: apx
description: "APX CLI umbrella — routes operations to sub-skills (sessions, MCPs, routines, tasks, commitments, telegram, projects, agents, agent vault, profiles, runtimes). Activate on `apx`, the APX daemon, or coordinating/running/delegating agents. Not for `.apc/` alone (use apc-context). Triggers: 'apx', 'apx run', 'apx daemon', 'coordinate agents'."
homepage: https://github.com/agentprojectcontext/apx
---

# APX — Agent Project Context Runtime

APX is a daemon (`127.0.0.1:7430`, auto-starts on first call) that turns external coding CLIs (Claude Code, Codex, OpenCode, Aider, …) and configurable agents into a unified orchestration surface. It reads APC project context from `.apc/` (committed) but keeps runtime state outside the repo under `~/.apx/projects/<project-id>/`. Super-agent has a default workspace at `~/.apx/projects/default` for system-level work.

## When to use APX (vs. native subagent)

If you can spawn a subagent natively in the current IDE (Claude Code, Cursor, …) — **do that**. No APX needed. Use APX when:
- User explicitly asks for a specific external runtime ("run this in Codex", "delegate to OpenCode").
- You need an agent in a runtime different from the one you're in.
- Orchestrating from outside any IDE (script, Telegram bot, CI, routine).

## Sub-skill index

| Topic | Sub-skill | When |
|-------|-----------|------|
| Delegate to external coding CLI | **apx-runtime** | `apx run <agent> --runtime claude-code\|codex\|...` |
| List/read/resume/summarise/continue sessions | **apx-sessions** | `apx session resume`, `apx sessions list`, "import a codex session" |
| Use a registered MCP tool | **apx-mcp** | `apx mcp tools`, `apx mcp run`, "call MCP filesystem", "MCP failing" |
| Connect/diagnose a service connector | **apx-integrations** | Asana/Calendar/GitHub/Obsidian, "not connected", "read-only calendar", Plugins tab |
| Add/configure/use a project agent | **apx-agent** | "add an agent", vault import, per-agent model, agent memory |
| Reusable agent templates (vault) | **apx-agency-agents** | "spawn Cody/Rocky/Tessa", "list agents", import a bundled default |
| Install/activate an agent profile (line of work) | **apx-profile** | "install the secretary", "go back to vanilla", "why does it message me" |
| Register/list/configure a project | **apx-project** | "register this project", `apx project list`, per-project config |
| Per-project TODO list | **apx-task** | "add a task", "remind me to…", "what's pending" |
| Promises made to a named person | **apx-commitment** | "I told X I would…", "le dije a X que…", "what do I owe X" |
| Scheduled/recurring agents | **apx-routine** | `apx routine add`, every-5m, cron-like jobs |
| Telegram I/O | **apx-telegram** | configure bot, channels, send a message |
| Voice channel (TTS, speech) — *optional* | **apx-voice** | only if voice is being set up |
| Build a new MCP server — *internal/dev* | **apx-mcp-builder** | authoring a brand-new MCP from scratch |
| Author a new APX skill — *internal/dev* | **apx-skill-builder** | adding to APX itself |

> *internal/dev* sub-skills aren't pushed to IDE skill dirs by default. They live in the APX repo; install to IDE with `apx skills add <slug> --global`.

## Talk to a peer (a2a) — an agent OR another coding CLI

**First: is this a message at all?** Work you want another agent to DO is a
task assigned to them (`create_task`, or `comment_task` mentioning them on the
existing one) — they take it up on their own turn, and the task holds the
back-and-forth. A report (`--severity status`/`fyi`) is FILED without
`--deliver`: it rides the digest and runs nobody's model. Only a `blocker`
delivers (`--severity blocker --deliver --background`). A live a2a exchange is
for when the owner is in the conversation and needs that answer now.

A background turn that stops with `spend breaker: …` hit the hourly ceiling on
model calls by unwatched work (`super_agent.spend_breaker`). It is paused on
purpose and the owner was already told: do not retry or route around it.
`apx usage breaker` shows it; only the owner lifts it (`apx usage resume`).

When the user says "hablá con Roby" / "avisale a <agent>" / "pasale esto a <peer>",
message them on the **a2a channel** — NOT `apx exec` (that posts as the user).

**If you are an APX agent, use the `send_to_agent` tool, not this command.** The
tool knows who you are, reaches any peer (an agent, the super-agent, a runtime),
and can leave the work running instead of holding your turn. The CLI below is for
a coding CLI reaching in from the outside — and it BLOCKS: `--deliver` holds the
terminal until the peer answers, which on a real exchange has meant one agent
frozen waiting on another until its own shell timeout killed the call.

### Don't wait for an answer you don't need yet

`send_to_agent` waits by default: the peer's answer is the tool's result. That is
right only when you need that answer to write your next sentence. A peer's turn
is a full tool loop that can run for many minutes, and waiting through one does
nothing for you or the owner.

| You want to… | Call it with |
|---|---|
| Ask something you need **right now** | *(nothing — the default waits)* |
| Hand work off and **pick it up when it lands** | `background: true` |
| Tell them something you will never need an answer to | `background: true, wake_me: false` |

With `background: true` the tool returns at once with a `job_id`, and the peer
works on its own. When it answers you are **woken**: the reply arrives as a new
message on that same a2a thread and you carry on from there.

Three things that matter when you background something:

- **Your context is not kept while you wait.** You are woken in a fresh turn with
  the reply and a recap of what you asked — nothing else. Put everything you will
  need in order to act on the answer into the message itself.
- **Do not poll.** Never call `send_to_agent` again for the same thing, and never
  "check" on it. You will be woken; asking again just opens a second exchange.
- **What you write when woken is your own note, not a reply.** It is not sent
  back to the peer — they answered and are waiting on nothing. Do not thank
  them or confirm receipt; message them again only with a genuinely new request.
- **A failure wakes you too**, and says so in as many words. If the peer never
  answered, the job timed out, or the daemon restarted while it ran, you are told
  that plainly and there is no result to use. Do not report such a job as done.

Each agent may leave **3** jobs running at once, and a chain of agents handing
work to each other stops at **3** hand-offs deep — waiting or backgrounded, via
`send_to_agent` or `call_agent`. Both limits come back as a message you can act
on, not as a crash. A peer's own turn gets **20** tool steps; if it runs out it
answers with what it did and what is left, and you decide whether to continue.

### The same thing for a long COMMAND

A peer is not the only worker that takes minutes. A render, an encode, a build, a
batch over a folder — `run_shell` waits for all of them, and kills them at 600 s
at the very most, so anything longer **cannot finish in the foreground at all**.

```js
run_shell({ command: "hyperframes render reel-13.html -o out/13.mp4", background: true })
// → { job_id, pid, log_path, status: "running", … }   immediately
```

It is the same mechanism, deliberately: the same store, the same panel, the same
three-job wall (peers and commands **share** it), the same cancel. What differs
is only what a process can give you that a peer cannot, and where you come back.

- **The owner watches it print.** The tail of the output rides on the job while it
  runs, so the background-work panel shows a line that moves. Launching the work
  is therefore how you SHOW the work — an agent that says it is rendering and has
  no job running is an agent that is not rendering.
- **You are woken in THIS chat**, not on an a2a thread: a new turn carrying the
  command, its exit code and the tail of its output. There is nobody to reply to
  — you are back with the owner, so report to them.
- **The whole output is on disk** at the `log_path` you were given. The wake-up
  carries the tail; `tail -n 100 <log_path>` gets the rest if you need it.
- **A batch is a queue, not one command.** Thirteen reels with a wall of three:
  launch three, and launch the next one each time a wake-up tells you one landed.
  Do not chain all thirteen into a single `&&` — one failure at reel 4 takes the
  other nine with it and you cannot tell which of them ran.
- **`exit 0` is not "it worked".** A render can exit 0 having written nothing.
  When you are woken, check what it was supposed to produce — the file, its size —
  before you tell anybody it is done.

The failure modes are the peer's, with one of its own: if the daemon restarts
mid-command the process keeps going (it is detached) but nobody is watching it any
more, so you are woken with `lost` — which means **unknown**, not failed. Look at
the files before saying anything about it.

The super-agent is the exception: its thread is its channel, so it cannot be woken
this way. It may still launch, watch and stop a job; the tool says so in the
answer, and work somebody needs to act on belongs with a project agent instead.

```bash
apx send <you> <peer> "<message>" --deliver [--project <name>]
```

- `<you>`: your own identity as sender, and never anybody else's. A coding CLI
  passes its **runtime id** (`claude-code`, `codex`, `opencode`, `aider`,
  `cursor-agent`, `gemini-cli`, `qwen-code`, `antigravity`); an agent passes its
  **slug**. It need NOT be a registered agent. Short spellings fold into the
  canonical id (`claude` → `claude-code`, `gemini` → `gemini-cli`, `qwen` →
  `qwen-code`, `cursor` → `cursor-agent`), so one CLI stays one peer with one
  history. Append `:<session>` for WHICH conversation with you this is —
  `claude-code:acme-web`; a bare session name is kept as written and becomes a
  correspondent nobody can place.
  Do NOT take a name out of `apx agent list` because the role sounds like the
  work you are doing — that list is who can RECEIVE. Whoever you name is who the
  exchange is filed under, in THAT agent's project, with THAT agent's model
  stamped on your words.
- `<peer>`: whoever answers. Either:
  - an **agent slug** from AGENTS.md — answered by that agent's model; or
  - a **runtime id** (`claude-code`, `codex`, `opencode`, `aider`, `cursor-agent`,
    `gemini-cli`, `qwen-code`, `antigravity`) — answered by spawning that CLI.
    This is how one coding IDE talks to another through APX.
- `:<thread>` opens a SECOND, independent exchange with the same peer —
  `apx send claude-code opencode:review "…"`. Separate history, separate
  session.
- An agent slug wins over a runtime of the same name. If a slug lives in several
  projects, `apx send` refuses and lists them — pass `--project`.
  `apx agent list --all` shows every agent with its project. A runtime peer is
  registered nowhere: it runs in the project you are standing in, in YOUR cwd.
- `--deliver` runs the peer now and returns its reply on stdout. The exchange
  shows in the web inbox as a "claude-code · opencode" group chat.

### Two kinds of exchange: talking, and working

By default an a2a message opens a **conversation**: the peer runs in its own
read-only mode (`claude --permission-mode plan`, `codex --sandbox read-only`,
`opencode --agent plan`). It can read anything and answer anything, but it
cannot change the codebase. That is deliberate — being messaged is not consent
to have your checkout edited.

`--code` opens a **coding session** instead: write access on, the peer is told to
do the work rather than describe it, and the exchange is mirrored into the **Code
module** (`/code`) so it shows up where every other coding session does — the
sender's messages as the user turns, the peer's replies as the assistant's.

`claude-code` and `codex` are never `--code` peers. They are the CLIs you drive
yourself, and a message must not also start them writing to the same checkout;
they answer read-only. Send the work to `opencode`, or use `apx run`.

```bash
apx send claude-code opencode "¿qué le falta a src/auth?" --deliver
apx send claude-code opencode "agregá el retry al fetch helper" --deliver --code
```

The peer runs in YOUR current directory, so `--code` edits the checkout you are
standing in, not the project record's path.

A coding session can take minutes. `--background` hands the turn back at once and
the reply lands on the thread when it finishes (`--timeout <s>` caps it; default
300s foreground, 3600s background):

```bash
apx send claude-code opencode "migrá los tests a node:test" --deliver --code --background
```

### The exchange keeps its own session

A runtime peer continues its OWN session between turns (`claude -p --resume`,
`codex exec resume`, `opencode run --session`). APX stores that id on the thread
and resumes it next message, so the peer is not handed the transcript again and
does not redo work it already did. `apx send` prints the session it used.

A peer that cannot keep a session still works — APX carries the thread history in
the prompt instead. Either way the conversation continues; sessions only make it
cheaper. When there is no session, `apx send` says why instead of leaving the
line blank.

Runtimes with native sessions today: `claude-code`, `codex`, `opencode`. The rest
(`aider`, `cursor-agent`, `gemini-cli`, `qwen-code`, `antigravity`) fall back to
the carried thread.

### Answering an a2a message

Your output IS the reply: APX logs it and hands it back to the sender. Do NOT
also run `apx send` with that same answer — it files the exchange twice. Use
`apx send` only to open a NEW exchange: a follow-up once this turn is over, or a
message to somebody else. Every a2a message carries its own return address.

- The agent decides whether/how to tell the user on its own channel (respecting
  quiet-hours) — you don't `apx telegram send` the user yourself.
- `--severity blocker|status|fyi` tags urgency when relaying up to Roby: a
  `blocker` alerts the owner **in the act** (Roby pings, crossing quiet-hours);
  `status`/`fyi` ride the end-of-day digest and never interrupt.

## Generic patterns (apply to every sub-skill)

### Verify commands before recommending

Don't invent APX subcommands. Confirm exact form with `apx --help` or `apx <command> --help` before telling another runtime to invoke APX. Avoid guessed aliases (e.g. `apx send-telegram` is not a thing — see apx-telegram).

### `APC_RESULT` contract

When you want APX to capture a structured value from an agent (any runtime), instruct the agent to print on its last meaningful line:

```
APC_RESULT: <one-line value>
```

APX's `extractApfResult()` parses that and stores it as the session's `result` field. Useful for automation, routines, CI.

### Tool permissions

```bash
apx permission show
apx permission set automatico   # total | automatico | permiso
```

`automatico` runs read/list/safe shell checks directly; asks before destructive shell, MCP, runtime, outbound, config, or filesystem mutation.

### Memory

Write memory only for durable, safe project facts. No raw transcripts or secrets.

```bash
apx memory <slug>                       # read agent's memory.md
apx memory <slug> --append "<fact>"     # append durable note
apx memory <slug> --replace < file.md   # replace entire memory from stdin
```

### Observe activity

```bash
apx messages tail                               # last 50 messages, all channels
apx messages chat --channel telegram -n 20      # readable chat view
apx messages tail --channel runtime --agent <slug> -n 20
```

## Anti-patterns

- Don't activate apx-sessions inside a request that's purely about `apx run` orchestration — use apx-runtime.
- Don't activate apx-mcp-builder unless the user is actually authoring a new MCP server (deep dev guide, not usage).
- Don't push state to `.apc/` that belongs in `~/.apx/projects/<id>/` (sessions, conversations, runtime logs).

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…