Install
$ agentstack add skill-agentproto-ts-agentproto ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
When to use
- "Start / check / restart the agentproto daemon", "what's it serving", session
control, workspace registration.
- "Drive the browser / an imported MCP through agentproto" — this is the runtime
underneath the browser, local-browser, linkedin, instagram, … skills. Reach for those skills for the recipe; reach for THIS one for the plumbing (is the daemon up? what's imported? why isn't a tool showing up?).
- "Author / extend an agentproto tool or driver" in
projects/agentproto/ts. - One-shot agent turns from the CLI (
agentproto run --prompt …). - "Build / extend the agentic PR review · fix · pr CI lanes" (the sandboxed
agent that reviews PRs and opens fixes, billing our subscription) → reference/ci-review-fix-lanes.md.
- "Create / apply an agentproto skill — where does it live, how is it
installed" (AIP-3 SKILL.md, the skill-pack-agentproto centralizing pack, .github/agent-skills CI skills) → reference/authoring-skills.md.
If you just need to act in a logged-in web app, go straight to local-browser / the site skill — they assume this plumbing already works.
What it is
agentproto is an open standard (the AIP specs at ) with a TypeScript reference implementation in this repo and an agentproto CLI.
Two-axis tool model (projects/agentproto/ts/README.md):
ITool @agentproto/tool defineTool(...) the contract (no body)
Tool @agentproto/driver implementTool(handle, body) contract + typed body
Driver @agentproto/driver defineDriver({...}) bundle of tools + infra
- Drivers (
packages/driver//) run a tool over a transport:builtin
· cli · http · mcp · sdk.
- Adapters (
adapters//) re-express the same implementation in a
host framework: toMastraTool, toAiSdkTool.
Write the body once; project it everywhere without a rewrite.
The runtime on this machine
The daemon ("agentproto serve") is a long-running local gateway: HTTP + MCP + PTY sessions, optionally exposed over a Cloudflare tunnel so remote clients (Guilde web, a phone) can drive local tools.
repo-local config .agentproto/ (per-workspace)
runtime.json live daemon: workspace, port (127.0.0.1:18790), pid
allowed-commands.json shell allow-list the daemon will execute
remote.json / cloudflared-*.yml tunnel wiring (secrets — never print)
user config ~/.agentproto/ (per-machine)
start-daemon-{local,prod}.sh launch scripts
imported-mcps.json MCPs proxied through /mcp (e.g. local-browser)
workspaces.json dirs the daemon may spawn sessions into
sessions.json live/known sessions
config.json / credentials.json auth + settings (secrets)
chrome-profile*/ chrome-mcp/ the local-browser plugin's cloned Chrome
Daemon vs tunnel — when to use which:
| Scenario | What to run | | -------------------------------------------------------- | ------------------------------------------------------ | | Claude Code (local) using mcp__agentproto__* tools | daemon only — ~/.agentproto/start-daemon-local.sh | | Guilde web app / mobile / remote client needs the daemon | daemon + tunnel — ~/.agentproto/start-daemon-prod.sh |
The tunnel (Cloudflare) exposes 127.0.0.1:18790 on a public URL with a bearer token. Without it, the daemon is reachable only from the local machine.
One-command restart (after VS Code reboot or daemon crash):
# From repo root — builds workspace + starts daemon (local profile) + starts guilde-tunnel :3600
./dev-up.sh
# Flags:
./dev-up.sh --no-build # skip rebuild (use last build)
./dev-up.sh --no-tunnel # daemon only, no guilde-tunnel
Then reconnect the MCP server in Claude Desktop / Claude Code settings.
Health check, in order:
curl -s http://127.0.0.1:18790/health—{"status":"ok"}= daemon live
(local profile). Use :18791 for prod profile.
- If dead: use the Bash tool to launch it (Claude Code can do this
directly): ``bash # Local profile (port 18790) — what mcp-bridge.mjs connects to: ~/.agentproto/start-daemon-local.sh &>/tmp/agentproto-daemon.log & sleep 3 && curl -s http://127.0.0.1:18790/health # Add --cli workspace if you need unpublished local fixes: ~/.agentproto/start-daemon-local.sh --cli workspace &>/tmp/agentproto-daemon.log & ``
--cli flag — controls which binary the daemon runs (orthogonal to profile):
~/.agentproto/start-daemon-local.sh # local profile :18790, published binary
~/.agentproto/start-daemon-local.sh --cli workspace # local profile :18790, local build ← use this for unpublished fixes
~/.agentproto/start-daemon-prod.sh --cli workspace # prod profile :18791, local build + tunnel
~/.agentproto/start-daemon-prod.sh --cli /abs/path/to/cli.mjs
Use --cli workspace when local packages have unpublished fixes or you need adapters that aren't published yet (e.g. adapter-claude-code from the workspace).
> Port trap: the mcp-bridge.mjs (Claude Desktop MCP connection) hardcodes > port 18790 = local profile. Using start-daemon-prod.sh (port 18791) > makes the bridge fail with "Unable to connect". Always use > start-daemon-local.sh when the goal is fixing the Claude Desktop MCP tools.
Persistence across restarts — the daemon (post-2026-06-19) writes two files at shutdown and reads them at boot:
~/.agentproto/transcripts/.json # ring buffer + cursor metadata per session
~/.agentproto/command-results.json # done/cancelled async commands (24 h TTL)
After restart: agent_output on a ghost session returns the saved transcript (not []), and command_log_tail { commandId } resolves finished commands. Sessions that were alive before the fix was deployed have no transcript file — they stay empty until the next clean shutdown. 3. After daemon is up, the MCP connection in Claude Desktop must be manually reconnected (settings → disconnect/reconnect on the agentproto server). The mcp__agentproto__* tools reappear once reconnected. 4. Imported tools missing? Check ~/.agentproto/imported-mcps.json, then mcp_imported_status / mcp_imported_tool_list once connected.
CLI cheat-sheet
agentproto auth authenticate against a remote host
agentproto config ~/.agentproto/config.json
agentproto daemon run as a launchd background service
agentproto install interactive picker → type then slug
agentproto install install adapter CLI + run setup
agentproto install --skip-setup install only (no setup)
agentproto setup re-run an adapter's setup (idempotent)
agentproto setup --force re-run ignoring ledger + skip_if
agentproto setup --only re-run one step only
agentproto run --cwd . --prompt … spawn adapter, one turn, exit
agentproto serve [--connect ] long-running daemon (HTTP+MCP+sessions)
agentproto workspace dirs the daemon can spawn into
agentproto sessions [...] browse + control live sessions
One-shot turn (machine-readable with --json → NDJSON, one event per line):
agentproto run claude-code --cwd . --prompt "summarise this repo"
echo "summarise CHANGELOG.md" | agentproto run claude-code --json
agentproto run claude-code --resume
Spawn + attach a real PTY session:
agentproto serve &
agentproto sessions terminal --name claude-tui --attach -- claude
agentproto-playground MCP (AIP authoring — the main one to use)
The agentproto-playground MCP (script: ~/.local/bin/agentproto-playground-mcp) exposes 6 verbs × N doctypes. Tools appear as mcp__agentproto-playground___.
Registered doctypes (core)
| Doctype | MCP name | File written | Required params | | -------------- | --------- | ------------------------------ | -------------------------------------------------- | | AIP-14 tool | tool | tools//TOOL.md | id, description, inputSchema, outputSchema | | AIP-42 agent | agent | .agents//AGENT.md | id, description, model | | AIP-39 action | action | .actions//ACTION.md | id, description, verb, target_kind | | AIP-41 routine | routine | follows routineSpec convention | id, description, trigger |
Plus any workspace extensions (AIP-40) auto-register as create_, e.g. create_playground_deal.
Verb signatures (same pattern for every doctype)
create_ { params: object, dir: string, body?: string, dryRun?: boolean }
→ writes /; dryRun=true = validate + return content, no write
load_ { path: string }
→ { path, handle, body } — reads manifest from disk
list_ { dir: string, skipDirs?: string[] }
→ array of handles found under dir
⚠ Point at a SPECIFIC workspace dir (e.g. "playground/workspace"), NOT the
repo root — doc fixtures in site/ and agentproto/specs/ contain the same
standard-library agents and will produce duplicates.
Default skipDirs: ["node_modules", ".git", "dist", ".next", ".turbo"]
update_ { path: string, patch: object, body?: string }
→ load → shallow-merge patch → write; only keys in patch change
resolve_ { block: EXACTLY ONE OF: { "inline": {...params} } | { "ref": "@scope/id" }
| { "file": "relative/path.md" },
baseDir?: string }
→ fully-typed handle (validates frontmatter schema only)
⚠ Schema-only validation: cross-doc refs (tools[], skills[], etc.) are stored
as opaque strings and are NOT existence-checked at resolve time. A handle that
resolves cleanly does NOT confirm the referenced tools/agents are registered.
⚠ The `ref` form throws at runtime ("no resolveRef provided") unless you supply
baseDir and the playground has a registry. Prefer `inline` or `file` forms.
delete_ { path: string }
→ removes the manifest file
ToolSearch gotcha — session tools need select: not keyword search
The daemon session tools (agent_start, session_list, etc.) are deferred tools in Claude Code. Keyword-based ToolSearch finds nothing because deferred tools are not in the keyword index. You must use exact-name select::
ToolSearch("select:mcp__agentproto__agent_start,mcp__agentproto__session_list,mcp__agentproto__agent_output,mcp__agentproto__agent_prompt")
The playground MCP (mcp__agentproto-playground__*) and the daemon MCP (mcp__agentproto__*) are two different servers — playground is authoring-only (these 6 verbs), daemon has the session/runtime tools. Both need separate ToolSearch loads.
create_agent — full params
{
"params": {
"id": "my-agent", // required: [a-z0-9@._/-]+
"description": "Does X by Y.", // required: 1-2000 chars
"model": "anthropic/claude-sonnet-4-6", // required
// optional:
"version": "1.0.0",
"tools": ["echo"], // AIP-14 tool refs
"skills": [{ "file": ".claude/skills/agentproto/SKILL.md" }],
"memory": { "scope": "per-conversation", "retention_turns": 50 },
"autonomy": 5, // 0-10
"boundaries": ["Never commit without approval"],
"traits": { "diligence": 8 },
"tags": ["research"],
},
"dir": "playground/workspace", // workspace-relative directory
"body": "You are …\n", // system prompt (markdown body)
"dryRun": false,
}
create_tool — full params
{
"params": {
"id": "my-tool", // required
"description": "Does X.", // required
"inputSchema": {
"type": "object",
"properties": { "query": { "type": "string" } },
"required": ["query"],
},
"outputSchema": {
"type": "object",
"properties": { "result": { "type": "string" } },
},
// optional:
"approval": "auto", // auto | always | on-mutate | policy:
"risk_level": 0, // 0-3
"cost_class": "trivial", // trivial | metered | expensive
"timeout_ms": 30000,
"idempotent": true,
"mutates": [],
"tags": ["example"],
},
"dir": "playground/workspace",
}
Workflow: dry-run an agent before writing
1. create_agent { params: {...}, dir: "...", dryRun: true } → validate
2. If ok → create_agent { dryRun: false } → write AGENT.md
3. resolve_agent { block: { file: ".agents/my-agent/AGENT.md" }, baseDir: "playground/workspace" }
→ fully resolved handle (confirms wiring)
4. Run it: agentproto run my-agent --cwd . --prompt "…"
OR via daemon: agent_start { adapter: "claude-code", prompt: "…" }
Daemon MCP tools (available as mcp__agentproto__*)
The daemon at http://127.0.0.1:18790/mcp exposes these tools directly:
Filesystem (workspace-scoped):
read_file { path }·write_file { path, content }·
list_directory { path? }
get_file_info { path }·create_directory { path }·
delete_file { path }
Shell execution (allowlist-gated via .agentproto/allowed-commands.json):
command_execute { command, args?, cwd?, stdin?, timeoutMs?, async? }→ sync:
{ exitCode, stdout, stderr, durationMs } · async: { commandId } · blocked (not in allowlist): { commandId, status: "pending_approval" }
get_command_output { commandId }→
{ status, stdout, stderr, exitCode?, durationMs }
cancel_command { commandId }→ SIGTERM a running async command
Async pattern (use for builds, claude -p, tests — MCP transport timeout is ~60 s):
r = command_execute { command: "pnpm", args: ["test"], async: true }
loop: out = get_command_output { commandId: r.commandId }; break if out.status != "running"
Command permission flow (when a command is blocked by the allowlist):
r = command_execute { command: "foo", ... }
# → { commandId, status: "pending_approval" } ← not in allowlist
permissions_list {}
# → { count, items: [{ requestId, command, args, cwd, risk, status, waitingSecs }] }
permissions_respond { id: r.requestId, decision: "approve" }
# → fast commands return output inline; slow ones: poll command_log_tail
permissions_respond { id: r.requestId, decision: "approve", scope: "always" }
# → also writes command to .agentproto/allowed-commands.json (never asks again)
permissions_respond { id: r.requestId, decision: "deny" }
# → exitCode -1, stderr "Permission denied by operator."
Allowlist setup (if command_execute is blocked with "not in allowlist"):
echo '{"version":1,"commands":["claude","gh","pnpm","node","git","npx"]}' > .agentproto/allowed-commands.json
Agent sessions (long-running adapter processes):
adapter_list { filter?: "all"|"available"|"ready" }→ full catalog with
status per entry:
"supported"— known adapter, package not installed yet → suggest
agentproto install
"available"— installed and importable, setup not yet run → call
agentproto setup
"ready"— installed + setup complete (or no setup required) → safe to
spawn
- Default
filter: "all"always returns the full catalog (never empty). Use
filter: "ready" to find what can be spawned immediately.
command_list { adapter: "claude-code" }→ slash-command catalog for one
adapter
agent_start { adapter, workspaceSlug?, cwd?, prompt?, label?, model? }→
{ sessionId }
- Only works for adapters with
status: "available"or"ready". If
adapter_list shows "supported", the spawn will fail — tell the user to install first.
agent_prompt { sessionId, prompt }→ queued if mid-turn, dispatched on
turn-end
- `a
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: agentproto
- Source: agentproto/ts
- License: Apache-2.0
- Homepage: https://agentproto.sh
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.