Deep Agents CLI (deepagents-cli) Analysis Report
Completed July 11, 2026 · 21 artifacts examined
5Findings
1Critical
4Medium
RAISE maturity 2.70 / 5.0
Executive Summary
Agent Remit (as declared)
A deterministic command-line deployment tool for Managed Deep Agents — it scaffolds a project (`init`), validates and bundles a declared project folder, and upserts it as a managed agent on the LangSmith platform (`deploy`), and manages workspace `agents` and `mcp-servers`. It performs no LLM inference itself: model identifiers it handles are configuration carried into the bundle for the deployed agent. It may talk only to `api.smith.langchain.com` over HTTPS with the developer's own API key, must assemble bundles solely from the project's declared sources, must never fold credentials into the payload, and must gate remote-agent updates and deletions behind explicit confirmation. Remote MCP server URLs it bundles, registers, or deploys against MUST use TLS.
Behavior Summary (as observed)
This is a well-engineered deterministic tool whose zero-trust primitives are real and runtime-enforced — HTTPS-only platform transport with userinfo rejection and `trust_env=False`, symlink/path-escape rejection on every bundled file, repo-local `.env` and deploy-state that cannot steer authenticated requests, MCP auth-header redaction, and explicit confirmation before updating a remote agent or deleting a resource — nearly all of them backed by security-relevant unit tests. The one material divergence is a single transport-security hole: the remit's restored requirement that remote MCP server URLs MUST use TLS is enforced nowhere. `mcp-servers add`/`update` pass `--url` straight to the platform without a scheme check, and `deploy` resolves referenced MCP URLs by registration and invocability only, never re-checking their scheme — so a `http://` or `ws://` MCP endpoint (and any `--header` credential sent to it) is accepted, registered, and deployed against in cleartext. The remaining gaps are posture-level: floor-pinned core dependencies, no durable action log, and a threat model that describes a package that no longer ships.
Scope of Analysis
A Python 3.11+ package (`deepagents_cli`) with an `argparse` entrypoint (`main.py`) that dispatches only `init`, `deploy`, `agents`, and `mcp-servers`; a bare invocation redirects the user to the separate `deepagents-code` package. The deploy surface lives under `deepagents_cli/deploy/`: `project.py` parses the on-disk project (rejecting symlinks and path escapes), `payload.py` is a pure function producing the agent payload and managed-directory tree, `api_client.py` wraps `httpx.Client(trust_env=False)` against a scheme-normalized HTTPS endpoint, `mcp_resolver.py` validates referenced MCP URLs against the live workspace list, `state.py` persists deploy state under `~/.deepagents/`, and `commands.py` holds the command handlers, confirmation prompts, and MCP header redaction. The package performs no LLM inference, spawns no shell/subprocess/server, and the only browser launch is for MCP OAuth. The committed `libs/cli/THREAT_MODEL.md` is stale — it documents the retired interactive-REPL surface, not this deploy tooling.
Remit Coverage

Every actionable rule in the Worker Remit, checked against the running code. Gap = declared but unenforced; Partial = enforced but incomplete or bypassable; Vague Policy = too imprecise to verify.

