deepagents-cli 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/.gitignore +2 -0
  2. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/CHANGELOG.md +6 -0
  3. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/PKG-INFO +9 -1
  4. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/README.md +8 -0
  5. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/_version.py +1 -1
  6. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/templates.py +38 -7
  7. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/package-lock.json +3 -3
  8. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/pyproject.toml +1 -1
  9. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_bundler.py +85 -0
  10. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/uv.lock +5 -5
  11. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/DEV.md +0 -0
  12. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/Makefile +0 -0
  13. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/THREAT_MODEL.md +0 -0
  14. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/__init__.py +0 -0
  15. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/__main__.py +0 -0
  16. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/config.py +0 -0
  17. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/__init__.py +0 -0
  18. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/bundler.py +0 -0
  19. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/commands.py +0 -0
  20. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/config.py +0 -0
  21. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/context_hub.py +0 -0
  22. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +0 -0
  23. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +0 -0
  24. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +0 -0
  25. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +0 -0
  26. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +0 -0
  27. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +0 -0
  28. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/index.html +0 -0
  29. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/logo-dark.svg +0 -0
  30. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/deploy/frontend_dist/logo-light.svg +0 -0
  31. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/main.py +0 -0
  32. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/model_config.py +0 -0
  33. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/deepagents_cli/py.typed +0 -0
  34. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/deploy-content-writer/.env.example +0 -0
  35. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
  36. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
  37. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/deploy-content-writer/user/context.md +0 -0
  38. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/deploy-content-writer/user/preferences.md +0 -0
  39. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/arxiv-search/SKILL.md +0 -0
  40. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  41. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/langgraph-docs/SKILL.md +0 -0
  42. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/skill-creator/SKILL.md +0 -0
  43. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  44. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  45. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/examples/skills/web-research/SKILL.md +0 -0
  46. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/.nvmrc +0 -0
  47. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/index.html +0 -0
  48. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/package.json +0 -0
  49. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/postcss.config.js +0 -0
  50. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/public/logo-dark.svg +0 -0
  51. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/public/logo-light.svg +0 -0
  52. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/App.tsx +0 -0
  53. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/ThemeProvider.tsx +0 -0
  54. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/auth/anonymous.tsx +0 -0
  55. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/auth/clerk.tsx +0 -0
  56. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/auth/loader.tsx +0 -0
  57. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/auth/supabase.tsx +0 -0
  58. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/auth/types.ts +0 -0
  59. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/AppHeader.tsx +0 -0
  60. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/FilePanels.tsx +0 -0
  61. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/MessageList.tsx +0 -0
  62. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/SubagentActivity.tsx +0 -0
  63. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/ThreadPicker.tsx +0 -0
  64. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/TodosPanel.tsx +0 -0
  65. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/ToolCallCard.tsx +0 -0
  66. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/toolcalls/FileToolCard.tsx +0 -0
  67. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/toolcalls/SearchCard.tsx +0 -0
  68. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/toolcalls/ThinkCard.tsx +0 -0
  69. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/toolcalls/TodosCard.tsx +0 -0
  70. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/components/toolcalls/index.ts +0 -0
  71. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/constants.ts +0 -0
  72. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/index.css +0 -0
  73. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/main.tsx +0 -0
  74. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/runtimeConfig.ts +0 -0
  75. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/types.ts +0 -0
  76. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/src/vite-env.d.ts +0 -0
  77. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/tsconfig.json +0 -0
  78. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/frontend/vite.config.ts +0 -0
  79. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/images/cli.png +0 -0
  80. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/scripts/check_imports.py +0 -0
  81. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/scripts/debug_server.sh +0 -0
  82. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/scripts/install.sh +0 -0
  83. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/README.md +0 -0
  84. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/integration_tests/__init__.py +0 -0
  85. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/integration_tests/conftest.py +0 -0
  86. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/integration_tests/test_context_hub.py +0 -0
  87. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/integration_tests/test_deploy_hub.py +0 -0
  88. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/__init__.py +0 -0
  89. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/conftest.py +0 -0
  90. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/__init__.py +0 -0
  91. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_commands.py +0 -0
  92. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_config.py +0 -0
  93. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_context_hub.py +0 -0
  94. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_frontend_bundle.py +0 -0
  95. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/deploy/test_frontend_config.py +0 -0
  96. {deepagents_cli-0.1.1 → deepagents_cli-0.1.2}/tests/unit_tests/test_version.py +0 -0
