CodeDocs Vault

03 — Entry Points & Execution Flow

There are three execution entry points, one per surface.

A. Cowork / Claude Code installation (interactive)

Entry point: the user installs a plugin from the marketplace.

# Either via Cowork UI (paste repo URL in Settings → Plugins → Add plugin)
# Or via Claude Code CLI:
claude plugin marketplace add anthropics/claude-for-financial-services
claude plugin install financial-analysis@claude-for-financial-services
claude plugin install pitch-agent@claude-for-financial-services

(README.md:60-69)

What the marketplace consumes: .claude-plugin/marketplace.json lists 20 plugins, each pointing at a directory under plugins/ (marketplace.json:6-107). Each of those directories has its own .claude-plugin/plugin.json with name, version, description, author.

flowchart LR
  U[User] --> M[Marketplace UI / claude CLI]
  M --> MJ["marketplace.json"]
  MJ --> P["plugin source dir"]
  P --> PJ[".claude-plugin/plugin.json"]
  P --> CMD["commands/*.md"]
  P --> SK["skills/*/SKILL.md"]
  P --> AG["agents/*.md"]
  P --> MC[".mcp.json"]
  P -.-> H["hooks/*.json (currently empty)"]

What happens at runtime:

  1. Slash commands appear: /comps, /dcf, /earnings, /ic-memo (mapping in README.md:160-247).
  2. Named agents become available in Cowork dispatch.
  3. Skills auto-fire when their description matches the conversation context.
  4. MCP connectors authenticate per-user against the providers in plugins/vertical-plugins/financial-analysis/.mcp.json.

Hooks are scaffolded but currently empty (plugins/vertical-plugins/financial-analysis/hooks/hooks.json:1[]; investment-banking/hooks/hooks.json{"hooks": {}}).

B. Claude Managed Agents deployment (headless)

Entry point: scripts/deploy-managed-agent.sh <slug> (e.g. gl-reconciler).

export ANTHROPIC_API_KEY=sk-ant-...
export GL_MCP_URL=...           # read-only GL MCP
export SUBLEDGER_MCP_URL=...    # read-only subledger MCP
scripts/deploy-managed-agent.sh gl-reconciler

(managed-agent-cookbooks/gl-reconciler/README.md:11-15)

Deploy flow (DAG)

The script walks managed-agent-cookbooks/<slug>/agent.yaml and recursively deploys subagents first, then the orchestrator. Subagents must already exist before the orchestrator can reference them by ID.

flowchart TB
  start([scripts/deploy-managed-agent.sh slug])
  load["yaml2json(agent.yaml)<br/>+ ${ENV} substitution<br/>(deploy-managed-agent.sh:36-52)"]
  expand["resolve_manifest:<br/>expand from_plugin: → individual {path:} entries<br/>(deploy-managed-agent.sh:88-112)"]
  inline["inline_system: read system.file → embed as string<br/>(deploy-managed-agent.sh:114-130)"]
 
  loopskill{For each<br/>{path: ...}<br/>skill}
  zip["cd skill/.. && zip -qr skill.zip skill"]
  postskill["POST /v1/skills (multipart, beta: skills-2025-10-02)<br/>(deploy-managed-agent.sh:70-86)"]
  cache["cache skill_id by basename"]
 
  loopsub{For each<br/>callable_agents.manifest}
  recurse["recurse: create_agent(subagent.yaml)"]
  delout["del .output_schema before POST<br/>(deploy-managed-agent.sh:154)"]
 
  postorch["POST /v1/agents<br/>(beta: managed-agents-2026-04-01)<br/>(deploy-managed-agent.sh:162)"]
  done([echo agent id + console URL])
 
  start --> load --> expand --> inline
  inline --> loopskill
  loopskill --> zip --> postskill --> cache
  cache --> loopsub
  loopsub --> recurse --> delout
  delout --> postorch --> done

Notable transformations:

  1. from_plugin: expansion. A single skills: [{from_plugin: ../../plugins/agent-plugins/pitch-agent}] line in the orchestrator yaml becomes one {__upload: <abs>/skills/<each>/} per skill in that plugin (deploy-managed-agent.sh:95-105).
  2. Skill upload caching. Skills uploaded once per run, indexed by basename in a tempfile (deploy-managed-agent.sh:54-65). A skill referenced by orchestrator and subagent uploads only once.
  3. output_schema is deleted before POST. output_schema: is a deploy-side convenience, not an API field. The Managed Agents API doesn't enforce structured output — scripts/validate.py is the firm-side enforcer. Kept under the del(.output_schema) jq filter at deploy-managed-agent.sh:154.
  4. Env-var sandboxing. ${VAR} substitution rejects values with characters outside [A-Za-z0-9._/:@-] (deploy-managed-agent.sh:43-47) — prevents shell-injection from a hostile env value into the manifest.

