mcp-use 1.3.6__tar.gz → 1.3.7__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.

Potentially problematic release.


This version of mcp-use might be problematic. Click here for more details.

Files changed (162) hide show
  1. mcp_use-1.3.7/.github/workflows/publish.yml +81 -0
  2. mcp_use-1.3.7/.github/workflows/tests.yml +95 -0
  3. {mcp_use-1.3.6 → mcp_use-1.3.7}/PKG-INFO +8 -3
  4. {mcp_use-1.3.6 → mcp_use-1.3.7}/README.md +6 -1
  5. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/docs.json +31 -9
  6. mcp_use-1.3.7/docs/essentials/elicitation.mdx +363 -0
  7. mcp_use-1.3.7/docs/essentials/sampling.mdx +86 -0
  8. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/server-manager.mdx +1 -2
  9. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/browser_use.py +4 -5
  10. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/client.py +38 -5
  11. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/config.py +11 -1
  12. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/base.py +46 -11
  13. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/http.py +21 -12
  14. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/sandbox.py +13 -2
  15. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/stdio.py +13 -2
  16. {mcp_use-1.3.6 → mcp_use-1.3.7}/pyproject.toml +2 -2
  17. mcp_use-1.3.7/tests/integration/conftest.py +38 -0
  18. mcp_use-1.3.7/tests/integration/primitives/test_elicitation.py +26 -0
  19. mcp_use-1.3.7/tests/integration/primitives/test_prompts.py +20 -0
  20. mcp_use-1.3.7/tests/integration/primitives/test_resources.py +42 -0
  21. mcp_use-1.3.7/tests/integration/primitives/test_sampling.py +48 -0
  22. mcp_use-1.3.7/tests/integration/primitives/test_tools.py +28 -0
  23. mcp_use-1.3.7/tests/integration/servers_for_testing/primitive_server.py +72 -0
  24. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_client.py +29 -7
  25. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_http_connector.py +9 -3
  26. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_sandbox_connector.py +8 -2
  27. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_stdio_connector.py +9 -3
  28. mcp_use-1.3.6/.github/workflows/claude.yml +0 -36
  29. mcp_use-1.3.6/.github/workflows/publish.yml +0 -80
  30. mcp_use-1.3.6/.github/workflows/transportstests.yml +0 -41
  31. mcp_use-1.3.6/.github/workflows/unittests.yml +0 -31
  32. mcp_use-1.3.6/examples/browser_mcp.json +0 -11
  33. mcp_use-1.3.6/tests/integration/transports/sse/test_connection_state_tracking.py +0 -297
  34. {mcp_use-1.3.6 → mcp_use-1.3.7}/.env.example +0 -0
  35. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  36. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/pull_request_template.md +0 -0
  37. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/release-drafter.yml +0 -0
  38. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/workflows/changelog.yml +0 -0
  39. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/workflows/release-drafter.yml +0 -0
  40. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/workflows/stale.yml +0 -0
  41. {mcp_use-1.3.6 → mcp_use-1.3.7}/.github/workflows/update-readme.yml +0 -0
  42. {mcp_use-1.3.6 → mcp_use-1.3.7}/.gitignore +0 -0
  43. {mcp_use-1.3.6 → mcp_use-1.3.7}/.pre-commit-config.yaml +0 -0
  44. {mcp_use-1.3.6 → mcp_use-1.3.7}/CHANGELOG.md +0 -0
  45. {mcp_use-1.3.6 → mcp_use-1.3.7}/CLAUDE.md +0 -0
  46. {mcp_use-1.3.6 → mcp_use-1.3.7}/CODE_OF_CONDUCT.md +0 -0
  47. {mcp_use-1.3.6 → mcp_use-1.3.7}/CONTRIBUTING.md +0 -0
  48. {mcp_use-1.3.6 → mcp_use-1.3.7}/LICENSE +0 -0
  49. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/README.md +0 -0
  50. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/api-reference/adapters.mdx +0 -0
  51. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/api-reference/introduction.mdx +0 -0
  52. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/api-reference/mcpagent.mdx +0 -0
  53. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/api-reference/mcpclient.mdx +0 -0
  54. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/changelog.mdx +0 -0
  55. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/community/showcase.mdx +0 -0
  56. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/development/observability.mdx +0 -0
  57. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/development/telemetry.mdx +0 -0
  58. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/development.mdx +0 -0
  59. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/agent-configuration.mdx +0 -0
  60. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/client-configuration.mdx +0 -0
  61. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/configuration.mdx +0 -0
  62. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/connection-types.mdx +0 -0
  63. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/essentials/llm-integration.mdx +0 -0
  64. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/favicon.svg +0 -0
  65. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/fonts.css +0 -0
  66. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/guides/building-custom-agents.mdx +0 -0
  67. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/guides/logging.mdx +0 -0
  68. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/guides/multi-server-setup.mdx +0 -0
  69. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/guides/security.mdx +0 -0
  70. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/guides/streaming.mdx +0 -0
  71. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/01.png +0 -0
  72. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/02.png +0 -0
  73. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/configuration-dark.png +0 -0
  74. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/configuration-light.png +0 -0
  75. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/examples-dark.png +0 -0
  76. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/examples-light.png +0 -0
  77. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/hero-dark.png +0 -0
  78. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/hero-light.png +0 -0
  79. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/installation-dark.png +0 -0
  80. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/installation-light.png +0 -0
  81. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/quickstart-dark.png +0 -0
  82. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/images/quickstart-light.png +0 -0
  83. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/index.mdx +0 -0
  84. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/installation.mdx +0 -0
  85. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/logo/dark.svg +0 -0
  86. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/logo/light.svg +0 -0
  87. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/logo/react.svg +0 -0
  88. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/quickstart.mdx +0 -0
  89. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/snippets/snippet-intro.mdx +0 -0
  90. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/snippets/youtube-embed.mdx +0 -0
  91. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/troubleshooting/common-issues.mdx +0 -0
  92. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/troubleshooting/connection-errors.mdx +0 -0
  93. {mcp_use-1.3.6 → mcp_use-1.3.7}/docs/troubleshooting/performance.mdx +0 -0
  94. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/airbnb_mcp.json +0 -0
  95. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/airbnb_use.py +0 -0
  96. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/blender_use.py +0 -0
  97. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/chat_example.py +0 -0
  98. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/filesystem_use.py +0 -0
  99. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/http_example.py +0 -0
  100. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/mcp_everything.py +0 -0
  101. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/multi_server_example.py +0 -0
  102. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/sandbox_everything.py +0 -0
  103. {mcp_use-1.3.6 → mcp_use-1.3.7}/examples/stream_example.py +0 -0
  104. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/__init__.py +0 -0
  105. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/adapters/__init__.py +0 -0
  106. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/adapters/base.py +0 -0
  107. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/adapters/langchain_adapter.py +0 -0
  108. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/agents/__init__.py +0 -0
  109. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/agents/base.py +0 -0
  110. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/agents/mcpagent.py +0 -0
  111. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/agents/prompts/system_prompt_builder.py +0 -0
  112. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/agents/prompts/templates.py +0 -0
  113. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/__init__.py +0 -0
  114. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/utils.py +0 -0
  115. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/connectors/websocket.py +0 -0
  116. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/logging.py +0 -0
  117. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/__init__.py +0 -0
  118. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/server_manager.py +0 -0
  119. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/__init__.py +0 -0
  120. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/base_tool.py +0 -0
  121. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/connect_server.py +0 -0
  122. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/disconnect_server.py +0 -0
  123. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/get_active_server.py +0 -0
  124. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/list_servers_tool.py +0 -0
  125. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/search_tools.py +0 -0
  126. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/managers/tools/use_tool.py +0 -0
  127. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/observability/__init__.py +0 -0
  128. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/observability/laminar.py +0 -0
  129. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/observability/langfuse.py +0 -0
  130. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/session.py +0 -0
  131. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/__init__.py +0 -0
  132. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/base.py +0 -0
  133. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/sse.py +0 -0
  134. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/stdio.py +0 -0
  135. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/streamable_http.py +0 -0
  136. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/task_managers/websocket.py +0 -0
  137. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/telemetry/__init__.py +0 -0
  138. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/telemetry/events.py +0 -0
  139. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/telemetry/telemetry.py +0 -0
  140. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/telemetry/utils.py +0 -0
  141. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/types/sandbox.py +0 -0
  142. {mcp_use-1.3.6 → mcp_use-1.3.7}/mcp_use/utils.py +0 -0
  143. {mcp_use-1.3.6 → mcp_use-1.3.7}/pytest.ini +0 -0
  144. {mcp_use-1.3.6 → mcp_use-1.3.7}/ruff.toml +0 -0
  145. {mcp_use-1.3.6 → mcp_use-1.3.7}/static/logo_black.svg +0 -0
  146. {mcp_use-1.3.6 → mcp_use-1.3.7}/static/logo_white.svg +0 -0
  147. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/conftest.py +0 -0
  148. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/__init__.py +0 -0
  149. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/servers_for_testing/__init__.py +0 -0
  150. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/servers_for_testing/custom_streaming_server.py +0 -0
  151. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/servers_for_testing/simple_server.py +0 -0
  152. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/servers_for_testing/timeout_test_server.py +0 -0
  153. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/transports/customStreaming/__init__.py +0 -0
  154. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/transports/customStreaming/test_custom_streaming_integration.py +0 -0
  155. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/transports/sse/test_sse_integration.py +0 -0
  156. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/transports/stdio/test_stdio_integration.py +0 -0
  157. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/integration/transports/streamableHttp/test_streamable_http_integration.py +0 -0
  158. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_config.py +0 -0
  159. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_logging.py +0 -0
  160. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_search_tools_issue_138.py +0 -0
  161. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_session.py +0 -0
  162. {mcp_use-1.3.6 → mcp_use-1.3.7}/tests/unit/test_websocket_connection_manager.py +0 -0