Verified: 21 Gap: 1 Partial: 1 Vague Policy: 0 Enforcement Not Possible: 0 Total Rules: 23
Rule ID Section Rule (quoted) Status Finding
R-01 Job Description "Assemble the agent payload and managed-directory file tree only from the project's declared sources, then upsert the agent on /v1/deepagents/agents (create when new, patch metadata + commit Hub directory when it already exists)." Verified
R-02 Job Description "Validate that every MCP server URL referenced by the project is already registered in the workspace and invocable by the caller's identity — never auto-registering servers during deploy." Verified
R-03 Job Description "Offer a `--dry-run` that prints the exact payload and directory files it would send, without contacting any mutating endpoint." Verified
R-04 Approved Communication Channels "Default endpoint `https://api.smith.langchain.com`; scheme forced to HTTPS, userinfo rejected, proxy env ignored (`trust_env=False`)." Verified
R-05 Approved Communication Channels "Scaffolding writes new files; overwriting an existing project folder requires `--force`." Verified
R-06 Data Boundaries — Forbidden Data Movement "Writing, committing to version control, logging, or printing platform / provider / Hub / tracing credentials or MCP auth-header values." Verified
R-07 Data Boundaries — Forbidden Data Movement "Folding secret material (e.g. `.env` contents) into the seeded bundle payload — environment stays environment; it is never merged into the skills, subagent, or managed-directory payload." Verified
R-08 Data Boundaries — Forbidden Data Movement "Pulling any file into the bundle from outside the resolved project root, via symlink, path traversal, or an undeclared source." Verified
R-09 Data Boundaries — Forbidden Data Movement "Letting repository-local deploy state steer authenticated requests (auth resolution ignores repo-local state)." Verified
R-10 Action Boundaries — Requires Human Approval Before Execution "Deploying to an `agent_id` declared in `agent.json` that local state has not previously confirmed — the CLI must show the target agent name/id and require a `y/N` confirmation before updating that remote agent (bypassable only with `--yes`)." Verified
R-11 Action Boundaries — Requires Human Approval Before Execution "Deleting a workspace agent or MCP server (requires `y/N` confirmation or `--yes`)." Verified
R-12 Action Boundaries — Never Allowed "Shipping a bundle assembled from anything other than the project's declared sources." Verified
R-13 Action Boundaries — Never Allowed "Deploying a project that failed configuration validation." Verified
R-14 Action Boundaries — Never Allowed "Reaching the platform over a non-HTTPS endpoint, or one carrying userinfo." Verified
R-15 Action Boundaries — Never Allowed "Bundling, registering, or deploying a project that references a remote MCP server over a non-TLS URL (`http://` / `ws://`) — remote MCP server URLs MUST use TLS (`https` / `wss`)." Gap PRAX-2026-07-11-001
R-16 Action Boundaries — Never Allowed "Auto-registering an MCP server, or deploying while a referenced MCP server is unregistered or uninvocable by the caller's identity." Verified
R-17 Action Boundaries — Never Allowed "Creating a fresh agent via `--reset` while `agent.json` still declares an `agent_id`." Verified
R-18 Tools and Capabilities — Forbidden Tools "Any LLM/model client invoked by the CLI itself (the tool performs no inference)." Verified
R-19 Tools and Capabilities — Forbidden Tools "Any interactive-REPL / coding-agent surface (belongs to `deepagents-code`)." Verified
R-20 Tools and Capabilities — Forbidden Tools "Any spawner of unauthenticated local dev servers, subprocess shells, hooks, or sandboxes as part of the deploy surface (those belonged to the retired REPL surface)." Verified
R-21 Behavioral Expectations — Acceptable Retry Behavior "HTTP 5xx responses are retried once with a short backoff; a directory-commit conflict (409/412) is re-fetched and re-applied once." Verified
R-22 Known Good Baseline "Dependencies are expected to be version-controlled with a committed, pinned lockfile." Partial PRAX-2026-07-11-002
R-23 Behavioral Expectations — Expected Patterns "A malformed project stops the deploy with a specific error rather than shipping a partial or invalid bundle." Verified
Findings Register

Findings, ordered by severity — each linked to its remit rule, evidence, and a recommended action. Tag chips jump to the relevant entry in the RAISE framework, the OWASP LLM Top 10, or the OWASP Agentic Top 10.

LLM06 primary — the finding's main OWASP categoryASI10 secondary — a category it also touches