Dry-run mode

scripts/deploy-managed-agent.sh <slug> --dry-run produces the resolved POST bodies without contacting the API (deploy-managed-agent.sh:17-18, 173-180). scripts/test-cookbooks.sh uses this in CI to assert all 10 cookbooks resolve cleanly:

# scripts/test-cookbooks.sh:8-26 — every cookbook:
#   - is valid JSON
#   - has non-empty system
#   - is depth-1 (subagent has no callable_agents)
#   - does not leak output_schema

Steering events

After deploy, the workflow engine drives the agent with steering events. The example shapes are in steering-examples.json files. From managed-agent-cookbooks/gl-reconciler/steering-examples.json:2-13:

[
  {"event": "Reconcile GL vs subledger, trade date 2026-04-30, classes: equities, fixed-income, derivatives",
   "description": "Daily run across three asset classes"},
  {"event": "Re-trace break: account 41200-EQ-US, trade date 2026-04-30",
   "description": "Follow-up steering event to deep-dive a single break"}
]

These are the user-side strings; the firm's workflow engine (Temporal / Airflow / event bus) sends them to client.beta.agents.sessions.steer(...).

Cross-agent handoff

scripts/orchestrate.py is the reference event loop. It is not the deploy entry point — it runs alongside the workflow engine to route handoff blobs.

# orchestrate.py:64-82 (paraphrased)
with client.beta.agents.sessions.stream(session_id=...) as stream:
    for event in stream:
        if event.type != "message_delta": continue
        handoff = extract_handoff(event.text)
        if not handoff: continue
        target_id = agent_ids.get(handoff["target_agent"])
        client.beta.agents.sessions.steer(
            agent_id=target_id,
            input=handoff["payload"]["event"],
        )

extract_handoff (orchestrate.py:45-61) regex-matches the JSON, JSON-decodes, and jsonschema.validates against HANDOFF_PAYLOAD_SCHEMA. Anything malformed is silently dropped — the agent's text continues to the user but the routing step is skipped.

C. Microsoft 365 add-in setup (admin wizard)

Entry point: the admin types /claude-for-msft-365-install:setup after installing the plugin.

claude plugin install claude-for-msft-365-install@claude-for-financial-services
# inside the session:
/claude-for-msft-365-install:setup

The slash command at claude-for-msft-365-install/commands/setup.md is itself the agent. It branches the admin through:

  1. Step 1 — pick gateway / vertex / bedrock / foundry (setup.md:28-44).
  2. Step 1b — Excel/Word/PowerPoint vs Outlook (setup.md:51-66). Outlook is a separate manifest with extra Graph admin consent; Bedrock + Outlook is unsupported.
  3. Per-cloud branch — provisioning steps with copy-paste console URLs and gcloud / IAM commands.
  4. Generates the manifest by shelling out to node scripts/build-manifest.mjs (setup.md:18-20).
  5. Maintains a setup log at ~/Desktop/claude-for-msft-365-install-setup.md so reruns can resume from where they left off (setup.md:11-15).

This is interesting because the slash command IS the program. There's no setup.py or wizard binary — the markdown drives an LLM to ask the right questions, run the right commands, and write the manifest. The Node script is a small render step at the end.

Summary table

Surface Entry point What runs What you get
Cowork / Claude Code claude plugin install <name>@claude-for-financial-services Single Claude session reading plugin files Slash commands, auto-firing skills, named agents, MCP connectors
Managed Agents (headless) scripts/deploy-managed-agent.sh <slug> then client.beta.agents.sessions.steer(...) Depth-1 hierarchy: orchestrator + 2-3 subagents on Anthropic infra Files written to ./out/ per session; orchestrator may emit handoff requests
Microsoft 365 add-in setup /claude-for-msft-365-install:setup Interactive Claude session driving an admin through tenant setup Customized manifest.xml for M365 Admin Center, Azure consent done, optional per-user config