testmcpy 0.9.2__tar.gz → 0.10.3__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 (205) hide show
  1. {testmcpy-0.9.2/testmcpy.egg-info → testmcpy-0.10.3}/PKG-INFO +29 -10
  2. {testmcpy-0.9.2 → testmcpy-0.10.3}/README.md +28 -9
  3. {testmcpy-0.9.2 → testmcpy-0.10.3}/pyproject.toml +1 -1
  4. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/wizard.py +18 -26
  5. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/mcp_profiles.py +55 -1
  6. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/tools.py +30 -10
  7. testmcpy-0.9.2/testmcpy/ui/dist/assets/index-BXP9_Odn.js → testmcpy-0.10.3/testmcpy/ui/dist/assets/index-C2CLSwMl.js +66 -66
  8. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/dist/index.html +1 -1
  9. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/MCPProfileSelector.jsx +2 -1
  10. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/Reports.jsx +16 -0
  11. testmcpy-0.10.3/testmcpy/ui/src/pages/__tests__/Reports.test.jsx +104 -0
  12. {testmcpy-0.9.2 → testmcpy-0.10.3/testmcpy.egg-info}/PKG-INFO +29 -10
  13. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy.egg-info/SOURCES.txt +2 -1
  14. {testmcpy-0.9.2 → testmcpy-0.10.3}/LICENSE +0 -0
  15. {testmcpy-0.9.2 → testmcpy-0.10.3}/MANIFEST.in +0 -0
  16. {testmcpy-0.9.2 → testmcpy-0.10.3}/NOTICE +0 -0
  17. {testmcpy-0.9.2 → testmcpy-0.10.3}/setup.cfg +0 -0
  18. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/__init__.py +0 -0
  19. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/__main__.py +0 -0
  20. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/__init__.py +0 -0
  21. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/hooks.py +0 -0
  22. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/models.py +0 -0
  23. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/orchestrator.py +0 -0
  24. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/prompts.py +0 -0
  25. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/agent/tools.py +0 -0
  26. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/analytics.py +0 -0
  27. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/auth_debugger.py +0 -0
  28. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/auth_flow_recorder.py +0 -0
  29. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/__init__.py +0 -0
  30. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/app.py +0 -0
  31. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/__init__.py +0 -0
  32. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/agent.py +0 -0
  33. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/analytics.py +0 -0
  34. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/badge.py +0 -0
  35. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/baseline.py +0 -0
  36. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/bench.py +0 -0
  37. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/conformance.py +0 -0
  38. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/export_db.py +0 -0
  39. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/mcp.py +0 -0
  40. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/metamorphic.py +0 -0
  41. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/multi_env.py +0 -0
  42. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/mutate.py +0 -0
  43. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/push.py +0 -0
  44. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/run.py +0 -0
  45. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/scan.py +0 -0
  46. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/score.py +0 -0
  47. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/server.py +0 -0
  48. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/tools.py +0 -0
  49. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/cli/commands/tui.py +0 -0
  50. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/config.py +0 -0
  51. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/__init__.py +0 -0
  52. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/chat_session.py +0 -0
  53. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/docs_optimizer.py +0 -0
  54. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/mcp_manager.py +0 -0
  55. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/tool_comparison.py +0 -0
  56. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/core/tool_discovery.py +0 -0
  57. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/db.py +0 -0
  58. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/error_handlers.py +0 -0
  59. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/evals/__init__.py +0 -0
  60. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/evals/auth_evaluators.py +0 -0
  61. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/evals/base_evaluators.py +0 -0
  62. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/evals/evaluator_packs.py +0 -0
  63. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/evals/security_evaluators.py +0 -0
  64. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/__init__.py +0 -0
  65. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/base.py +0 -0
  66. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/curl.py +0 -0
  67. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/graphql.py +0 -0
  68. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/javascript_client.py +0 -0
  69. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/json_yaml.py +0 -0
  70. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/protobuf.py +0 -0
  71. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/python.py +0 -0
  72. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/python_client.py +0 -0
  73. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/thrift.py +0 -0
  74. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/typescript.py +0 -0
  75. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/formatters/typescript_client.py +0 -0
  76. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/llm_profiles.py +0 -0
  77. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/mcp_profiles.py +0 -0
  78. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/migrate_json.py +0 -0
  79. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/models.py +0 -0
  80. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/research/claude_sdk_detailed_exploration.py +0 -0
  81. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/research/claude_sdk_poc.py +0 -0
  82. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/research/claude_sdk_working_poc.py +0 -0
  83. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/research/test_ollama_tools.py +0 -0
  84. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/security/__init__.py +0 -0
  85. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/security/rules.py +0 -0
  86. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/security/scanner.py +0 -0
  87. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/__init__.py +0 -0
  88. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/api.py +0 -0
  89. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/auth_middleware.py +0 -0
  90. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/helpers/__init__.py +0 -0
  91. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/helpers/mcp_config.py +0 -0
  92. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/models.py +0 -0
  93. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/__init__.py +0 -0
  94. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/agent.py +0 -0
  95. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/analytics.py +0 -0
  96. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/auth.py +0 -0
  97. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/compare.py +0 -0
  98. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/compatibility.py +0 -0
  99. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/generation_logs.py +0 -0
  100. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/health.py +0 -0
  101. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/llm.py +0 -0
  102. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/metrics.py +0 -0
  103. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/results.py +0 -0
  104. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/runs.py +0 -0
  105. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/search.py +0 -0
  106. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/security.py +0 -0
  107. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/smoke_reports.py +0 -0
  108. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/test_profiles.py +0 -0
  109. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/routers/tests.py +0 -0
  110. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/run_persistence.py +0 -0
  111. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/run_registry.py +0 -0
  112. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/state.py +0 -0
  113. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/server/websocket.py +0 -0
  114. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/smoke_test.py +0 -0
  115. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/__init__.py +0 -0
  116. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/baseline.py +0 -0
  117. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/ci_gate.py +0 -0
  118. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/comparison_runner.py +0 -0
  119. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/coverage_analyzer.py +0 -0
  120. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/emitters.py +0 -0
  121. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/html_report.py +0 -0
  122. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/llm_integration.py +0 -0
  123. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/mcp_client.py +0 -0
  124. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/metamorphic.py +0 -0
  125. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/model_registry.py +0 -0
  126. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/models.py +0 -0
  127. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/multi_env.py +0 -0
  128. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/oauth_flows.py +0 -0
  129. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/prompt_mutation.py +0 -0
  130. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/report_generator.py +0 -0
  131. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/runner_tools.py +0 -0
  132. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/schema_diff.py +0 -0
  133. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/test_runner.py +0 -0
  134. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/token_manager.py +0 -0
  135. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/src/usability_score.py +0 -0
  136. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/storage.py +0 -0
  137. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/test_profiles.py +0 -0
  138. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/README.md +0 -0
  139. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/dist/assets/index-D35cfDhp.css +0 -0
  140. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/index.html +0 -0
  141. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/package-lock.json +0 -0
  142. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/package.json +0 -0
  143. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/postcss.config.js +0 -0
  144. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/App.jsx +0 -0
  145. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/BackgroundRunsIndicator.jsx +0 -0
  146. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/Badge.jsx +0 -0
  147. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/CommandPalette.jsx +0 -0
  148. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/CompareToolsTab.jsx +0 -0
  149. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ConfirmDialog.jsx +0 -0
  150. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/EditorStatusBar.jsx +0 -0
  151. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/EditorTabStrip.jsx +0 -0
  152. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ErrorAlert.jsx +0 -0
  153. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ErrorBoundary.jsx +0 -0
  154. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/LLMProfileSelector.jsx +0 -0
  155. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/LoadingSpinner.jsx +0 -0
  156. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/NotificationProvider.jsx +0 -0
  157. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/OptimizeDocsModal.jsx +0 -0
  158. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/OutputDiff.jsx +0 -0
  159. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ParameterCard.jsx +0 -0
  160. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/SchemaCodeViewer.jsx +0 -0
  161. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/SkeletonLoader.jsx +0 -0
  162. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/StreamingLogViewer.jsx +0 -0
  163. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TestGenerationModal.jsx +0 -0
  164. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TestProfileSelector.jsx +0 -0
  165. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TestResultPanel.jsx +0 -0
  166. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TestStatusIndicator.jsx +0 -0
  167. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ToolCallTimeline.jsx +0 -0
  168. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ToolComparison.jsx +0 -0
  169. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/ToolDebugModal.jsx +0 -0
  170. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TraceView.jsx +0 -0
  171. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/TypeBadge.jsx +0 -0
  172. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/Wizard.jsx +0 -0
  173. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/components/__tests__/OutputDiff.test.jsx +0 -0
  174. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/contexts/TestRunContext.jsx +0 -0
  175. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/contexts/ThemeContext.jsx +0 -0
  176. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/hooks/useEditorTheme.js +0 -0
  177. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/hooks/useKeyboardShortcuts.js +0 -0
  178. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/hooks/useSafeFetch.js +0 -0
  179. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/index.css +0 -0
  180. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/main.jsx +0 -0
  181. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/AuthDebugger.jsx +0 -0
  182. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/ChatInterface.jsx +0 -0
  183. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/Configuration.jsx +0 -0
  184. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/GenerationHistory.jsx +0 -0
  185. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/LLMProfiles.jsx +0 -0
  186. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/MCPExplorer.jsx +0 -0
  187. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/MCPProfiles.jsx +0 -0
  188. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/Performance.jsx +0 -0
  189. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/ProfilesManager.jsx +0 -0
  190. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/SecurityDashboard.jsx +0 -0
  191. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/Servers.jsx +0 -0
  192. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/TestManager.jsx +0 -0
  193. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/__tests__/ChatInterface.test.jsx +0 -0
  194. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/pages/__tests__/Performance.test.jsx +0 -0
  195. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/test-setup.js +0 -0
  196. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/utils/__tests__/formatConverters.test.js +0 -0
  197. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/utils/formatConverters.js +0 -0
  198. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/src/utils/formatters.js +0 -0
  199. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/tailwind.config.js +0 -0
  200. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/vite.config.js +0 -0
  201. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy/ui/vitest.config.js +0 -0
  202. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy.egg-info/dependency_links.txt +0 -0
  203. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy.egg-info/entry_points.txt +0 -0
  204. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy.egg-info/requires.txt +0 -0
  205. {testmcpy-0.9.2 → testmcpy-0.10.3}/testmcpy.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testmcpy