CRITICAL PRAX-2026-07-11-001 Remote MCP server URLs are never validated as TLS — `mcp-servers add`/`update` and `deploy` accept and use `http://` / `ws://` endpoints in cleartext.
Policy Rule — R-15 (Worker Remit):
"Bundling, registering, or deploying a project that references a remote MCP server over a non-TLS URL (`http://` / `ws://`) — remote MCP server URLs MUST use TLS (`https` / `wss`)."
libs/cli/deepagents_cli/deploy/commands.py:762 — _execute_mcp_server_add calls client.create_mcp_server(url=args.url, ...) with no scheme check; only urlparse(args.url).hostname is used, for the default name libs/cli/deepagents_cli/deploy/mcp_resolver.py:33 — _normalize_url lowercases and strips trailing slash only; resolve_referenced_servers matches by URL + can_invoke, never re-checking https/wss scheme
Recommended Action
Reject non-`https`/`wss` MCP URLs at the earliest point — in `_execute_mcp_server_add` / `_execute_mcp_server_update` and again in `mcp_resolver._collect_referenced_urls` — mirroring `api_client._normalize_endpoint`'s scheme check, and add unit tests asserting an `http://` MCP URL is refused.
MEDIUM PRAX-2026-07-11-002 Shipped `pyproject.toml` floor-pins dependencies and leaves `deepagents` and `langsmith` with no upper bound, so published-wheel resolution can drift.
Policy Rule — R-22 (Worker Remit):
"Dependencies are expected to be version-controlled with a committed, pinned lockfile."
libs/cli/pyproject.toml:26 — dependencies use >= floors; "deepagents>=0.6.12" and "langsmith>=0.9.3" carry no upper bound (lines 26-40), unlike the capped langchain/httpx/langgraph-sdk entries
Recommended Action
Add upper bounds to the unbounded core dependencies (e.g. `deepagents>=0.6.12,<1.0.0`, `langsmith>=0.9.3,<1.0.0`) so the published wheel cannot silently resolve a breaking major.
MEDIUM PRAX-2026-07-11-003 No durable or structured audit record of mutating operations — deploy upserts and agent/MCP-server deletions leave only ephemeral stdout.
libs/cli/deepagents_cli/config.py:30 — comment "The CLI does not configure logging handlers by default, so logger.warning output is invisible to end users"; no FileHandler is configured anywhere in the package libs/cli/deepagents_cli/deploy/commands.py:507 — deploy result and delete confirmations are emitted via print() only; no structured/durable record of the upsert or deletion is written
Recommended Action
Write a structured, append-only record (JSON lines under `~/.deepagents/`) of each mutating operation — deploy upsert with agent id/revision, and agent/MCP-server deletions — with a timestamp and the resolved endpoint.
MEDIUM PRAX-2026-07-11-004 MCP auth-header credentials are accepted as `--header KEY=VALUE` CLI arguments, exposing them via the process table and shell history.
libs/cli/deepagents_cli/deploy/commands.py:956 — _parse_header_args splits the raw `--header KEY=VALUE` argv entry and stores value verbatim; no interactive/stdin or env-reference intake exists
Recommended Action
Offer a non-argv path for header secrets — a `--header-env KEY=ENVVAR` form or an interactive prompt — and document it as the recommended way to pass MCP credentials.
MEDIUM PRAX-2026-07-11-005 The committed `THREAT_MODEL.md` documents the retired REPL/TUI surface, leaving the shipped deploy tooling without current threat coverage.
libs/cli/THREAT_MODEL.md:5 — header disclaims that the document predates the 0.1.0 split and that the TUI/MCP/sandbox/server sections "no longer apply"; the in-scope deploy surface is named but never threat-modeled
Recommended Action
Regenerate the threat model against the `deepagents_cli.deploy` surface — covering bundle fidelity, MCP URL trust (including TLS), deploy-target confirmation, and credential handling — or remove the stale file so it cannot mislead.
What's Working Well

Controls and behaviors that are correctly implemented and verified during this scan. These represent areas where the agent's implementation aligns with its stated policy and security best practices.

HTTPS-only platform transport with userinfo and proxy-env rejected

`api_client._normalize_endpoint` forces the `https` scheme and rejects embedded userinfo, and the `httpx.Client` is built with `trust_env=False` so proxy/TLS env cannot redirect requests; asserted by tests.

libs/cli/deepagents_cli/deploy/api_client.py:52

Bundle fidelity — symlink and path-escape rejection on every read

`project._read_project_text` / `_ensure_project_contained` reject symlinks and any path resolving outside the project root, so nothing outside the declared sources can enter the bundle; covered by multiple symlink/escape tests.

libs/cli/deepagents_cli/deploy/project.py:57

Repo-controlled `.env` and deploy state cannot steer authenticated requests

Endpoint/proxy/TLS keys from a project `.env` are snapshotted and restored (`config._warn_if_project_blocked_env_changed`), and deploy state lives under `~/.deepagents/` with `ApiClient.from_env` ignoring repo-local state.

libs/cli/deepagents_cli/config.py:11

Confirmation gates on remote-agent update and resource deletion

`_confirm_agent_json_target` shows the target agent name/id and requires y/N before patching a remote agent not seen in local state; agent and MCP-server deletes require y/N or `--yes`; tested.

libs/cli/deepagents_cli/deploy/commands.py:361

MCP auth-header redaction on display

`_redact_mcp_header` replaces header values with `***` before `mcp-servers get` prints the record, keeping credentials out of terminal output; asserted by test_mcp_servers_get_redacts_header_values.

libs/cli/deepagents_cli/deploy/commands.py:1071

No MCP auto-registration; registration and invocability validated at deploy

`resolve_referenced_servers` always queries the live workspace list and raises on unresolved or uninvokable MCP URLs rather than creating servers, keeping trust expansion explicit.

libs/cli/deepagents_cli/deploy/mcp_resolver.py:51
Discovered Log Files

Log files found in the agent's workspace during this scan. Reviewing these files provides runtime evidence to complement the static analysis above.

The CLI configures no logging handlers and writes no log files; the absence of any durable action record is itself a finding (PRAX-2026-07-11-003).
OWASP LLM Top 10 (2025) Coverage

Each card represents one category and shows the top 3 findings. All items in the Findings section.

LLM01 Prompt Injection
No findings
LLM04 Data and Model Poisoning
No findings
LLM05 Improper Output Handling
No findings
LLM06 Excessive Agency
No findings
LLM07 System Prompt Leakage
No findings
LLM08 Vector and Embedding Weaknesses
No findings
LLM09 Misinformation
No findings
LLM10 Unbounded Consumption
No findings
OWASP Agentic Top 10 (2026) Coverage