@@ -0,0 +1,81 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ # Required for PyPI trusted publishing
8
+ permissions:
9
+ id-token: write
10
+ contents: read
11
+
12
+ jobs:
13
+ check-version-and-publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v3
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v4
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ pip install build twine wheel tomli
29
+
30
+ - name: Verify version match
31
+ id: check-version
32
+ run: |
33
+ # Extract current version from pyproject.toml
34
+ PYPROJECT_VERSION=$(python -c "
35
+ import tomli
36
+ with open('pyproject.toml', 'rb') as f:
37
+ data = tomli.load(f)
38
+ print(data['project']['version'])
39
+ ")
40
+
41
+ # Get release tag version (remove 'v' prefix if present)
42
+ RELEASE_VERSION="${{ github.event.release.tag_name }}"
43
+ RELEASE_VERSION=${RELEASE_VERSION#v}
44
+
45
+ echo "PyProject version: $PYPROJECT_VERSION"
46
+ echo "Release version: $RELEASE_VERSION"
47
+
48
+ if [ "$PYPROJECT_VERSION" = "$RELEASE_VERSION" ]; then
49
+ echo "✅ Versions match! Proceeding with PyPI publish"
50
+ echo "should_publish=true" >> $GITHUB_OUTPUT
51
+ echo "version=$PYPROJECT_VERSION" >> $GITHUB_OUTPUT
52
+ else
53
+ echo "❌ Version mismatch! PyProject: $PYPROJECT_VERSION, Release: $RELEASE_VERSION"
54
+ echo "should_publish=false" >> $GITHUB_OUTPUT
55
+ exit 1
56
+ fi
57
+
58
+ - name: Build package
59
+ if: steps.check-version.outputs.should_publish == 'true'
60
+ run: |
61
+ python -m build
62
+
63
+ - name: Check if already published to PyPI
64
+ if: steps.check-version.outputs.should_publish == 'true'
65
+ id: check-pypi
66
+ run: |
67
+ # Check if this version exists on PyPI
68
+ VERSION="${{ steps.check-version.outputs.version }}"
69
+ if pip index versions mcp-use | grep -q "Available versions: .*$VERSION"; then
70
+ echo "Version $VERSION already exists on PyPI"
71
+ echo "publish_needed=false" >> $GITHUB_OUTPUT
72
+ else
73
+ echo "Version $VERSION not found on PyPI, will publish"
74
+ echo "publish_needed=true" >> $GITHUB_OUTPUT
75
+ fi
76
+
77
+ - name: Publish to PyPI
78
+ if: steps.check-pypi.outputs.publish_needed == 'true'
79
+ uses: pypa/gh-action-pypi-publish@release/v1
80
+ with:
81
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,95 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ lint:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v3
14
+ - name: Set up Python 3.11
15
+ uses: actions/setup-python@v4
16
+ with:
17
+ python-version: "3.11"
18
+ - name: Install dependencies
19
+ run: |
20
+ python -m pip install --upgrade pip
21
+ pip install ruff
22
+ - name: Lint with ruff
23
+ run: |
24
+ ruff check .
25
+ - name: Format check with ruff
26
+ run: |
27
+ ruff format --check .
28
+
29
+ unit-tests:
30
+ needs: lint
31
+ runs-on: ubuntu-latest
32
+ strategy:
33
+ matrix:
34
+ python-version: ["3.11", "3.12"]
35
+ steps:
36
+ - uses: actions/checkout@v3
37
+ - name: Set up Python ${{ matrix.python-version }}
38
+ uses: actions/setup-python@v4
39
+ with:
40
+ python-version: ${{ matrix.python-version }}
41
+ - name: Install dependencies
42
+ run: |
43
+ python -m pip install --upgrade pip
44
+ pip install .[dev,anthropic,openai,search,e2b]
45
+ - name: Test with pytest
46
+ run: |
47
+ pytest tests/unit
48
+
49
+ transport-tests:
50
+ needs: lint
51
+ name: "transport/${{ matrix.transport }}"
52
+ runs-on: ubuntu-latest
53
+ strategy:
54
+ fail-fast: false
55
+ matrix:
56
+ transport: [stdio, sse, streamableHttp]
57
+ steps:
58
+ - uses: actions/checkout@v3
59
+ - name: Set up Python 3.11
60
+ uses: actions/setup-python@v4
61
+ with:
62
+ python-version: "3.11"
63
+ - name: Install uv
64
+ run: |
65
+ pip install uv
66
+ - name: Install dependencies
67
+ run: |
68
+ uv pip install --system .[dev,anthropic,openai,search,e2b]
69
+ - name: Run integration tests for ${{ matrix.transport }} transport
70
+ run: |
71
+ pytest tests/integration/transports/${{ matrix.transport }}
72
+
73
+ primitive-tests:
74
+ needs: lint
75
+ name: "primitive/${{ matrix.primitive }}"
76
+ runs-on: ubuntu-latest
77
+ strategy:
78
+ fail-fast: false
79
+ matrix:
80
+ primitive: [sampling, tools, resources, prompts, elicitation]
81
+ steps:
82
+ - uses: actions/checkout@v3
83
+ - name: Set up Python 3.11
84
+ uses: actions/setup-python@v4
85
+ with:
86
+ python-version: "3.11"
87
+ - name: Install uv
88
+ run: |
89
+ pip install uv
90
+ - name: Install dependencies
91
+ run: |
92
+ uv pip install --system .[dev,anthropic,openai,search,e2b]
93
+ - name: Run integration tests for ${{ matrix.primitive }} primitive
94
+ run: |
95
+ pytest tests/integration/primitives/test_${{ matrix.primitive }}.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-use
3
- Version: 1.3.6
3
+ Version: 1.3.7
4
4
  Summary: MCP Library for LLMs
5
5
  Author-email: Pietro Zullo <pietro.zullo@gmail.com>
6
6
  License: MIT
@@ -28,7 +28,7 @@ Requires-Dist: langchain-anthropic; extra == 'anthropic'
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: black>=23.9.0; extra == 'dev'
30
30
  Requires-Dist: fastapi; extra == 'dev'
31
- Requires-Dist: fastmcp==2.8.0; extra == 'dev'
31
+ Requires-Dist: fastmcp==2.10.5; extra == 'dev'
32
32
  Requires-Dist: isort>=5.12.0; extra == 'dev'
33
33
  Requires-Dist: mypy>=1.5.0; extra == 'dev'
34
34
  Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
@@ -89,7 +89,12 @@ Description-Content-Type: text/markdown
89
89
 
90
90
  💬 Get started quickly - chat with your servers on our <b>hosted version</b>! [Try mcp-use chat (beta)](https://chat.mcp-use.com).
91
91
 
92
- # Features
92
+ | Supports | |
93
+ | :--- | :--- |
94
+ | **Primitives** | [![Tools](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-tools&label=Tools&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Resources](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-resources&label=Resources&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Prompts](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-prompts&label=Prompts&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Sampling](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-sampling&label=Sampling&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Elicitation](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-elicitation&label=Elicitation&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
95
+ | **Transports** | [![Stdio](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-stdio&label=Stdio&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![SSE](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-sse&label=SSE&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Streamable HTTP](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-streamableHttp&label=Streamable%20HTTP&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
96
+
97
+ ## Features
93
98
 
94
99
  <table>
95
100
  <tr>
@@ -44,7 +44,12 @@
44
44
 
45
45
  💬 Get started quickly - chat with your servers on our <b>hosted version</b>! [Try mcp-use chat (beta)](https://chat.mcp-use.com).
46
46
 
47
- # Features
47
+ | Supports | |
48
+ | :--- | :--- |
49
+ | **Primitives** | [![Tools](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-tools&label=Tools&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Resources](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-resources&label=Resources&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Prompts](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-prompts&label=Prompts&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Sampling](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-sampling&label=Sampling&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Elicitation](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=primitive-elicitation&label=Elicitation&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
50
+ | **Transports** | [![Stdio](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-stdio&label=Stdio&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![SSE](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-sse&label=SSE&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) [![Streamable HTTP](https://img.shields.io/github/actions/workflow/status/pietrozullo/mcp-use/tests.yml?job=transport-streamableHttp&label=Streamable%20HTTP&style=flat)](https://github.com/pietrozullo/mcp-use/actions/workflows/tests.yml) |
51
+
52
+ ## Features
48
53
 
49
54
  <table>
50
55
  <tr>
@@ -8,10 +8,32 @@
8
8
  "dark": "#000000"
9
9
  },
10
10
  "favicon": "/favicon.svg",
11
+ "contextual": {
12
+ "options": [
13
+ "copy",
14
+ "view",
15
+ "chatgpt",
16
+ "claude"
17
+ ]
18
+ },
11
19
  "icons": {
12
20
  "library": "lucide"
13
21
  },
14
22
  "navigation": {
23
+ "global": {
24
+ "anchors": [
25
+ {
26
+ "anchor": "Website",
27
+ "href": "https://mcp-use.com",
28
+ "icon": "globe"
29
+ },
30
+ {
31
+ "anchor": "Forum",
32
+ "href": "https://discord.gg/XkNkSkMz3V",
33
+ "icon": "discord"
34
+ }
35
+ ]
36
+ },
15
37
  "tabs": [
16
38
  {
17
39
  "tab": "Documentation",
@@ -30,7 +52,15 @@
30
52
  "pages": [
31
53
  "essentials/configuration",
32
54
  "essentials/client-configuration",
33
- "essentials/connection-types"
55
+ {
56
+ "group": "Client Features",
57
+ "icon": "list-plus",
58
+ "pages": [
59
+ "essentials/connection-types",
60
+ "essentials/sampling",
61
+ "essentials/elicitation"
62
+ ]
63
+ }
34
64
  ]
35
65
  },
36
66
  {
@@ -196,14 +226,6 @@
196
226
  }
197
227
  ]
198
228
  },
199
- "contextual": {
200
- "options": [
201
- "copy",
202
- "view",
203
- "chatgpt",
204
- "claude"
205
- ]
206
- },
207
229
  "seo": {
208
230
  "metatags": {
209
231
  "charset": "UTF-8",
@@ -0,0 +1,363 @@
1
+ ---
2
+ title: "Elicitation"
3
+ description: "Enable user input requests for MCP tools"
4
+ icon: "user-question"
5
+ ---
6
+
7
+ # Elicitation
8
+
9
+ <Info>
10
+ Elicitation allows MCP tools to request additional information from users during their execution.
11
+ </Info>
12
+
13
+ ## Configuration
14
+
15
+ To enable elicitation, provide an `elicitation_callback` function when initializing the MCPClient:
16
+
17
+ ```python
18
+ from mcp_use.client import MCPClient
19
+ from mcp.client.session import RequestContext
20
+ from mcp.types import ElicitRequestParams, ElicitResult
21
+
22
+ async def elicitation_callback(
23
+ context: RequestContext,
24
+ params: ElicitRequestParams
25
+ ) -> ElicitResult:
26
+ """
27
+ Your elicitation callback implementation.
28
+ This function receives a request for user input and returns the user's response.
29
+ """
30
+ # Display the message to the user and collect their input
31
+ print(f"Server requests: {params.message}")
32
+
33
+ # Example: Get user input (replace with your UI logic)
34
+ if hasattr(params, 'requestedSchema'):
35
+ # Handle structured input based on the schema
36
+ user_input = await collect_structured_input(params.requestedSchema)
37
+ else:
38
+ # Handle simple text input
39
+ user_input = input("Please provide your response: ")
40
+
41
+ # Return the result
42
+ return ElicitResult(
43
+ action="accept", # or "decline" or "cancel"
44
+ content=user_input
45
+ )
46
+
47
+ # Initialize client with elicitation support
48
+ client = MCPClient(
49
+ config="config.json",
50
+ elicitation_callback=elicitation_callback
51
+ )
52
+ ```
53
+
54
+ ## Handler Parameters
55
+
56
+ The elicitation handler receives two parameters:
57
+
58
+ ### Elicitation Handler Parameters
59
+
60
+ | Parameter | Type | Description |
61
+ |-----------|------|-------------|
62
+ | **context** | `RequestContext` | Request context containing metadata about the elicitation request |
63
+ | **params** | `ElicitRequestParams` | The MCP elicitation request parameters containing the message and optional schema |
64
+
65
+ #### ElicitRequestParams Structure
66
+
67
+ | Field | Type | Description |
68
+ |-------|------|-------------|
69
+ | **message** | `str` | The prompt message to display to the user |
70
+ | **requestedSchema** | `dict \| None` | Optional JSON schema defining the expected response structure |
71
+
72
+ ### Response Structure
73
+
74
+ The handler must return an `ElicitResult` object that specifies how the user responded:
75
+
76
+ #### ElicitResult Structure
77
+
78
+ | Field | Type | Description |
79
+ |-------|------|-------------|
80
+ | **action** | `Literal['accept', 'decline', 'cancel']` | How the user responded to the elicitation request |
81
+ | **content** | `dict \| str \| None` | The user's input data (required for "accept", omitted for "decline"/"cancel") |
82
+
83
+ #### Action Types:
84
+
85
+ - **accept**: User provided valid input - include their data in the `content` field
86
+ - **decline**: User chose not to provide the requested information - omit `content`
87
+ - **cancel**: User cancelled the entire operation - omit `content`
88
+
89
+ ### Example Parameter Usage
90
+
91
+ ```python
92
+ async def detailed_elicitation_callback(
93
+ context: RequestContext,
94
+ params: ElicitRequestParams
95
+ ) -> ElicitResult:
96
+ """Example showing how to use all parameters."""
97
+
98
+ # Access the user message
99
+ user_message = params.message
100
+ print(f"Request: {user_message}")
101
+
102
+ # Check if schema is provided for structured data
103
+ schema = getattr(params, 'requestedSchema', None)
104
+
105
+ if schema:
106
+ # Handle structured input
107
+ schema_type = schema.get('type')
108
+ properties = schema.get('properties', {})
109
+ required_fields = schema.get('required', [])
110
+
111
+ print(f"Expecting {schema_type} with fields: {list(properties.keys())}")
112
+ print(f"Required fields: {required_fields}")
113
+
114
+ # Collect structured data
115
+ user_data = {}
116
+ for field_name, field_def in properties.items():
117
+ field_type = field_def.get('type', 'string')
118
+ description = field_def.get('description', '')
119
+
120
+ prompt = f"Enter {field_name}"
121
+ if description:
122
+ prompt += f" ({description})"
123
+ prompt += ": "
124
+
125
+ value = input(prompt)
126
+
127
+ # Basic type conversion
128
+ if field_type == 'number':
129
+ value = float(value) if value else None
130
+ elif field_type == 'integer':
131
+ value = int(value) if value else None
132
+ elif field_type == 'boolean':
133
+ value = value.lower() in ('true', '1', 'yes') if value else None
134
+
135
+ user_data[field_name] = value
136
+
137
+ # Validate required fields
138
+ missing = [f for f in required_fields if not user_data.get(f)]
139
+ if missing:
140
+ print(f"Missing required fields: {missing}")
141
+ return ElicitResult(action="cancel")
142
+
143
+ return ElicitResult(action="accept", content=user_data)
144
+
145
+ else:
146
+ # Handle simple text input
147
+ response = input(f"{user_message}: ")
148
+ if not response:
149
+ return ElicitResult(action="cancel")
150
+
151
+ return ElicitResult(action="accept", content=response)
152
+ ```
153
+
154
+ ## Response Actions
155
+
156
+ Elicitation responses use a three-action model to clearly distinguish between different user intentions:
157
+
158
+ ### Accept
159
+ User explicitly approved and submitted data:
160
+ ```python
161
+ return ElicitResult(
162
+ action="accept",
163
+ content={"name": "John Doe", "email": "john@example.com"}
164
+ )
165
+ ```
166
+
167
+ ### Decline
168
+ User explicitly declined the request:
169
+ ```python
170
+ return ElicitResult(
171
+ action="decline"
172
+ # content field is typically omitted
173
+ )
174
+ ```
175
+
176
+ ### Cancel
177
+ User dismissed without making an explicit choice:
178
+ ```python
179
+ return ElicitResult(
180
+ action="cancel"
181
+ # content field is typically omitted
182
+ )
183
+ ```
184
+
185
+ ## Structured Data Requests
186
+
187
+ MCP tools can request structured data using JSON schemas. The schema defines the expected format and validation rules:
188
+
189
+ ```python
190
+ async def advanced_elicitation_callback(
191
+ context: RequestContext,
192
+ params: ElicitRequestParams
193
+ ) -> ElicitResult:
194
+ """Handle structured data requests with validation."""
195
+
196
+ # Check if a schema is provided
197
+ if hasattr(params, 'requestedSchema') and params.requestedSchema:
198
+ schema = params.requestedSchema
199
+
200
+ # Example: Handle different schema types
201
+ if schema.get('type') == 'object':
202
+ properties = schema.get('properties', {})
203
+ required_fields = schema.get('required', [])
204
+
205
+ # Collect data for each property
206
+ user_data = {}
207
+ for field_name, field_schema in properties.items():
208
+ field_type = field_schema.get('type', 'string')
209
+ field_description = field_schema.get('description', '')
210
+
211
+ print(f"{field_name} ({field_type}): {field_description}")
212
+
213
+ # Collect input based on field type
214
+ if field_type == 'string':
215
+ value = input(f"Enter {field_name}: ")
216
+ elif field_type == 'number':
217
+ value = float(input(f"Enter {field_name}: "))
218
+ elif field_type == 'boolean':
219
+ value = input(f"Enter {field_name} (true/false): ").lower() == 'true'
220
+ elif field_type == 'integer':
221
+ value = int(input(f"Enter {field_name}: "))
222
+ else:
223
+ value = input(f"Enter {field_name}: ")
224
+
225
+ user_data[field_name] = value
226
+
227
+ # Basic validation for required fields
228
+ missing_fields = [field for field in required_fields if field not in user_data or not user_data[field]]
229
+ if missing_fields:
230
+ print(f"Missing required fields: {missing_fields}")
231
+ return ElicitResult(action="cancel")
232
+
233
+ return ElicitResult(action="accept", content=user_data)
234
+
235
+ # Fallback to simple text input
236
+ response = input(f"{params.message}: ")
237
+ return ElicitResult(action="accept", content=response)
238
+ ```
239
+
240
+ ## Creating Elicitation-Enabled Tools
241
+
242
+ When building MCP servers, tools can request user input using the context parameter:
243
+
244
+ ```python
245
+ from fastmcp import Context, FastMCP
246
+
247
+ mcp = FastMCP(name="MyServer")
248
+
249
+ @mcp.tool
250
+ async def purchase_item(ctx: Context) -> str:
251
+ """Purchase an item with user-provided details."""
252
+
253
+ # Define the schema for purchase information
254
+ purchase_schema = {
255
+ "type": "object",
256
+ "properties": {
257
+ "quantity": {
258
+ "type": "number",
259
+ "minimum": 1,
260
+ "description": "Number of items to purchase"
261
+ },
262
+ "unit": {
263
+ "type": "string",
264
+ "enum": ["kg", "lbs", "pieces"],
265
+ "description": "Unit of measurement"
266
+ },
267
+ "item_name": {
268
+ "type": "string",
269
+ "description": "Name of the item to purchase"
270
+ }
271
+ },
272
+ "required": ["quantity", "unit", "item_name"]
273
+ }
274
+
275
+ # Request purchase details from the user
276
+ result = await ctx.elicit(
277
+ message="Please provide purchase details",
278
+ response_type=purchase_schema
279
+ )
280
+
281
+ # Handle different response actions
282
+ if result.action == "accept":
283
+ data = result.data
284
+ return f"Purchasing {data['quantity']} {data['unit']} of {data['item_name']}"
285
+ elif result.action == "decline":
286
+ return "Purchase declined by user"
287
+ else:
288
+ return "Purchase cancelled"
289
+
290
+ @mcp.tool
291
+ async def collect_feedback(ctx: Context) -> str:
292
+ """Collect user feedback with a simple text request."""
293
+
294
+ result = await ctx.elicit(
295
+ message="Please provide your feedback about our service"
296
+ )
297
+
298
+ if result.action == "accept":
299
+ return f"Thank you for your feedback: {result.data}"
300
+ else:
301
+ return "No feedback provided"
302
+ ```
303
+
304
+ ## Integration with MCPAgent
305
+
306
+ When using elicitation with MCPAgent, the elicitation callback is automatically used during tool execution:
307
+
308
+ ```python
309
+ import asyncio
310
+ from mcp_use import MCPAgent, MCPClient
311
+ from langchain_openai import ChatOpenAI
312
+
313
+ async def main():
314
+ # Define elicitation callback
315
+ async def handle_user_input(ctx, params):
316
+ # Your UI logic here - this example uses simple input
317
+ print(f"\n🤖 Server Request: {params.message}")
318
+
319
+ if hasattr(params, 'requestedSchema') and params.requestedSchema:
320
+ # Handle structured input
321
+ schema = params.requestedSchema
322
+ if schema.get('type') == 'object':
323
+ data = {}
324
+ for field, field_schema in schema.get('properties', {}).items():
325
+ value = input(f"Enter {field}: ")
326
+ data[field] = value
327
+ return ElicitResult(action="accept", content=data)
328
+
329
+ # Simple text input
330
+ response = input("Your response: ")
331
+ return ElicitResult(action="accept", content=response)
332
+
333
+ # Create client with elicitation support
334
+ client = MCPClient.from_config_file(
335
+ "config.json",
336
+ elicitation_callback=handle_user_input
337
+ )
338
+
339
+ # Create agent
340
+ llm = ChatOpenAI(model="gpt-4")
341
+ agent = MCPAgent(llm=llm, client=client)
342
+
343
+ # Run agent - tools can now request user input
344
+ result = await agent.run("Help me purchase some items from the store")
345
+ print(result)
346
+
347
+ if __name__ == "__main__":
348
+ asyncio.run(main())
349
+ ```
350
+
351
+ ## Error Handling
352
+
353
+ If no elicitation callback is provided but a tool requests user input:
354
+
355
+ ```python
356
+ # Without elicitation callback
357
+ client = MCPClient(config="config.json") # No elicitation_callback
358
+
359
+ # Tool that requires elicitation will return an error
360
+ session = client.get_session("server_name")
361
+ result = await session.connector.call_tool("purchase_item", {})
362
+ # This will fail because no elicitation callback is configured
363
+ ```