3
- Version: 0.9.2
3
+ Version: 0.10.3
4
4
  Summary: A comprehensive testing framework for validating LLM tool calling capabilities with MCP services
5
5
  Author: Amin Ghadersohi
6
6
  License-Expression: Apache-2.0
@@ -94,13 +94,14 @@ Dynamic: license-file
94
94
  <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+"></a>
95
95
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
96
96
  <a href="https://pypi.org/project/testmcpy/"><img src="https://img.shields.io/badge/pypi-testmcpy-blue" alt="PyPI"></a>
97
+ <a href="https://preset-io.github.io/testmcpy"><img src="https://img.shields.io/badge/docs-preset--io.github.io-7aa2f7" alt="Documentation"></a>
97
98
  </p>
98
99
 
99
100
  ![MCP Explorer — tools, resources, and prompts from a connected MCP service](https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-explorer.png)
100
101
 
101
102
  ---
102
103
 
103
- **[Documentation](context/)** | **[Examples](examples/)** | **[Contributing](CONTRIBUTING.md)** | **[Discussions](https://github.com/preset-io/testmcpy/discussions)**
104
+ **[Documentation](https://preset-io.github.io/testmcpy)** | **[Getting Started](https://preset-io.github.io/testmcpy/getting-started)** | **[CLI Reference](https://preset-io.github.io/testmcpy/cli)** | **[Examples](examples/)** | **[Contributing](CONTRIBUTING.md)** | **[Discussions](https://github.com/preset-io/testmcpy/discussions)**
104
105
 
105
106
  ---
106
107
 
@@ -397,6 +398,8 @@ testmcpy run tests/ --model claude-haiku-4-5
397
398
 
398
399
  ## Commands Reference
399
400
 
401
+ The highlights are below — the full reference for all 38 commands lives at **[preset-io.github.io/testmcpy/cli](https://preset-io.github.io/testmcpy/cli)**.
402
+
400
403
  | Command | Description |
401
404
  |---------|-------------|
402
405
  | **Setup** | |
@@ -412,6 +415,12 @@ testmcpy run tests/ --model claude-haiku-4-5
412
415
  | `testmcpy research` | Test LLM tool-calling capabilities |
413
416
  | `testmcpy chat` | Interactive chat with MCP tools |
414
417
  | `testmcpy compare` | Multi-model comparison |
418
+ | **Quality & Benchmarking** | |
419
+ | `testmcpy bench` | Run a suite across models × profiles × repeats |
420
+ | `testmcpy conformance` | Run the official MCP spec conformance suite |
421
+ | `testmcpy score` | Grade tool surface for LLM usability (0-100, A-F) |
422
+ | `testmcpy scan` | Static security scan of tool metadata (SARIF output) |
423
+ | `testmcpy matrix` / `leaderboard` / `flaky` | Per-test × per-config analytics |
415
424
  | **Advanced** | |
416
425
  | `testmcpy baseline-save` | Save current test results as a named baseline |
417
426
  | `testmcpy baseline-compare` | Compare a run against a saved baseline |
@@ -459,7 +468,7 @@ Environment variables are also supported: `MCP_AUTH_TOKEN`, `MCP_JWT_URL`, `MCP_
459
468
 
460
469
  ## Web Interface
461
470
 
462
- Optional React-based UI with 14 pages for visual testing and analytics:
471
+ Optional React-based UI for visual testing and analytics — every page is documented at **[preset-io.github.io/testmcpy/web-ui](https://preset-io.github.io/testmcpy/web-ui)**:
463
472
 
464
473
  ![Test Manager — browse YAML suites, kick off runs, watch results stream in](https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/test-manager.png)
465
474
 
@@ -477,11 +486,9 @@ testmcpy serve
477
486
  | `/tests` | Test Manager | YAML test browser, execution, results |
478
487
  | `/reports` | Reports | All test results, evaluations, cost analysis |
479
488
  | `/chat` | Chat Interface | Multi-turn conversation with MCP tools |
480
- | `/metrics` | Metrics Dashboard | Performance and cost analytics |
481
- | `/compare` | Run Comparison | Side-by-side model comparison |
482
- | `/compatibility` | Compatibility Matrix | Tool/model compatibility view |
483
- | `/mcp-health` | MCP Health | Server health monitoring |
484
- | `/security` | Security Dashboard | Security analysis |
489
+ | `/performance` | Performance | Per-test matrix and config leaderboard (also serves `/metrics`, `/compare`) |
490
+ | `/servers` | Servers | Health monitoring + cross-server schema compatibility (also serves `/mcp-health`, `/compatibility`) |
491
+ | `/security` | Security Dashboard | Security evaluator results and risk summary |
485
492
  | `/generation-history` | Generation History | AI test generation logs |
486
493
  | `/auth-debugger` | Auth Debugger | Auth flow debugging |
487
494
  | `/config` | Configuration | Settings and environment |
@@ -498,7 +505,19 @@ Access at `http://localhost:8000`.
498
505
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/auth-debugger.png" alt="Auth Debugger page"><br><sub>Auth Debugger — step through OAuth / JWT / Bearer flows</sub></td>
499
506
  </tr>
500
507
  <tr>
508
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/metrics.png" alt="Performance matrix page"><br><sub>Performance — per-test results across model and MCP configurations</sub></td>
509
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/compare.png" alt="Leaderboard page"><br><sub>Leaderboard — configs ranked by pass rate, cost-per-pass, latency</sub></td>
510
+ </tr>
511
+ <tr>
512
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/security.png" alt="Security Dashboard page"><br><sub>Security Dashboard — security evaluator results and risk summary</sub></td>
513
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/compatibility.png" alt="Schema compatibility page"><br><sub>Schema Compat — cross-server tool schema compatibility matrix</sub></td>
514
+ </tr>
515
+ <tr>
516
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-health.png" alt="Server health page"><br><sub>Servers — MCP server health monitoring</sub></td>
501
517
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-profiles.png" alt="MCP Profiles page"><br><sub>MCP Profiles — manage MCP service connections</sub></td>
518
+ </tr>
519
+ <tr>
520
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/llm-profiles.png" alt="LLM Profiles page"><br><sub>LLM Profiles — provider configurations with model pricing</sub></td>
502
521
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/config.png" alt="Configuration page"><br><sub>Configuration — current settings and client snippets</sub></td>
503
522
  </tr>
504
523
  </table>
@@ -620,7 +639,7 @@ class MyEvaluator(BaseEvaluator):
620
639
  )
621
640
  ```
622
641
 
623
- See **[Evaluator Reference](context/concepts/evaluators.md)** for complete documentation.
642
+ See the **[Evaluator Reference](https://preset-io.github.io/testmcpy/concepts/evaluators)** and the **[Custom Evaluators guide](https://preset-io.github.io/testmcpy/guides/custom-evaluators)** for complete documentation.
624
643
 
625
644
  ## Examples
626
645
 
@@ -641,7 +660,7 @@ We welcome contributions! Whether it's bug reports, feature requests, documentat
641
660
 
642
661
  - **Issues**: [Report bugs or request features](https://github.com/preset-io/testmcpy/issues)
643
662
  - **Discussions**: [Ask questions and share ideas](https://github.com/preset-io/testmcpy/discussions)
644
- - **Documentation**: Browse the [context/](context/) directory
663
+ - **Documentation**: [preset-io.github.io/testmcpy](https://preset-io.github.io/testmcpy) (agent-facing source docs live in [context/](context/))
645
664
  - **Examples**: Explore [examples/](examples/) for sample code
646
665
 
647
666
  ## License
@@ -14,13 +14,14 @@
14
14
  <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+"></a>
15
15
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
16
16
  <a href="https://pypi.org/project/testmcpy/"><img src="https://img.shields.io/badge/pypi-testmcpy-blue" alt="PyPI"></a>
17
+ <a href="https://preset-io.github.io/testmcpy"><img src="https://img.shields.io/badge/docs-preset--io.github.io-7aa2f7" alt="Documentation"></a>
17
18
  </p>
18
19
 
19
20
  ![MCP Explorer — tools, resources, and prompts from a connected MCP service](https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-explorer.png)
20
21
 
21
22
  ---
22
23
 
23
- **[Documentation](context/)** | **[Examples](examples/)** | **[Contributing](CONTRIBUTING.md)** | **[Discussions](https://github.com/preset-io/testmcpy/discussions)**
24
+ **[Documentation](https://preset-io.github.io/testmcpy)** | **[Getting Started](https://preset-io.github.io/testmcpy/getting-started)** | **[CLI Reference](https://preset-io.github.io/testmcpy/cli)** | **[Examples](examples/)** | **[Contributing](CONTRIBUTING.md)** | **[Discussions](https://github.com/preset-io/testmcpy/discussions)**
24
25
 
25
26
  ---
26
27
 
@@ -317,6 +318,8 @@ testmcpy run tests/ --model claude-haiku-4-5
317
318
 
318
319
  ## Commands Reference
319
320
 
321
+ The highlights are below — the full reference for all 38 commands lives at **[preset-io.github.io/testmcpy/cli](https://preset-io.github.io/testmcpy/cli)**.
322
+
320
323
  | Command | Description |
321
324
  |---------|-------------|
322
325
  | **Setup** | |
@@ -332,6 +335,12 @@ testmcpy run tests/ --model claude-haiku-4-5
332
335
  | `testmcpy research` | Test LLM tool-calling capabilities |
333
336
  | `testmcpy chat` | Interactive chat with MCP tools |
334
337
  | `testmcpy compare` | Multi-model comparison |
338
+ | **Quality & Benchmarking** | |
339
+ | `testmcpy bench` | Run a suite across models × profiles × repeats |
340
+ | `testmcpy conformance` | Run the official MCP spec conformance suite |
341
+ | `testmcpy score` | Grade tool surface for LLM usability (0-100, A-F) |
342
+ | `testmcpy scan` | Static security scan of tool metadata (SARIF output) |
343
+ | `testmcpy matrix` / `leaderboard` / `flaky` | Per-test × per-config analytics |
335
344
  | **Advanced** | |
336
345
  | `testmcpy baseline-save` | Save current test results as a named baseline |
337
346
  | `testmcpy baseline-compare` | Compare a run against a saved baseline |
@@ -379,7 +388,7 @@ Environment variables are also supported: `MCP_AUTH_TOKEN`, `MCP_JWT_URL`, `MCP_
379
388
 
380
389
  ## Web Interface
381
390
 
382
- Optional React-based UI with 14 pages for visual testing and analytics:
391
+ Optional React-based UI for visual testing and analytics — every page is documented at **[preset-io.github.io/testmcpy/web-ui](https://preset-io.github.io/testmcpy/web-ui)**:
383
392
 
384
393
  ![Test Manager — browse YAML suites, kick off runs, watch results stream in](https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/test-manager.png)
385
394
 
@@ -397,11 +406,9 @@ testmcpy serve
397
406
  | `/tests` | Test Manager | YAML test browser, execution, results |
398
407
  | `/reports` | Reports | All test results, evaluations, cost analysis |
399
408
  | `/chat` | Chat Interface | Multi-turn conversation with MCP tools |
400
- | `/metrics` | Metrics Dashboard | Performance and cost analytics |
401
- | `/compare` | Run Comparison | Side-by-side model comparison |
402
- | `/compatibility` | Compatibility Matrix | Tool/model compatibility view |
403
- | `/mcp-health` | MCP Health | Server health monitoring |
404
- | `/security` | Security Dashboard | Security analysis |
409
+ | `/performance` | Performance | Per-test matrix and config leaderboard (also serves `/metrics`, `/compare`) |
410
+ | `/servers` | Servers | Health monitoring + cross-server schema compatibility (also serves `/mcp-health`, `/compatibility`) |
411
+ | `/security` | Security Dashboard | Security evaluator results and risk summary |
405
412
  | `/generation-history` | Generation History | AI test generation logs |
406
413
  | `/auth-debugger` | Auth Debugger | Auth flow debugging |
407
414
  | `/config` | Configuration | Settings and environment |
@@ -418,7 +425,19 @@ Access at `http://localhost:8000`.
418
425
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/auth-debugger.png" alt="Auth Debugger page"><br><sub>Auth Debugger — step through OAuth / JWT / Bearer flows</sub></td>
419
426
  </tr>
420
427
  <tr>
428
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/metrics.png" alt="Performance matrix page"><br><sub>Performance — per-test results across model and MCP configurations</sub></td>
429
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/compare.png" alt="Leaderboard page"><br><sub>Leaderboard — configs ranked by pass rate, cost-per-pass, latency</sub></td>
430
+ </tr>
431
+ <tr>
432
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/security.png" alt="Security Dashboard page"><br><sub>Security Dashboard — security evaluator results and risk summary</sub></td>
433
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/compatibility.png" alt="Schema compatibility page"><br><sub>Schema Compat — cross-server tool schema compatibility matrix</sub></td>
434
+ </tr>
435
+ <tr>
436
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-health.png" alt="Server health page"><br><sub>Servers — MCP server health monitoring</sub></td>
421
437
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/mcp-profiles.png" alt="MCP Profiles page"><br><sub>MCP Profiles — manage MCP service connections</sub></td>
438
+ </tr>
439
+ <tr>
440
+ <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/llm-profiles.png" alt="LLM Profiles page"><br><sub>LLM Profiles — provider configurations with model pricing</sub></td>
422
441
  <td align="center"><img src="https://raw.githubusercontent.com/preset-io/testmcpy/main/docs/screenshots/config.png" alt="Configuration page"><br><sub>Configuration — current settings and client snippets</sub></td>
423
442
  </tr>
424
443
  </table>
@@ -540,7 +559,7 @@ class MyEvaluator(BaseEvaluator):
540
559
  )
541
560
  ```
542
561
 
543
- See **[Evaluator Reference](context/concepts/evaluators.md)** for complete documentation.
562
+ See the **[Evaluator Reference](https://preset-io.github.io/testmcpy/concepts/evaluators)** and the **[Custom Evaluators guide](https://preset-io.github.io/testmcpy/guides/custom-evaluators)** for complete documentation.
544
563
 
545
564
  ## Examples
546
565
 
@@ -561,7 +580,7 @@ We welcome contributions! Whether it's bug reports, feature requests, documentat
561
580
 
562
581
  - **Issues**: [Report bugs or request features](https://github.com/preset-io/testmcpy/issues)
563
582
  - **Discussions**: [Ask questions and share ideas](https://github.com/preset-io/testmcpy/discussions)
564
- - **Documentation**: Browse the [context/](context/) directory
583
+ - **Documentation**: [preset-io.github.io/testmcpy](https://preset-io.github.io/testmcpy) (agent-facing source docs live in [context/](context/))
565
584
  - **Examples**: Explore [examples/](examples/) for sample code
566
585
 
567
586
  ## License
@@ -93,7 +93,7 @@ testmcpy = [
93
93
 
94
94
  [project]
95
95
  name = "testmcpy"
96
- version = "0.9.2"
96
+ version = "0.10.3"
97
97
  description = "A comprehensive testing framework for validating LLM tool calling capabilities with MCP services"
98
98
  authors = [{name = "Amin Ghadersohi"}]
99
99
  license = "Apache-2.0"
@@ -104,40 +104,32 @@ def add_mcp():
104
104
  # Step 5: Test Connection
105
105
  console.print("\n[bold yellow]Step 5: Test Connection[/bold yellow]")
106
106
  if Confirm.ask("Test connection now?", default=True):
107
- from testmcpy.mcp_profiles import AuthConfig, MCPServer
108
-
109
- test_url = mcp_url if transport == "sse" else f"stdio://{command}"
110
- mcp_server = MCPServer(
111
- name=name,
112
- mcp_url=test_url,
113
- auth=AuthConfig(auth_type=auth_config.get("type", "none")),
114
- timeout=timeout,
115
- rate_limit_rpm=rate_limit,
116
- transport=transport,
117
- command=command if transport == "stdio" else None,
118
- args=args_str.split() if args_str else None,
119
- )
120
-
121
107
  console.print("[dim]Connecting...[/dim]")
122
108
  try:
123
- from testmcpy.src.mcp_client import MCPClient
124
-
125
- client = MCPClient(
126
- mcp_url=mcp_server.mcp_url,
127
- auth=mcp_server.auth.to_dict() if mcp_server.auth else None,
128
- timeout=mcp_server.timeout,
129
- transport=mcp_server.transport,
130
- command=mcp_server.command,
131
- args=mcp_server.args,
132
- )
133
- tools = asyncio.run(client.list_tools())
109
+ from testmcpy.src.mcp_client import MCPClient, MCPError, StdioMCPClient
110
+
111
+ if transport == "stdio":
112
+ client: MCPClient | StdioMCPClient = StdioMCPClient(
113
+ command=command, args=args_str.split() if args_str else None
114
+ )
115
+ else:
116
+ client = MCPClient(mcp_url, auth=auth_config)
117
+
118
+ async def _test_connection():
119
+ try:
120
+ await client.initialize(timeout=float(timeout))
121
+ return await client.list_tools(timeout=float(timeout))
122
+ finally:
123
+ await client.close()
124
+
125
+ tools = asyncio.run(_test_connection())
134
126
  console.print(f"[green]Connected! Found {len(tools)} tools.[/green]")
135
127
  if tools:
136
128
  tool_names = [t.name if hasattr(t, "name") else str(t) for t in tools[:5]]
137
129
  console.print(
138
130
  f"[dim] Tools: {', '.join(tool_names)}{'...' if len(tools) > 5 else ''}[/dim]"
139
131
  )
140
- except (ConnectionError, TimeoutError, OSError, RuntimeError, ValueError) as e:
132
+ except (MCPError, ConnectionError, TimeoutError, OSError, RuntimeError, ValueError) as e:
141
133
  console.print(f"[red]Connection failed: {e}[/red]")
142
134
  if not Confirm.ask("Continue anyway?", default=True):
143
135
  raise typer.Abort()
@@ -1,6 +1,7 @@
1
1
  """MCP profile management endpoints."""
2
2
 
3
3
  import copy
4
+ import logging
4
5
  import re
5
6
  from pathlib import Path
6
7
 
@@ -14,7 +15,9 @@ from testmcpy.server.helpers import (
14
15
  load_mcp_yaml,
15
16
  save_mcp_yaml,
16
17
  )
17
- from testmcpy.src.mcp_client import MCPClient
18
+ from testmcpy.src.mcp_client import MCPClient, MCPError, StdioMCPClient
19
+
20
+ logger = logging.getLogger(__name__)
18
21
 
19
22
  router = APIRouter(prefix="/api/mcp", tags=["mcp-profiles"])
20
23
 
@@ -87,6 +90,15 @@ class MCPReorderRequest(BaseModel):
87
90
  to_index: int
88
91
 
89
92
 
93
+ class TestConnectionRequest(BaseModel):
94
+ mcp_url: str
95
+ transport: str = "sse"
96
+ command: str | None = None
97
+ args: list[str] | None = None
98
+ auth: AuthConfig | None = None
99
+ timeout: int | None = None
100
+
101
+
90
102
  # Helper to get the mcp_clients dict from api module
91
103
  def get_mcp_clients() -> dict[str, MCPClient]:
92
104
  """Get the global mcp_clients dict from api module."""
@@ -872,3 +884,45 @@ async def test_mcp_connection(profile_id: str, mcp_index: int):
872
884
  raise
873
885
  except Exception as e:
874
886
  raise HTTPException(status_code=500, detail=str(e))
887
+
888
+
889
+ @router.post("/test-connection")
890
+ async def test_connection_standalone(request: TestConnectionRequest):
891
+ """Test connection to an MCP server from an inline config.
892
+
893
+ Used by the Add MCP wizard to test a server before it is saved to any
894
+ profile (unlike /profiles/{id}/test-connection/{idx}, which tests a
895
+ saved MCP).
896
+ """
897
+ timeout = float(request.timeout) if request.timeout else 30.0
898
+
899
+ if request.transport == "stdio":
900
+ command = request.command or request.mcp_url.removeprefix("stdio://")
901
+ if not command:
902
+ raise HTTPException(status_code=400, detail="command is required for stdio transport")
903
+ client: MCPClient | StdioMCPClient = StdioMCPClient(command=command, args=request.args)
904
+ else:
905
+ if not request.mcp_url:
906
+ raise HTTPException(status_code=400, detail="mcp_url is required")
907
+ # AuthConfig already matches the {type, token, ...} dict shape
908
+ # MCPClient._setup_auth() reads (it tolerates extra keys).
909
+ auth_dict = request.auth.model_dump(exclude_none=True) if request.auth else {"type": "none"}
910
+ client = MCPClient(request.mcp_url, auth=auth_dict)
911
+
912
+ try:
913
+ await client.initialize(timeout=timeout)
914
+ tools = await client.list_tools(timeout=timeout)
915
+ return {
916
+ "success": True,
917
+ "status": "connected",
918
+ "message": f"Successfully connected — found {len(tools)} tools",
919
+ "tool_count": len(tools),
920
+ "tools": [tool.name for tool in tools],
921
+ }
922
+ except (MCPError, ConnectionError, TimeoutError, OSError, RuntimeError, ValueError) as e:
923
+ return {"success": False, "status": "error", "message": f"Connection failed: {str(e)}"}
924
+ finally:
925
+ try:
926
+ await client.close()
927
+ except (MCPError, ConnectionError, OSError, RuntimeError) as e:
928
+ logger.warning("Failed to close test client: %s", e)
@@ -13,7 +13,7 @@ from testmcpy.config import get_config
13
13
  from testmcpy.mcp_profiles import load_profile
14
14
  from testmcpy.server.state import get_default_mcp_client, get_mcp_clients
15
15
  from testmcpy.src.llm_integration import create_llm_provider
16
- from testmcpy.src.mcp_client import MCPClient, MCPError
16
+ from testmcpy.src.mcp_client import MCPClient, MCPError, MCPToolCall
17
17
 
18
18
  logger = logging.getLogger(__name__)
19
19
 
@@ -1010,16 +1010,25 @@ async def compare_tools(request: ToolCompareRequest):
1010
1010
  start_time = time.time()
1011
1011
 
1012
1012
  # Initialize client
1013
- client = MCPClient(mcp_url=mcp_config.get_mcp_url(), auth=mcp_config.auth)
1013
+ client = MCPClient(
1014
+ base_url=mcp_config.mcp_url,
1015
+ auth=mcp_config.auth.to_dict() if mcp_config.auth else None,
1016
+ )
1014
1017
  await client.initialize()
1015
1018
 
1016
1019
  # Call the tool
1017
1020
  tool_result = await client.call_tool(
1018
- name=request.tool_name, arguments=request.parameters
1021
+ MCPToolCall(name=request.tool_name, arguments=request.parameters)
1019
1022
  )
1020
1023
 
1021
- result["success"] = True
1022
- result["result"] = tool_result
1024
+ if tool_result.is_error:
1025
+ result["success"] = False
1026
+ result["error"] = tool_result.error_message or "Tool call failed"
1027
+ else:
1028
+ from testmcpy.server.api import _serialize_tool_content
1029
+
1030
+ result["success"] = True
1031
+ result["result"] = _serialize_tool_content(tool_result.content)
1023
1032
  result["duration_ms"] = (time.time() - start_time) * 1000
1024
1033
 
1025
1034
  except Exception as e:
@@ -1029,9 +1038,9 @@ async def compare_tools(request: ToolCompareRequest):
1029
1038
  finally:
1030
1039
  if client:
1031
1040
  try:
1032
- await client.cleanup()
1033
- except Exception:
1034
- pass
1041
+ await client.close()
1042
+ except (MCPError, ConnectionError, OSError, RuntimeError) as e:
1043
+ logger.warning("Failed to close comparison client: %s", e)
1035
1044
 
1036
1045
  return result
1037
1046
 
@@ -1116,7 +1125,10 @@ async def debug_tool(tool_name: str, request: ToolDebugRequest):
1116
1125
  profile_data = load_profile(request.profile)
1117
1126
  if profile_data and profile_data.mcps:
1118
1127
  mcp_config = profile_data.mcps[0]
1119
- client = MCPClient(mcp_url=mcp_config.get_mcp_url(), auth=mcp_config.auth)
1128
+ client = MCPClient(
1129
+ base_url=mcp_config.mcp_url,
1130
+ auth=mcp_config.auth.to_dict() if mcp_config.auth else None,
1131
+ )
1120
1132
  await client.initialize()
1121
1133
  mcp_clients[client_key] = client
1122
1134
  except Exception as e:
@@ -1137,7 +1149,15 @@ async def debug_tool(tool_name: str, request: ToolDebugRequest):
1137
1149
 
1138
1150
  # Step 2: Call tool
1139
1151
  try:
1140
- response = await client.call_tool(tool_name, request.parameters)
1152
+ tool_result = await client.call_tool(
1153
+ MCPToolCall(name=tool_name, arguments=request.parameters)
1154
+ )
1155
+ if tool_result.is_error:
1156
+ raise MCPError(tool_result.error_message or "Tool call failed")
1157
+
1158
+ from testmcpy.server.api import _serialize_tool_content
1159
+
1160
+ response = _serialize_tool_content(tool_result.content)
1141
1161
 
1142
1162
  steps.append(
1143
1163
  {