@@ -138,6 +138,8 @@ celerybeat.pid
138
138
  # Environments
139
139
  .env
140
140
  .envrc
141
+ env.local
142
+ *.env.local
141
143
  .venv
142
144
  env/
143
145
  venv/
@@ -3,6 +3,12 @@
3
3
  From 0.1.0 onward, `deepagents-cli` only contains `deploy`, `dev`, and `init`.
4
4
  The coding agent (interactive TUI & headless CLI) moved to [`deepagents-code`](https://github.com/langchain-ai/deepagents/blob/main/libs/code/CHANGELOG.md).
5
5
 
6
+ ## [0.1.2](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.1.1...deepagents-cli==0.1.2) (2026-05-21)
7
+
8
+ ### Bug Fixes
9
+
10
+ * Expand `${VAR}` in `mcp.json` header values ([#3523](https://github.com/langchain-ai/deepagents/issues/3523)) ([6cfc5f9](https://github.com/langchain-ai/deepagents/commit/6cfc5f9004271c23c486a0b05e8f9f0002e75e2b))
11
+
6
12
  ## [0.1.1](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.1.0...deepagents-cli==0.1.1) (2026-05-18)
7
13
 
8
14
  ### Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-cli
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Deployment tooling for Deep Agents - bundle, run, and ship agents to LangGraph Platform.
5
5
  Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
@@ -55,6 +55,14 @@ Description-Content-Type: text/markdown
55
55
  [![PyPI - Downloads](https://img.shields.io/pepy/dt/deepagents-cli)](https://pypistats.org/packages/deepagents-cli)
56
56
  [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/langchain_oss.svg?style=social&label=Follow%20%40LangChain)](https://x.com/langchain_oss)
57
57
 
58
+ > [!IMPORTANT]
59
+ > **The interactive coding agent moved.** As of `deepagents-cli==0.1.0`, this package contains only the deployment subcommands (`init`, `dev`, `deploy`). The interactive REPL — previously launched via `deepagents` — now ships as [`deepagents-code`](https://docs.langchain.com/oss/python/deepagents/code/overview) (`dcode`).
60
+ >
61
+ > ```bash
62
+ > curl -LsSf https://langch.in/dcode | bash
63
+ > dcode
64
+ > ```
65
+
58
66
  ## Install
59
67
 
60
68
  ```bash
@@ -5,6 +5,14 @@
5
5
  [![PyPI - Downloads](https://img.shields.io/pepy/dt/deepagents-cli)](https://pypistats.org/packages/deepagents-cli)
6
6
  [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/langchain_oss.svg?style=social&label=Follow%20%40LangChain)](https://x.com/langchain_oss)
7
7
 
8
+ > [!IMPORTANT]
9
+ > **The interactive coding agent moved.** As of `deepagents-cli==0.1.0`, this package contains only the deployment subcommands (`init`, `dev`, `deploy`). The interactive REPL — previously launched via `deepagents` — now ships as [`deepagents-code`](https://docs.langchain.com/oss/python/deepagents/code/overview) (`dcode`).
10
+ >
11
+ > ```bash
12
+ > curl -LsSf https://langch.in/dcode | bash
13
+ > dcode
14
+ > ```
15
+
8
16
  ## Install
9
17
 
10
18
  ```bash
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Keep the `x-release-please-version` annotation — release-please uses it to
4
4
  # bump `__version__` in sync with `pyproject.toml` on every release PR.
5
- __version__ = "0.1.1" # x-release-please-version
5
+ __version__ = "0.1.2" # x-release-please-version
6
6
 
7
7
  DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/cli"
8
8
  """URL for `deepagents-cli` documentation."""
@@ -409,10 +409,28 @@ AUTH_BLOCKS: dict[str, tuple[str, str | None]] = {
409
409
 
410
410
  MCP_TOOLS_TEMPLATE = '''\
411
411
  async def _load_mcp_tools():
412
- """Load MCP tools from bundled config (http/sse only)."""
412
+ """Load MCP tools from bundled config (http/sse only).
413
+
414
+ The `url` and `headers` values support `${VAR}` references which are
415
+ expanded against `os.environ` when the deployed graph loads. This
416
+ mirrors the substitution behavior documented for `deepagents-code`'s
417
+ `.mcp.json` (https://docs.langchain.com/oss/python/deepagents/code/mcp-tools).
418
+ Unset variables are left as the literal `${VAR}` so the resulting auth
419
+ failure surfaces a recognizable token rather than an empty header.
420
+ """
413
421
  import json
422
+ import os
423
+ import re
414
424
  from pathlib import Path
415
425
 
426
+ def _expand(value):
427
+ """Expand `${VAR}` references in strings; pass other types through."""
428
+ if isinstance(value, str):
429
+ return os.path.expandvars(value)
430
+ return value
431
+
432
+ unresolved_re = re.compile(r"\\$\\{[^}]+\\}")
433
+
416
434
  mcp_path = Path(__file__).parent / "_mcp.json"
417
435
  if not mcp_path.exists():
418
436
  return []
@@ -428,9 +446,23 @@ async def _load_mcp_tools():
428
446
  for name, cfg in servers.items():
429
447
  transport = cfg.get("type", cfg.get("transport", "stdio"))
430
448
  if transport in ("http", "sse"):
431
- conn = {"transport": transport, "url": cfg["url"]}
449
+ conn = {"transport": transport, "url": _expand(cfg["url"])}
432
450
  if "headers" in cfg:
433
- conn["headers"] = cfg["headers"]
451
+ conn["headers"] = {
452
+ k: _expand(v) for k, v in cfg["headers"].items()
453
+ }
454
+ unresolved = sorted({
455
+ match
456
+ for value in (conn["url"], *conn.get("headers", {}).values())
457
+ if isinstance(value, str)
458
+ for match in unresolved_re.findall(value)
459
+ })
460
+ if unresolved:
461
+ logger.warning(
462
+ "MCP server %r has unresolved environment reference(s): %s",
463
+ name,
464
+ ", ".join(unresolved),
465
+ )
434
466
  connections[name] = conn
435
467
 
436
468
  if not connections:
@@ -441,11 +473,10 @@ async def _load_mcp_tools():
441
473
 
442
474
  client = MultiServerMCPClient(connections)
443
475
  return await client.get_tools()
444
- except Exception as exc: # noqa: BLE001
445
- logger.warning(
446
- "Failed to load MCP tools from %d server(s): %s",
476
+ except Exception:
477
+ logger.exception(
478
+ "Failed to load MCP tools from %d server(s)",
447
479
  len(connections),
448
- exc,
449
480
  )
450
481
  return []
451
482
  '''
@@ -6091,9 +6091,9 @@
6091
6091
  }
6092
6092
  },
6093
6093
  "node_modules/ws": {
6094
- "version": "8.20.0",
6095
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz",
6096
- "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==",
6094
+ "version": "8.20.1",
6095
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz",
6096
+ "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==",
6097
6097
  "license": "MIT",
6098
6098
  "engines": {
6099
6099
  "node": ">=10.0.0"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "deepagents-cli"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Deployment tooling for Deep Agents - bundle, run, and ship agents to LangGraph Platform."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -2,7 +2,11 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import asyncio
5
6
  import json
7
+ import logging
8
+ import sys
9
+ import types
6
10
  from typing import TYPE_CHECKING
7
11
 
8
12
  import pytest
@@ -207,6 +211,87 @@ class TestRenderDeployGraph:
207
211
  assert "_load_mcp_tools" not in result
208
212
  assert "pass # no MCP servers configured" in result
209
213
 
214
+ def test_mcp_loader_expands_env_vars(
215
+ self,
216
+ tmp_path: Path,
217
+ monkeypatch: pytest.MonkeyPatch,
218
+ caplog: pytest.LogCaptureFixture,
219
+ ) -> None:
220
+ """Emitted loader expands `${VAR}` in url + headers before MCP connect.
221
+
222
+ Mirrors the `${VAR}` substitution behavior of `deepagents-code`'s
223
+ `.mcp.json`. Without this, headers like
224
+ `Authorization: Bearer ${TOKEN}` reach MCP servers as the literal
225
+ string and auth fails silently.
226
+
227
+ Also verifies the documented contracts: unset references are left as
228
+ literal `${VAR}` so a recognizable token surfaces, non-string header
229
+ values pass through unchanged, and unresolved tokens emit a warning.
230
+ """
231
+ from deepagents_cli.deploy.templates import MCP_TOOLS_TEMPLATE
232
+
233
+ captured: dict[str, dict] = {}
234
+
235
+ class _FakeClient:
236
+ def __init__(self, connections: dict) -> None:
237
+ captured["connections"] = connections
238
+
239
+ async def get_tools(self) -> list:
240
+ return []
241
+
242
+ fake_root = types.ModuleType("langchain_mcp_adapters")
243
+ fake_client = types.ModuleType("langchain_mcp_adapters.client")
244
+ fake_client.MultiServerMCPClient = _FakeClient # type: ignore[attr-defined]
245
+ monkeypatch.setitem(sys.modules, "langchain_mcp_adapters", fake_root)
246
+ monkeypatch.setitem(sys.modules, "langchain_mcp_adapters.client", fake_client)
247
+
248
+ (tmp_path / "_mcp.json").write_text(
249
+ json.dumps(
250
+ {
251
+ "mcpServers": {
252
+ "primary": {
253
+ "type": "http",
254
+ "url": "https://api.example.com/${ENDPOINT}",
255
+ "headers": {
256
+ "Authorization": "Bearer ${TOKEN}",
257
+ "X-Unset": "value-${MISSING_VAR}",
258
+ "X-Numeric": 42,
259
+ },
260
+ },
261
+ },
262
+ },
263
+ ),
264
+ encoding="utf-8",
265
+ )
266
+
267
+ monkeypatch.setenv("ENDPOINT", "v1/chat")
268
+ monkeypatch.setenv("TOKEN", "secret-abc")
269
+ monkeypatch.delenv("MISSING_VAR", raising=False)
270
+
271
+ loader_logger = logging.getLogger("test_mcp_loader")
272
+ namespace: dict = {
273
+ "__file__": str(tmp_path / "graph.py"),
274
+ "logger": loader_logger,
275
+ }
276
+ exec(
277
+ compile(MCP_TOOLS_TEMPLATE, "<MCP_TOOLS_TEMPLATE>", "exec"),
278
+ namespace,
279
+ )
280
+
281
+ with caplog.at_level(logging.WARNING, logger="test_mcp_loader"):
282
+ asyncio.run(namespace["_load_mcp_tools"]())
283
+
284
+ conn = captured["connections"]["primary"]
285
+ assert conn["url"] == "https://api.example.com/v1/chat"
286
+ assert conn["headers"]["Authorization"] == "Bearer secret-abc"
287
+ assert conn["headers"]["X-Unset"] == "value-${MISSING_VAR}"
288
+ assert conn["headers"]["X-Numeric"] == 42
289
+ assert any(
290
+ "unresolved environment reference" in rec.getMessage()
291
+ and "${MISSING_VAR}" in rec.getMessage()
292
+ for rec in caplog.records
293
+ )
294
+
210
295
  def test_no_system_prompt_in_output(self) -> None:
211
296
  """AGENTS.md should not be baked into the deploy graph as a system prompt."""
212
297
  config = _minimal_config()
@@ -792,7 +792,7 @@ wheels = [
792
792
 
793
793
  [[package]]
794
794
  name = "deepagents"
795
- version = "0.6.1"
795
+ version = "0.6.3"
796
796
  source = { editable = "../deepagents" }
797
797
  dependencies = [
798
798
  { name = "langchain" },
@@ -836,7 +836,7 @@ test = [
836
836
 
837
837
  [[package]]
838
838
  name = "deepagents-cli"
839
- version = "0.1.1"
839
+ version = "0.1.2"
840
840
  source = { editable = "." }
841
841
  dependencies = [
842
842
  { name = "deepagents" },
@@ -1399,11 +1399,11 @@ wheels = [
1399
1399
 
1400
1400
  [[package]]
1401
1401
  name = "idna"
1402
- version = "3.11"
1402
+ version = "3.15"
1403
1403
  source = { registry = "https://pypi.org/simple" }
1404
- sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
1404
+ sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" }
1405
1405
  wheels = [
1406
- { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
1406
+ { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" },
1407
1407
  ]
1408
1408
 
1409
1409
  [[package]]
File without changes
File without changes