Each card represents one category and shows the top 3 findings. All items in the Findings section.

ASI01 Agent Goal Hijack
No findings
ASI02 Tool Misuse and Exploitation
No findings
ASI03 Identity and Privilege Abuse
No findings
ASI04 Agentic Supply Chain Vulnerabilities
No findings
ASI05 Unexpected Code Execution (RCE)
No findings
ASI06 Memory and Context Poisoning
No findings
ASI08 Cascading Failures
No findings
ASI09 Human-Agent Trust Exploitation
No findings
ASI10 Rogue Agents
No findings
RAISE Maturity Posture

Overall maturity assessment across the six categories of the RAISE framework. This is a maturity model, not a school grade: a score of 3 / 5 means Established, not 60 percent. Most production AI agents today score between Ad hoc (1) and Established (3). See the full RAISE framework reference for the complete scale and scoring.

2.70 / 5.0
Weighted Maturity Score · Partial
Partial. The CLI has a coherent and largely verified security architecture for a deterministic developer tool: platform transport is HTTPS-only with userinfo and proxy-env rejected, bundle assembly is confined to declared sources with symlink and traversal defenses, repo-controlled state cannot redirect authenticated requests, and high-impact operations are confirmation-gated — and a real test suite asserts these. It is held back by one transport-trust gap (remote MCP server URLs are never validated as TLS), by supply-chain hygiene that leans on floor pins with unbounded upper bounds on core dependencies, and by the absence of any durable, structured record of the mutating operations it performs.
Limit Your Domain
4/ 5
Confidence: High  |  Weight: 15%  |  Weighted: 0.60
The wired surface is exactly four subcommands (`main._dispatch_command`); every other invocation redirects to `deepagents-code`, and the forbidden surfaces (model client, REPL, dev-server/shell/sandbox spawner) are genuinely absent from the deploy modules rather than merely disabled.
Balance Your Knowledge Base
3/ 5
Confidence: High  |  Weight: 15%  |  Weighted: 0.45
Bundle provenance is tightly controlled — `payload.build_*` is a pure function over declared project sources, `.env`/environment is never folded into the payload, and `project.py` rejects symlinks and path escapes — though bundled file contents themselves are not otherwise scanned (by design, as the developer authors them).
Implement Zero Trust
3/ 5
Confidence: High  |  Weight: 25%  |  Weighted: 0.75
Strong operative controls — HTTPS+userinfo endpoint enforcement (`api_client._normalize_endpoint`), `trust_env=False`, repo-local `.env`/state ignored for auth, deploy-target and delete confirmations — are offset by one real transport hole: remote MCP server URLs are never validated as TLS at add, update, or deploy (PRAX-2026-07-11-001).
Manage Your Supply Chain
2/ 5
Confidence: Medium  |  Weight: 15%  |  Weighted: 0.30
A committed `uv.lock` and repo-level `dependabot.yml` show active management, but the shipped `pyproject.toml` floor-pins its dependencies and leaves `deepagents` and `langsmith` with no upper bound, so the published wheel's resolved versions can drift (PRAX-2026-07-11-002).
Build an AI Red Team
3/ 5
Confidence: High  |  Weight: 15%  |  Weighted: 0.45
148 unit tests include explicit adversarial cases that assert the security architecture — symlink and path-escape rejection, HTTPS-endpoint and userinfo enforcement, `trust_env` off, header redaction, and confirmation gates — but no test exercises the MCP-TLS requirement, and the committed threat model is stale (PRAX-2026-07-11-005).
Monitor Continuously
1/ 5
Confidence: High  |  Weight: 15%  |  Weighted: 0.15
The CLI configures no logging handlers and keeps no durable record of its mutating operations (deploy upsert, agent/MCP-server delete); all feedback is ephemeral stdout/stderr via `print`, leaving nothing to reconstruct what was deployed or deleted after the fact (PRAX-2026-07-11-003).

Maturity Scoring Rubric

Every score above is based on this scale. A score is a snapshot of observable posture — not a verdict on the people or team behind the system.

Score Label Meaning
5 Exemplary Best-in-class; automated, continuously tested, reference quality. Rarely achieved in shipping systems.
4 Strong Comprehensive controls, active management, minor gaps. Production-ready.
3 Established Documented controls consistently applied; known gaps accepted. A respectable baseline.
2 Partial Some controls exist but coverage is incomplete; key gaps remain.
1 Ad hoc Informal or inconsistent measures; relies on individual judgment.
0 Absent No evidence this category is addressed at all.
Weighting: the weighted overall above is the sum of each category's score × weight (the per-category weights are shown on each card). Zero Trust carries double weight by design; see the RAISE framework reference for the rationale.