deepagents-cli 0.0.45__tar.gz → 0.0.46__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 (277) hide show
  1. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/CHANGELOG.md +7 -0
  2. deepagents_cli-0.0.46/DEV.md +92 -0
  3. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/PKG-INFO +1 -1
  4. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_debug.py +3 -3
  5. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_env_vars.py +38 -1
  6. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_version.py +1 -1
  7. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/app.py +73 -4
  8. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/main.py +45 -15
  9. deepagents_cli-0.0.46/deepagents_cli/mcp_auth.py +704 -0
  10. deepagents_cli-0.0.46/deepagents_cli/mcp_commands.py +202 -0
  11. deepagents_cli-0.0.46/deepagents_cli/mcp_providers/__init__.py +23 -0
  12. deepagents_cli-0.0.46/deepagents_cli/mcp_providers/_registry.py +39 -0
  13. deepagents_cli-0.0.46/deepagents_cli/mcp_providers/base.py +99 -0
  14. deepagents_cli-0.0.46/deepagents_cli/mcp_providers/github.py +91 -0
  15. deepagents_cli-0.0.46/deepagents_cli/mcp_providers/slack.py +130 -0
  16. deepagents_cli-0.0.46/deepagents_cli/mcp_tools.py +1521 -0
  17. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/server.py +20 -3
  18. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/server_graph.py +25 -2
  19. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/server_manager.py +64 -1
  20. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/ui.py +35 -0
  21. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/mcp_viewer.py +159 -89
  22. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/welcome.py +44 -1
  23. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/pyproject.toml +7 -1
  24. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_agent_friendly.py +8 -0
  25. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_app.py +57 -6
  26. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_args.py +74 -1
  27. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_env_vars.py +45 -0
  28. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_local_context.py +3 -1
  29. deepagents_cli-0.0.46/tests/unit_tests/test_mcp_auth.py +957 -0
  30. deepagents_cli-0.0.46/tests/unit_tests/test_mcp_commands.py +332 -0
  31. deepagents_cli-0.0.46/tests/unit_tests/test_mcp_tools.py +2264 -0
  32. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_mcp_viewer.py +14 -6
  33. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_server_graph.py +13 -6
  34. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_server_manager.py +60 -0
  35. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/uv.lock +1 -1
  36. deepagents_cli-0.0.45/DEV.md +0 -52
  37. deepagents_cli-0.0.45/deepagents_cli/mcp_tools.py +0 -712
  38. deepagents_cli-0.0.45/tests/unit_tests/test_mcp_tools.py +0 -1804
  39. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/.gitignore +0 -0
  40. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/Makefile +0 -0
  41. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/README.md +0 -0
  42. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/THREAT_MODEL.md +0 -0
  43. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/__init__.py +0 -0
  44. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/__main__.py +0 -0
  45. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_ask_user_types.py +0 -0
  46. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_cli_context.py +0 -0
  47. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_git.py +0 -0
  48. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_server_config.py +0 -0
  49. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_session_stats.py +0 -0
  50. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_testing_models.py +0 -0
  51. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/_textual_patches.py +0 -0
  52. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/agent.py +0 -0
  53. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/app.tcss +0 -0
  54. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/ask_user.py +0 -0
  55. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/built_in_skills/__init__.py +0 -0
  56. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/built_in_skills/remember/SKILL.md +0 -0
  57. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/built_in_skills/skill-creator/SKILL.md +0 -0
  58. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/built_in_skills/skill-creator/scripts/init_skill.py +0 -0
  59. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/built_in_skills/skill-creator/scripts/quick_validate.py +0 -0
  60. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/clipboard.py +0 -0
  61. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/command_registry.py +0 -0
  62. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/config.py +0 -0
  63. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/configurable_model.py +0 -0
  64. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/default_agent_prompt.md +0 -0
  65. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/__init__.py +0 -0
  66. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/bundler.py +0 -0
  67. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/commands.py +0 -0
  68. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/config.py +0 -0
  69. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/anonymous-B9UzAXQd.js +0 -0
  70. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/clerk-5xHgyQyG.js +0 -0
  71. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/highlighted-body-OFNGDK62-rX-7qT8o.js +0 -0
  72. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/index-DM3gptpu.js +0 -0
  73. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/index-Ddy7F6KI.css +0 -0
  74. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/assets/supabase-S6NACDgm.js +0 -0
  75. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/index.html +0 -0
  76. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/logo-dark.svg +0 -0
  77. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/frontend_dist/logo-light.svg +0 -0
  78. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/deploy/templates.py +0 -0
  79. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/editor.py +0 -0
  80. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/extras_info.py +0 -0
  81. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/file_ops.py +0 -0
  82. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/formatting.py +0 -0
  83. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/hooks.py +0 -0
  84. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/input.py +0 -0
  85. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/integrations/__init__.py +0 -0
  86. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/integrations/sandbox_factory.py +0 -0
  87. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/integrations/sandbox_provider.py +0 -0
  88. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/local_context.py +0 -0
  89. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/mcp_trust.py +0 -0
  90. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/media_utils.py +0 -0
  91. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/model_config.py +0 -0
  92. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/non_interactive.py +0 -0
  93. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/notifications.py +0 -0
  94. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/offload.py +0 -0
  95. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/output.py +0 -0
  96. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/project_utils.py +0 -0
  97. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/py.typed +0 -0
  98. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/remote_client.py +0 -0
  99. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/sessions.py +0 -0
  100. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/skills/__init__.py +0 -0
  101. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/skills/commands.py +0 -0
  102. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/skills/invocation.py +0 -0
  103. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/skills/load.py +0 -0
  104. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/subagents.py +0 -0
  105. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/system_prompt.md +0 -0
  106. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/terminal_capabilities.py +0 -0
  107. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/textual_adapter.py +0 -0
  108. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/theme.py +0 -0
  109. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/token_state.py +0 -0
  110. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/tool_display.py +0 -0
  111. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/tools.py +0 -0
  112. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/unicode_security.py +0 -0
  113. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/update_check.py +0 -0
  114. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/__init__.py +0 -0
  115. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/_links.py +0 -0
  116. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/agent_selector.py +0 -0
  117. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/approval.py +0 -0
  118. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/ask_user.py +0 -0
  119. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/autocomplete.py +0 -0
  120. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/chat_input.py +0 -0
  121. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/diff.py +0 -0
  122. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/history.py +0 -0
  123. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/loading.py +0 -0
  124. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/message_store.py +0 -0
  125. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/messages.py +0 -0
  126. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/model_selector.py +0 -0
  127. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/notification_center.py +0 -0
  128. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/notification_detail.py +0 -0
  129. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/notification_settings.py +0 -0
  130. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/status.py +0 -0
  131. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/theme_selector.py +0 -0
  132. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/thread_selector.py +0 -0
  133. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/tool_renderers.py +0 -0
  134. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/tool_widgets.py +0 -0
  135. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/deepagents_cli/widgets/update_available.py +0 -0
  136. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/deploy-content-writer/.env.example +0 -0
  137. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/deploy-content-writer/skills/blog-post/SKILL.md +0 -0
  138. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/deploy-content-writer/skills/social-media/SKILL.md +0 -0
  139. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/deploy-content-writer/user/context.md +0 -0
  140. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/deploy-content-writer/user/preferences.md +0 -0
  141. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/arxiv-search/SKILL.md +0 -0
  142. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/arxiv-search/arxiv_search.py +0 -0
  143. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/langgraph-docs/SKILL.md +0 -0
  144. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/skill-creator/SKILL.md +0 -0
  145. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/skill-creator/scripts/init_skill.py +0 -0
  146. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/skill-creator/scripts/quick_validate.py +0 -0
  147. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/examples/skills/web-research/SKILL.md +0 -0
  148. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/.nvmrc +0 -0
  149. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/index.html +0 -0
  150. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/package-lock.json +0 -0
  151. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/package.json +0 -0
  152. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/postcss.config.js +0 -0
  153. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/public/logo-dark.svg +0 -0
  154. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/public/logo-light.svg +0 -0
  155. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/App.tsx +0 -0
  156. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/ThemeProvider.tsx +0 -0
  157. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/auth/anonymous.tsx +0 -0
  158. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/auth/clerk.tsx +0 -0
  159. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/auth/loader.tsx +0 -0
  160. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/auth/supabase.tsx +0 -0
  161. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/auth/types.ts +0 -0
  162. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/AppHeader.tsx +0 -0
  163. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/FilePanels.tsx +0 -0
  164. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/MessageList.tsx +0 -0
  165. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/SubagentActivity.tsx +0 -0
  166. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/ThreadPicker.tsx +0 -0
  167. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/TodosPanel.tsx +0 -0
  168. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/ToolCallCard.tsx +0 -0
  169. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/toolcalls/FileToolCard.tsx +0 -0
  170. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/toolcalls/SearchCard.tsx +0 -0
  171. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/toolcalls/ThinkCard.tsx +0 -0
  172. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/toolcalls/TodosCard.tsx +0 -0
  173. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/components/toolcalls/index.ts +0 -0
  174. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/constants.ts +0 -0
  175. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/index.css +0 -0
  176. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/main.tsx +0 -0
  177. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/runtimeConfig.ts +0 -0
  178. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/types.ts +0 -0
  179. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/src/vite-env.d.ts +0 -0
  180. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/tsconfig.json +0 -0
  181. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/frontend/vite.config.ts +0 -0
  182. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/images/cli.png +0 -0
  183. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/scripts/check_imports.py +0 -0
  184. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/scripts/debug_server.sh +0 -0
  185. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/scripts/install.sh +0 -0
  186. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/README.md +0 -0
  187. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/__init__.py +0 -0
  188. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/benchmarks/__init__.py +0 -0
  189. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/benchmarks/test_codspeed_import_benchmarks.py +0 -0
  190. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/benchmarks/test_startup_benchmarks.py +0 -0
  191. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/conftest.py +0 -0
  192. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/test_acp_mode.py +0 -0
  193. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/test_compact_resume.py +0 -0
  194. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/test_sandbox_factory.py +0 -0
  195. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/integration_tests/test_sandbox_operations.py +0 -0
  196. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/__init__.py +0 -0
  197. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/conftest.py +0 -0
  198. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/__init__.py +0 -0
  199. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/test_bundler.py +0 -0
  200. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/test_commands.py +0 -0
  201. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/test_config.py +0 -0
  202. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/test_frontend_bundle.py +0 -0
  203. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/deploy/test_frontend_config.py +0 -0
  204. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/skills/__init__.py +0 -0
  205. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/skills/test_commands.py +0 -0
  206. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/skills/test_load.py +0 -0
  207. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/skills/test_skills_json.py +0 -0
  208. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_agent.py +0 -0
  209. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_agent_selector.py +0 -0
  210. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_approval.py +0 -0
  211. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_ask_user.py +0 -0
  212. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_ask_user_middleware.py +0 -0
  213. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_autocomplete.py +0 -0
  214. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_charset.py +0 -0
  215. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_chat_input.py +0 -0
  216. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_command_registry.py +0 -0
  217. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_compact_tool.py +0 -0
  218. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_config.py +0 -0
  219. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_configurable_model.py +0 -0
  220. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_debug.py +0 -0
  221. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_editor.py +0 -0
  222. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_end_to_end.py +0 -0
  223. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_exception_handling.py +0 -0
  224. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_extras_info.py +0 -0
  225. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_file_ops.py +0 -0
  226. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_formatting.py +0 -0
  227. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_git.py +0 -0
  228. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_history.py +0 -0
  229. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_hooks.py +0 -0
  230. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_imports.py +0 -0
  231. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_input_parsing.py +0 -0
  232. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_links.py +0 -0
  233. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_loading.py +0 -0
  234. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_main.py +0 -0
  235. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_main_acp_mode.py +0 -0
  236. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_main_args.py +0 -0
  237. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_mcp_trust.py +0 -0
  238. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_media_utils.py +0 -0
  239. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_message_store.py +0 -0
  240. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_messages.py +0 -0
  241. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_model_config.py +0 -0
  242. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_model_selector.py +0 -0
  243. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_model_switch.py +0 -0
  244. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_non_interactive.py +0 -0
  245. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_notification_center.py +0 -0
  246. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_notification_detail.py +0 -0
  247. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_notifications.py +0 -0
  248. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_offload.py +0 -0
  249. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_offload_dict_messages.py +0 -0
  250. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_output.py +0 -0
  251. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_reload.py +0 -0
  252. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_remote_client.py +0 -0
  253. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_sandbox_factory.py +0 -0
  254. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_server.py +0 -0
  255. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_server_config.py +0 -0
  256. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_server_helpers.py +0 -0
  257. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_session_stats.py +0 -0
  258. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_sessions.py +0 -0
  259. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_shell_allow_list.py +0 -0
  260. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_skill_invocation.py +0 -0
  261. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_status.py +0 -0
  262. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_subagents.py +0 -0
  263. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_terminal_capabilities.py +0 -0
  264. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_textual_adapter.py +0 -0
  265. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_textual_patches.py +0 -0
  266. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_theme.py +0 -0
  267. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_thread_selector.py +0 -0
  268. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_token_tracker.py +0 -0
  269. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_tool_display.py +0 -0
  270. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_ui.py +0 -0
  271. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_unicode_security.py +0 -0
  272. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_update_available.py +0 -0
  273. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_update_check.py +0 -0
  274. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_version.py +0 -0
  275. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/test_welcome.py +0 -0
  276. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/tools/__init__.py +0 -0
  277. {deepagents_cli-0.0.45 → deepagents_cli-0.0.46}/tests/unit_tests/tools/test_fetch_url.py +0 -0
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.0.46](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.45...deepagents-cli==0.0.46) (2026-04-30)
4
+
5
+ ### Features
6
+
7
+ * Rework MCP integration and add OAuth login ([#2906](https://github.com/langchain-ai/deepagents/issues/2906)) ([6b7b0be](https://github.com/langchain-ai/deepagents/commit/6b7b0bef95db673fed23fc92803abaaa398b0a6d))
8
+ * `allowedTools` and `disabledTools` filters in MCP config ([#2835](https://github.com/langchain-ai/deepagents/issues/2835)) ([eafd691](https://github.com/langchain-ai/deepagents/commit/eafd6912db637ab59085a0b05d6e36d6cdd10e1a))
9
+
3
10
  ## [0.0.45](https://github.com/langchain-ai/deepagents/compare/deepagents-cli==0.0.44...deepagents-cli==0.0.45) (2026-04-30)
4
11
 
5
12
  ### Bug Fixes
@@ -0,0 +1,92 @@
1
+ # CLI Development Guide
2
+
3
+ ## Live CSS development with Textual devtools
4
+
5
+ Textual's devtools console enables CSS hot-reload and live `self.log()` output during development.
6
+
7
+ ### Prerequisites
8
+
9
+ Sync the `test` dependency group (includes `textual-dev`):
10
+
11
+ ```bash
12
+ cd libs/cli && uv sync --group test
13
+ ```
14
+
15
+ Create the dev wrapper script (one-time):
16
+
17
+ ```bash
18
+ cat > /tmp/dev_deepagents.py << 'PYEOF'
19
+ """Dev wrapper to run Deep Agents CLI with textual devtools."""
20
+ import sys
21
+ sys.argv = ["deepagents"] + sys.argv[1:]
22
+
23
+ from deepagents_cli.main import cli_main
24
+ cli_main()
25
+ PYEOF
26
+ ```
27
+
28
+ ### Running
29
+
30
+ **Terminal 1** — devtools console:
31
+
32
+ ```bash
33
+ cd libs/cli && uv run --group test textual console
34
+ ```
35
+
36
+ **Terminal 2** — CLI with live reload:
37
+
38
+ ```bash
39
+ cd libs/cli && uv run --group test textual run --dev /tmp/dev_deepagents.py
40
+ ```
41
+
42
+ Edit any `.tcss` file and save — changes appear immediately. Any `self.log()` calls in widget code show in the console.
43
+
44
+ ### Console options
45
+
46
+ - `textual console -v` — verbose mode, shows all events (key presses, mouse, etc.)
47
+ - `textual console -x EVENT` — exclude noisy event groups
48
+ - `textual console --port 7342` — custom port (pass matching `--port` to `textual run`)
49
+
50
+ ### Why the wrapper script?
51
+
52
+ `textual run --dev` handles the devtools connection, but it needs to run inside the project's virtualenv to import `deepagents_cli`. The wrapper script bridges the gap — `uv run --group test textual run --dev` ensures both `textual-dev` (from the `test` group) and `deepagents_cli` are available in the same environment.
53
+
54
+ ## Debugging
55
+
56
+ The CLI runs a `langgraph dev` subprocess for every interactive session. When the subprocess crashes during startup, the TUI shows a one-line failure banner; the actual exception lives in the subprocess's stdout/stderr, which is captured to a temp file.
57
+
58
+ ### Environment variables
59
+
60
+ | Variable | Effect |
61
+ | --- | --- |
62
+ | `DEEPAGENTS_CLI_DEBUG=1` | Preserves the server subprocess log on shutdown and prints its path to stderr. Without this, the log is deleted when the process stops. Also enables the CLI-process file handler below. Accepts `1`/`true`/`yes`/`on` (case-insensitive) as enabled; `0`/`false`/`no`/`off`/empty/unset as disabled. |
63
+ | `DEEPAGENTS_CLI_DEBUG_FILE=<path>` | Overrides the default path (`/tmp/deepagents_debug.log`) for the CLI-process file handler, which attaches at `DEBUG` level to `textual_adapter` and `remote_client`. **Only takes effect when `DEEPAGENTS_CLI_DEBUG` is truthy.** Useful for diagnosing streaming/client-side issues; does **not** capture the server subprocess. |
64
+
65
+ `DEEPAGENTS_CLI_DEBUG` is what you want for startup crashes (graph init, MCP config, sandbox): the preserved subprocess log contains the real traceback. The optional `DEEPAGENTS_CLI_DEBUG_FILE` override is for post-startup client-side debugging.
66
+
67
+ ### Finding the server subprocess log
68
+
69
+ On macOS, `tempfile` resolves to `$TMPDIR` (a path under `/var/folders/.../T/`). Each `ServerProcess` writes its combined stdout+stderr to a file matching `deepagents_server_log_*.txt`:
70
+
71
+ ```bash
72
+ # Newest first
73
+ ls -lt ${TMPDIR:-/tmp}/deepagents_server_log_*.txt | head -5
74
+
75
+ # Tail the latest while reproducing the crash
76
+ tail -F "$(ls -t ${TMPDIR:-/tmp}/deepagents_server_log_*.txt | head -1)"
77
+ ```
78
+
79
+ The interesting line is `Failed to initialize server graph: <exc>` followed by a traceback — everything above that is uvicorn/lifespan unwinding.
80
+
81
+ ### Triage flow for a startup crash
82
+
83
+ 1. **Rerun with `DEEPAGENTS_CLI_DEBUG=1`.** The log is preserved and a "Server log preserved at: ..." line is printed to stderr. Textual's fullscreen mode can hide that line, but the file itself is still on disk.
84
+ 2. **Locate the log** via the `ls` command above. Open it in your editor.
85
+ 3. **Search for `Failed to initialize server graph`.** The stack trace beneath names the concrete failure point (MCP config validation, sandbox init, model resolution, subagent load, etc.).
86
+ 4. **Pre-flight validators run in the CLI process** for the common failure modes (e.g., `--mcp-config` is validated in `start_server_and_get_agent` before the subprocess spawns). When the banner shows `MCPConfigError: <path>: <reason>`, the subprocess never started — fix the file and retry.
87
+
88
+ ### Common startup failure patterns
89
+
90
+ - **`MCPConfigError: Invalid MCP config at <path>: ...`** — malformed `--mcp-config`. The pre-flight wraps the underlying `ValueError`/`TypeError` with the offending path. See `_preflight_validate_mcp_config` in `server_manager.py`.
91
+ - **`Server 'X' missing required 'command' field`** (from a discovered project `.mcp.json`, not `--mcp-config`) — an stdio server config without `command`. For remote servers, just use `{"url": "..."}`; transport is inferred as `http` when no `type`/`transport` is present.
92
+ - **Uncaught exception inside a bare `sys.exit(1)`** — usually means the surrounding `make_graph()` raised. Look one traceback up in the subprocess log for the real cause.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepagents-cli
3
- Version: 0.0.45
3
+ Version: 0.0.46
4
4
  Summary: Terminal interface for Deep Agents - interactive AI agent with file operations, shell access, and sub-agent capabilities.
5
5
  Project-URL: Homepage, https://docs.langchain.com/oss/python/deepagents/overview
6
6
  Project-URL: Documentation, https://reference.langchain.com/python/deepagents/
@@ -12,7 +12,7 @@ import logging
12
12
  import os
13
13
  from pathlib import Path
14
14
 
15
- from deepagents_cli._env_vars import DEBUG, DEBUG_FILE
15
+ from deepagents_cli._env_vars import DEBUG, DEBUG_FILE, is_env_truthy
16
16
 
17
17
 
18
18
  def configure_debug_logging(target: logging.Logger) -> None:
@@ -22,12 +22,12 @@ def configure_debug_logging(target: logging.Logger) -> None:
22
22
  with `DEEPAGENTS_CLI_DEBUG_FILE`. The handler appends so that multiple
23
23
  modules share the same log file across a session.
24
24
 
25
- Does nothing when `DEEPAGENTS_CLI_DEBUG` is not set.
25
+ Does nothing when `DEEPAGENTS_CLI_DEBUG` is not truthy (see `is_env_truthy`).
26
26
 
27
27
  Args:
28
28
  target: Logger to configure.
29
29
  """
30
- if not os.environ.get(DEBUG):
30
+ if not is_env_truthy(DEBUG):
31
31
  return
32
32
 
33
33
  debug_path = Path(
@@ -23,6 +23,8 @@ ever renamed, only the value here changes.
23
23
 
24
24
  from __future__ import annotations
25
25
 
26
+ import os
27
+
26
28
  # ---------------------------------------------------------------------------
27
29
  # Constants — import these instead of bare string literals.
28
30
  # Keep alphabetically sorted by constant name.
@@ -32,7 +34,10 @@ AUTO_UPDATE = "DEEPAGENTS_CLI_AUTO_UPDATE"
32
34
  """Enable automatic CLI updates ('1', 'true', or 'yes')."""
33
35
 
34
36
  DEBUG = "DEEPAGENTS_CLI_DEBUG"
35
- """Enable verbose debug logging to a file."""
37
+ """Enable verbose debug logging and preserve the server subprocess log.
38
+
39
+ Parsed by `is_env_truthy`: accepts `1`, `true`, `yes`, `on` (case-insensitive)
40
+ as enabled, and `0`, `false`, `no`, `off`, empty string, or unset as disabled."""
36
41
 
37
42
  DEBUG_FILE = "DEEPAGENTS_CLI_DEBUG_FILE"
38
43
  """Path for the debug log file (default: `/tmp/deepagents_debug.log`)."""
@@ -69,3 +74,35 @@ SHELL_ALLOW_LIST = "DEEPAGENTS_CLI_SHELL_ALLOW_LIST"
69
74
 
70
75
  USER_ID = "DEEPAGENTS_CLI_USER_ID"
71
76
  """Attach a user identifier to LangSmith trace metadata."""
77
+
78
+
79
+ _TRUTHY_VALUES = frozenset({"1", "true", "yes", "on"})
80
+ _FALSY_VALUES = frozenset({"0", "false", "no", "off", ""})
81
+
82
+
83
+ def is_env_truthy(name: str, *, default: bool = False) -> bool:
84
+ """Return whether env var *name* is set to a recognizably truthy value.
85
+
86
+ Unlike `bool(os.environ.get(name))`, this does not treat `"0"` or
87
+ `"false"` as enabled. Use this for on/off flags where the user would
88
+ reasonably expect `VAR=0` to mean "disabled".
89
+
90
+ Args:
91
+ name: Environment variable name (typically a `DEEPAGENTS_CLI_*`
92
+ constant from this module).
93
+ default: Value returned when the variable is unset OR set to a
94
+ value that is neither recognizably truthy nor falsy.
95
+
96
+ Returns:
97
+ `True` for `1`/`true`/`yes`/`on` (case-insensitive), `False` for
98
+ `0`/`false`/`no`/`off`/empty string, or `default` otherwise.
99
+ """
100
+ raw = os.environ.get(name)
101
+ if raw is None:
102
+ return default
103
+ lowered = raw.strip().lower()
104
+ if lowered in _TRUTHY_VALUES:
105
+ return True
106
+ if lowered in _FALSY_VALUES:
107
+ return False
108
+ return default
@@ -1,6 +1,6 @@
1
1
  """Version information and lightweight constants for `deepagents-cli`."""
2
2
 
3
- __version__ = "0.0.45" # x-release-please-version
3
+ __version__ = "0.0.46" # x-release-please-version
4
4
 
5
5
  DOCS_URL = "https://docs.langchain.com/oss/python/deepagents/cli"
6
6
  """URL for `deepagents-cli` documentation."""
@@ -428,6 +428,27 @@ def _truncate(text: str, *, limit: int) -> str:
428
428
  return text[: limit - 1].rstrip() + "…"
429
429
 
430
430
 
431
+ def _format_startup_error(error: BaseException) -> str:
432
+ """Format a server-startup exception for the welcome banner.
433
+
434
+ `wait_for_server_healthy` appends a tail of the subprocess log to its
435
+ `RuntimeError` message (see `_LOG_TAIL_CHARS` in `server.py`), which
436
+ would overwhelm the banner. Trim to the headline so the user sees an
437
+ actionable line instead of a scrolling traceback; `DEEPAGENTS_CLI_DEBUG=1`
438
+ preserves the full log on disk for triage.
439
+
440
+ Args:
441
+ error: The exception raised during server startup.
442
+
443
+ Returns:
444
+ A single-line `Type: message` summary suitable for the banner.
445
+ """
446
+ first_line = str(error).splitlines()[0].strip() if str(error) else ""
447
+ if not first_line:
448
+ first_line = error.__class__.__name__
449
+ return f"{type(error).__name__}: {_truncate(first_line, limit=300)}"
450
+
451
+
431
452
  class TextualSessionState:
432
453
  """Session state for the Textual app."""
433
454
 
@@ -755,6 +776,19 @@ class DeepAgentsApp(App):
755
776
  self._mcp_tool_count = sum(len(s.tools) for s in (mcp_server_info or []))
756
777
  """Total tool count across MCP servers, displayed in the status bar."""
757
778
 
779
+ self._mcp_unauthenticated = sum(
780
+ 1 for s in (mcp_server_info or []) if s.status == "unauthenticated"
781
+ )
782
+ """MCP servers awaiting a `deepagents mcp login` run."""
783
+
784
+ self._mcp_errored = sum(
785
+ 1 for s in (mcp_server_info or []) if s.status == "error"
786
+ )
787
+ """MCP servers that failed to load (config or network error)."""
788
+
789
+ self._active_mcp_viewer: Any = None
790
+ """Handle to the `/mcp` modal so server-ready events can refresh it."""
791
+
758
792
  self._profile_override = profile_override
759
793
  """Extra profile fields from `--profile-override`, retained so later
760
794
  profile-aware behavior (model selection, offload budget display,
@@ -1090,6 +1124,8 @@ class DeepAgentsApp(App):
1090
1124
  yield WelcomeBanner(
1091
1125
  thread_id=self._lc_thread_id,
1092
1126
  mcp_tool_count=self._mcp_tool_count,
1127
+ mcp_unauthenticated=self._mcp_unauthenticated,
1128
+ mcp_errored=self._mcp_errored,
1093
1129
  connecting=self._connecting,
1094
1130
  resuming=self._resume_thread_intent is not None,
1095
1131
  local_server=self._server_kwargs is not None,
@@ -1707,14 +1743,28 @@ class DeepAgentsApp(App):
1707
1743
  self._server_proc = event.server_proc
1708
1744
  self._mcp_server_info = event.mcp_server_info
1709
1745
  self._mcp_tool_count = sum(len(s.tools) for s in (event.mcp_server_info or []))
1746
+ self._mcp_unauthenticated = sum(
1747
+ 1 for s in (event.mcp_server_info or []) if s.status == "unauthenticated"
1748
+ )
1749
+ self._mcp_errored = sum(
1750
+ 1 for s in (event.mcp_server_info or []) if s.status == "error"
1751
+ )
1710
1752
 
1711
1753
  # Update welcome banner to show ready state
1712
1754
  try:
1713
1755
  banner = self.query_one("#welcome-banner", WelcomeBanner)
1714
- banner.set_connected(self._mcp_tool_count)
1756
+ banner.set_connected(
1757
+ self._mcp_tool_count,
1758
+ mcp_unauthenticated=self._mcp_unauthenticated,
1759
+ mcp_errored=self._mcp_errored,
1760
+ )
1715
1761
  except NoMatches:
1716
1762
  logger.warning("Welcome banner not found during server ready transition")
1717
1763
 
1764
+ if self._active_mcp_viewer is not None:
1765
+ with suppress(Exception):
1766
+ self._active_mcp_viewer.refresh_server_info(self._mcp_server_info or [])
1767
+
1718
1768
  # Session-start sequence: load resumed history, run `--startup-cmd`
1719
1769
  # (if any), then dispatch the initial prompt/skill and drain
1720
1770
  # user-typed messages. Sequenced through a single task so the
@@ -1746,8 +1796,14 @@ class DeepAgentsApp(App):
1746
1796
 
1747
1797
  def on_deep_agents_app_server_start_failed(self, event: ServerStartFailed) -> None:
1748
1798
  """Handle background server startup failure."""
1799
+ from deepagents_cli.mcp_tools import MCPConfigError
1800
+
1749
1801
  self._connecting = False
1750
- self._server_startup_error = f"{type(event.error).__name__}: {event.error}"
1802
+ if isinstance(event.error, MCPConfigError):
1803
+ # Already carries the path + hint; showing the class name is noise.
1804
+ self._server_startup_error = str(event.error)
1805
+ else:
1806
+ self._server_startup_error = _format_startup_error(event.error)
1751
1807
  logger.error("Server startup failed: %s", event.error, exc_info=event.error)
1752
1808
  # Update banner to show persistent failure state
1753
1809
  try:
@@ -5048,6 +5104,7 @@ class DeepAgentsApp(App):
5048
5104
  bar indicator and session state.
5049
5105
  """
5050
5106
  from deepagents_cli.widgets.agent_selector import AgentSelectorScreen
5107
+ from deepagents_cli.widgets.mcp_viewer import MCPViewerScreen
5051
5108
  from deepagents_cli.widgets.notification_center import (
5052
5109
  NotificationCenterScreen,
5053
5110
  )
@@ -5074,6 +5131,9 @@ class DeepAgentsApp(App):
5074
5131
  ):
5075
5132
  self.screen.action_move_up()
5076
5133
  return
5134
+ if isinstance(self.screen, MCPViewerScreen):
5135
+ self.screen.action_move_up()
5136
+ return
5077
5137
  # shift+tab is reused for navigation inside modal screens (e.g.
5078
5138
  # ModelSelectorScreen); skip the toggle so it doesn't fire through.
5079
5139
  if isinstance(self.screen, ModalScreen):
@@ -5645,7 +5705,11 @@ class DeepAgentsApp(App):
5645
5705
  self._connecting = False
5646
5706
  try:
5647
5707
  banner = self.query_one("#welcome-banner", WelcomeBanner)
5648
- banner.set_connected(self._mcp_tool_count)
5708
+ banner.set_connected(
5709
+ self._mcp_tool_count,
5710
+ mcp_unauthenticated=self._mcp_unauthenticated,
5711
+ mcp_errored=self._mcp_errored,
5712
+ )
5649
5713
  except NoMatches:
5650
5714
  pass
5651
5715
  self.notify(
@@ -6221,9 +6285,14 @@ class DeepAgentsApp(App):
6221
6285
  """Show read-only MCP server/tool viewer as a modal screen."""
6222
6286
  from deepagents_cli.widgets.mcp_viewer import MCPViewerScreen
6223
6287
 
6224
- screen = MCPViewerScreen(server_info=self._mcp_server_info or [])
6288
+ screen = MCPViewerScreen(
6289
+ server_info=self._mcp_server_info or [],
6290
+ connecting=self._connecting,
6291
+ )
6292
+ self._active_mcp_viewer = screen
6225
6293
 
6226
6294
  def handle_result(result: None) -> None: # noqa: ARG001
6295
+ self._active_mcp_viewer = None
6227
6296
  if self._chat_input:
6228
6297
  self._chat_input.focus_input()
6229
6298
 
@@ -388,6 +388,7 @@ def parse_args() -> argparse.Namespace:
388
388
  Parsed arguments namespace.
389
389
  """
390
390
  from deepagents_cli.deploy import setup_deploy_parsers
391
+ from deepagents_cli.mcp_commands import setup_mcp_parsers
391
392
  from deepagents_cli.output import add_json_output_arg
392
393
  from deepagents_cli.skills import setup_skills_parser
393
394
 
@@ -516,6 +517,10 @@ def parse_args() -> argparse.Namespace:
516
517
  subparsers,
517
518
  make_help_action=_make_help_action,
518
519
  )
520
+ setup_mcp_parsers(
521
+ subparsers,
522
+ make_help_action=_make_help_action,
523
+ )
519
524
 
520
525
  threads_parser = subparsers.add_parser(
521
526
  "threads",
@@ -1301,24 +1306,29 @@ def _print_session_stats(stats: Any, console: Any) -> None: # noqa: ANN401
1301
1306
 
1302
1307
 
1303
1308
  def _check_mcp_project_trust(*, trust_flag: bool = False) -> bool | None:
1304
- """Check whether project-level MCP stdio servers should be trusted.
1309
+ """Check whether project-level MCP servers should be trusted.
1310
+
1311
+ Both stdio and remote (http/sse) project entries require approval —
1312
+ remote entries from an attacker-controlled `.mcp.json` can SSRF or
1313
+ exfiltrate environment variables via `${VAR}` interpolation in their
1314
+ `headers`, so they are gated identically to stdio commands.
1305
1315
 
1306
- When the project has no stdio servers in project-level configs, returns
1307
- `None` (no gate needed). When `--trust-project-mcp` was passed, returns
1308
- `True`. Otherwise checks the persistent trust store; if untrusted, shows
1309
- an interactive approval prompt.
1316
+ When the project has no servers in project-level configs, returns
1317
+ `None` (no gate needed). When `--trust-project-mcp` was passed,
1318
+ returns `True`. Otherwise checks the persistent trust store; if
1319
+ untrusted, shows an interactive approval prompt.
1310
1320
 
1311
1321
  Args:
1312
1322
  trust_flag: Whether `--trust-project-mcp` was passed.
1313
1323
 
1314
1324
  Returns:
1315
- `True` to allow project stdio servers, `False` to deny, or `None`
1316
- when no project stdio servers exist.
1325
+ `True` to allow project servers, `False` to deny, or `None`
1326
+ when no project servers exist.
1317
1327
  """
1318
1328
  from deepagents_cli.mcp_tools import (
1319
1329
  classify_discovered_configs,
1320
1330
  discover_mcp_configs,
1321
- extract_stdio_server_commands,
1331
+ extract_project_server_summaries,
1322
1332
  load_mcp_config_lenient,
1323
1333
  )
1324
1334
  from deepagents_cli.project_utils import ProjectContext
@@ -1333,14 +1343,14 @@ def _check_mcp_project_trust(*, trust_flag: bool = False) -> bool | None:
1333
1343
  if not project_configs:
1334
1344
  return None
1335
1345
 
1336
- # Collect all stdio servers across project configs
1337
- all_stdio: list[tuple[str, str, list[str]]] = []
1346
+ # Collect all servers (stdio + remote) across project configs
1347
+ all_servers: list[tuple[str, str, str]] = []
1338
1348
  for path in project_configs:
1339
1349
  cfg = load_mcp_config_lenient(path)
1340
1350
  if cfg is not None:
1341
- all_stdio.extend(extract_stdio_server_commands(cfg))
1351
+ all_servers.extend(extract_project_server_summaries(cfg))
1342
1352
 
1343
- if not all_stdio:
1353
+ if not all_servers:
1344
1354
  return None
1345
1355
 
1346
1356
  if trust_flag:
@@ -1369,9 +1379,8 @@ def _check_mcp_project_trust(*, trust_flag: bool = False) -> bool | None:
1369
1379
  prompt_console.print(
1370
1380
  "[bold yellow]Project MCP servers require approval:[/bold yellow]"
1371
1381
  )
1372
- for name, cmd, args in all_stdio:
1373
- args_str = " ".join(args) if args else ""
1374
- prompt_console.print(f' [bold]"{name}"[/bold]: {cmd} {args_str}')
1382
+ for name, kind, summary in all_servers:
1383
+ prompt_console.print(f' [bold]"{name}"[/bold] ({kind}): {summary}')
1375
1384
  prompt_console.print()
1376
1385
 
1377
1386
  try:
@@ -1767,6 +1776,27 @@ def cli_main() -> None:
1767
1776
  from deepagents_cli.deploy import execute_deploy_command
1768
1777
 
1769
1778
  execute_deploy_command(args)
1779
+ elif args.command == "mcp":
1780
+ from deepagents_cli.mcp_commands import run_mcp_login
1781
+ from deepagents_cli.ui import show_mcp_help
1782
+
1783
+ if args.mcp_command == "login":
1784
+ if getattr(args, "mcp_config", None) and not args.config_path:
1785
+ print( # noqa: T201
1786
+ "--mcp-config is not supported for 'mcp login'. "
1787
+ "Use: deepagents mcp login <server> --config <path>",
1788
+ file=sys.stderr,
1789
+ )
1790
+ sys.exit(2)
1791
+ sys.exit(
1792
+ asyncio.run(
1793
+ run_mcp_login(
1794
+ server=args.server,
1795
+ config_path=args.config_path,
1796
+ )
1797
+ )
1798
+ )
1799
+ show_mcp_help()
1770
1800
  elif args.command == "threads":
1771
1801
  from deepagents_cli.sessions import (
1772
1802
  delete_thread_command,