deepset-mcp 0.0.2rc1__tar.gz → 0.0.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.
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.github/workflows/pypi_release.yml +5 -28
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/PKG-INFO +12 -15
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/README.md +9 -13
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/pyproject.toml +2 -1
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline_template/models.py +29 -2
- deepset_mcp-0.0.3/src/deepset_mcp/config.py +25 -0
- deepset_mcp-0.0.3/src/deepset_mcp/main.py +184 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tool_factory.py +53 -35
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/doc_search.py +0 -25
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/pipeline_template.py +23 -14
- deepset_mcp-0.0.3/src/deepset_mcp/tools/secrets.py +98 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_pipeline_template_resource.py +83 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/pipeline_template/test_pipeline_template_resource.py +125 -2
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_doc_search.py +5 -119
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_pipeline_template.py +227 -34
- deepset_mcp-0.0.3/test/unit/tools/test_secrets.py +286 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/uv.lock +62 -4
- deepset_mcp-0.0.2rc1/src/deepset_mcp/main.py +0 -133
- deepset_mcp-0.0.2rc1/src/deepset_mcp/tools/secrets.py +0 -45
- deepset_mcp-0.0.2rc1/test/unit/tools/test_secrets.py +0 -180
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.github/workflows/ai_agent.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.github/workflows/ci.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.github/workflows/docker_push.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.gitignore +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/.python-version +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/Dockerfile +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/Makefile +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/REPO.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/assets/claude_desktop_projects.png +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/assets/claude_desktop_with_tools.png +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/assets/deepset-mcp-3.gif +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/entrypoint.sh +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/debugging/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/debugging/debugging_agent.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/debugging/system_prompt.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/generalist/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/generalist/generalist_agent.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/agents/generalist/system_prompt.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/README.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/client.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/custom_components/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/custom_components/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/custom_components/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/custom_components/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/exceptions.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/haystack_service/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/haystack_service/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/haystack_service/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/indexes/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/indexes/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/indexes/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/indexes/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/integrations/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/integrations/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/integrations/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/integrations/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline/log_level.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline_template/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline_template/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/pipeline_template/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/secrets/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/secrets/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/secrets/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/secrets/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/shared_models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/transport.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/user/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/user/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/user/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/workspace/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/workspace/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/workspace/protocols.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/api/workspace/resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/README.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/agent_configs/debugging_agent.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/agent_configs/generalist_agent.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/dp_validation_error_analysis/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/dp_validation_error_analysis/eda.ipynb +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/dp_validation_error_analysis/prepare_interaction_data.ipynb +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/dp_validation_error_analysis/preprocessing_utils.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/agent_benchmark_runner.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/agent_loader.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli_agent.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli_index.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli_pipeline.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli_tests.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/cli_utils.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/config.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/config_loader.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/interactive.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/repl.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/setup_actions.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/streaming.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/teardown_actions.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/runner/tracing.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/chat_rag_answers_wrong_format.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/documents_output_wrong.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/jinja_str_instead_of_complex_type.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/jinja_syntax_error.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/missing_output_mapping.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/no_query_input.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/chat_agent_jinja_str.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/chat_agent_jinja_syntax.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/chat_rag_answers_wrong_format.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/chat_rag_missing_output_mapping.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/rag_documents_wrong_format.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/rag_no_query_input.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/benchmark/tasks/pipelines/standard_index.yml +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/initialize_embedding_model.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/prompts/deepset_copilot_prompt.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/prompts/deepset_debugging_agent.md +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/store.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/custom_components.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/haystack_service.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/haystack_service_models.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/indexes.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/model_protocol.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/pipeline.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/tokonomics/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/tokonomics/decorators.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/tokonomics/explorer.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/tokonomics/object_store.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/src/deepset_mcp/tools/workspace.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/conftest.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_haystack_service_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_index_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_integrations_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_pipeline_logs.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_pipeline_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_secret_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/integration/test_integration_workspace_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/custom_components/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/custom_components/test_custom_components_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/haystack_service/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/haystack_service/test_haystack_service_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/indexes/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/indexes/test_index_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/integrations/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/integrations/test_integration_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/pipeline/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/pipeline/test_pipeline_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/pipeline/test_pipeline_resource_search.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/pipeline_template/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/secrets/test_secret_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/test_transport.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/user/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/user/test_user_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/workspace/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/api/workspace/test_workspace_resource.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/conftest.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/test_async_deepset_client.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_custom_components.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_haystack_service.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_indexes.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_pipeline.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/test_workspace.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/__init__.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_decorators.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_explorable.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_explorer.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_integration.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_object_ref.py +0 -0
- {deepset_mcp-0.0.2rc1 → deepset_mcp-0.0.3}/test/unit/tools/tokonomics/test_object_store.py +0 -0
|
@@ -12,14 +12,12 @@ jobs:
|
|
|
12
12
|
- uses: actions/checkout@v4
|
|
13
13
|
with:
|
|
14
14
|
persist-credentials: false
|
|
15
|
-
- name: Set up Python
|
|
16
|
-
uses: actions/setup-python@v5
|
|
17
|
-
with:
|
|
18
|
-
python-version: "3.x"
|
|
19
15
|
- name: Install uv
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
uses: astral-sh/setup-uv@v5
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
run: uv python install
|
|
19
|
+
- name: Install the project
|
|
20
|
+
run: uv sync --locked --all-extras --dev
|
|
23
21
|
- name: Build a binary wheel and a source tarball
|
|
24
22
|
run: uv build
|
|
25
23
|
- name: Store the distribution packages
|
|
@@ -47,24 +45,3 @@ jobs:
|
|
|
47
45
|
path: dist/
|
|
48
46
|
- name: Publish distribution to PyPI
|
|
49
47
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
50
|
-
publish-to-testpypi:
|
|
51
|
-
name: Publish deepset-mcp distribution to TestPyPI
|
|
52
|
-
if: startsWith(github.ref, 'refs/tags/') # only publish to TestPyPI on tag pushes
|
|
53
|
-
needs:
|
|
54
|
-
- build
|
|
55
|
-
runs-on: ubuntu-latest
|
|
56
|
-
environment:
|
|
57
|
-
name: testpypi
|
|
58
|
-
url: https://test.pypi.org/p/deepset-mcp
|
|
59
|
-
permissions:
|
|
60
|
-
id-token: write # IMPORTANT: mandatory for trusted publishing
|
|
61
|
-
steps:
|
|
62
|
-
- name: Download all the dists
|
|
63
|
-
uses: actions/download-artifact@v4
|
|
64
|
-
with:
|
|
65
|
-
name: python-package-distributions
|
|
66
|
-
path: dist/
|
|
67
|
-
- name: Publish distribution to TestPyPI
|
|
68
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
69
|
-
with:
|
|
70
|
-
repository-url: https://test.pypi.org/legacy/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: deepset-mcp
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.3
|
|
4
4
|
Summary: Collection of MCP tools and Agents to work with the deepset AI platform. Create, debug or learn about pipelines on the platform. Useable from the CLI, Cursor, Claude Code, or other MCP clients.
|
|
5
5
|
Project-URL: Homepage, https://deepset.ai
|
|
6
6
|
Author-email: Mathis Lucka <mathis.lucka@deepset.ai>, Tanay Soni <tanay.soni@deepset.ai>
|
|
@@ -18,10 +18,11 @@ Requires-Python: >=3.11
|
|
|
18
18
|
Requires-Dist: fastapi
|
|
19
19
|
Requires-Dist: glom
|
|
20
20
|
Requires-Dist: httpx
|
|
21
|
-
Requires-Dist: mcp
|
|
21
|
+
Requires-Dist: mcp>=1.10.1
|
|
22
22
|
Requires-Dist: model2vec
|
|
23
23
|
Requires-Dist: numpy
|
|
24
24
|
Requires-Dist: pydantic>=2.0.0
|
|
25
|
+
Requires-Dist: pyjwt[crypto]
|
|
25
26
|
Requires-Dist: pyyaml
|
|
26
27
|
Requires-Dist: rich
|
|
27
28
|
Provides-Extra: analysis
|
|
@@ -117,18 +118,14 @@ Agents can use these tools to:
|
|
|
117
118
|
Running the server with uv gives you faster startup time and consumes slightly less resources on your system.
|
|
118
119
|
|
|
119
120
|
1. [Install uv](https://docs.astral.sh/uv/guides/install-python/) if you don't have it yet
|
|
120
|
-
2.
|
|
121
|
-
3. Put the following into your `claude_desktop_config.json`
|
|
121
|
+
2. Put the following into your `claude_desktop_config.json`
|
|
122
122
|
|
|
123
123
|
```python
|
|
124
124
|
{
|
|
125
125
|
"mcpServers": {
|
|
126
126
|
"deepset": {
|
|
127
|
-
"command": "
|
|
127
|
+
"command": "uvx",
|
|
128
128
|
"args": [
|
|
129
|
-
"--directory",
|
|
130
|
-
"/path/to/your/clone/of/deepset-mcp-server", # path to your clone of the deepset-mcp-server repo
|
|
131
|
-
"run",
|
|
132
129
|
"deepset-mcp"
|
|
133
130
|
],
|
|
134
131
|
"env": {
|
|
@@ -141,7 +138,10 @@ Running the server with uv gives you faster startup time and consumes slightly l
|
|
|
141
138
|
}
|
|
142
139
|
```
|
|
143
140
|
|
|
144
|
-
|
|
141
|
+
This will load the [deepset-mcp package from PyPi](https://pypi.org/project/deepset-mcp/) and install it into a temporary virtual environment.
|
|
142
|
+
|
|
143
|
+
3. Quit and start the Claude Desktop App
|
|
144
|
+
|
|
145
145
|
|
|
146
146
|
|
|
147
147
|
### Other MCP Clients
|
|
@@ -156,7 +156,7 @@ Here is where you need to configure `deepset-mcp` for:
|
|
|
156
156
|
|
|
157
157
|
Generally speaking, depending on your installation, you need to configure an MCP client with one of the following commands:
|
|
158
158
|
|
|
159
|
-
`
|
|
159
|
+
`uvx deepset-mcp --workspace your_workspace --api-key your_api_key`
|
|
160
160
|
|
|
161
161
|
If you installed the deepset-mcp package globally and added it to your `PATH`, you can just run:
|
|
162
162
|
|
|
@@ -192,11 +192,8 @@ For example:
|
|
|
192
192
|
{
|
|
193
193
|
"mcpServers": {
|
|
194
194
|
"deepset": {
|
|
195
|
-
"command": "
|
|
195
|
+
"command": "uvx",
|
|
196
196
|
"args": [
|
|
197
|
-
"--directory",
|
|
198
|
-
"/path/to/your/clone/of/deepset-mcp-server",
|
|
199
|
-
"run",
|
|
200
197
|
"deepset-mcp",
|
|
201
198
|
"--workspace-mode",
|
|
202
199
|
"explicit"
|
|
@@ -272,7 +269,7 @@ If your pipeline is not deployed yet, the LLM can autonomously validate it and f
|
|
|
272
269
|
## CLI
|
|
273
270
|
You can use the MCP server as a Haystack Agent through a command-line interface.
|
|
274
271
|
|
|
275
|
-
Install with `
|
|
272
|
+
Install with `uvx tool install "deepset-mcp[cli]"`.
|
|
276
273
|
|
|
277
274
|
Start the interactive CLI with:
|
|
278
275
|
|
|
@@ -78,18 +78,14 @@ Agents can use these tools to:
|
|
|
78
78
|
Running the server with uv gives you faster startup time and consumes slightly less resources on your system.
|
|
79
79
|
|
|
80
80
|
1. [Install uv](https://docs.astral.sh/uv/guides/install-python/) if you don't have it yet
|
|
81
|
-
2.
|
|
82
|
-
3. Put the following into your `claude_desktop_config.json`
|
|
81
|
+
2. Put the following into your `claude_desktop_config.json`
|
|
83
82
|
|
|
84
83
|
```python
|
|
85
84
|
{
|
|
86
85
|
"mcpServers": {
|
|
87
86
|
"deepset": {
|
|
88
|
-
"command": "
|
|
87
|
+
"command": "uvx",
|
|
89
88
|
"args": [
|
|
90
|
-
"--directory",
|
|
91
|
-
"/path/to/your/clone/of/deepset-mcp-server", # path to your clone of the deepset-mcp-server repo
|
|
92
|
-
"run",
|
|
93
89
|
"deepset-mcp"
|
|
94
90
|
],
|
|
95
91
|
"env": {
|
|
@@ -102,7 +98,10 @@ Running the server with uv gives you faster startup time and consumes slightly l
|
|
|
102
98
|
}
|
|
103
99
|
```
|
|
104
100
|
|
|
105
|
-
|
|
101
|
+
This will load the [deepset-mcp package from PyPi](https://pypi.org/project/deepset-mcp/) and install it into a temporary virtual environment.
|
|
102
|
+
|
|
103
|
+
3. Quit and start the Claude Desktop App
|
|
104
|
+
|
|
106
105
|
|
|
107
106
|
|
|
108
107
|
### Other MCP Clients
|
|
@@ -117,7 +116,7 @@ Here is where you need to configure `deepset-mcp` for:
|
|
|
117
116
|
|
|
118
117
|
Generally speaking, depending on your installation, you need to configure an MCP client with one of the following commands:
|
|
119
118
|
|
|
120
|
-
`
|
|
119
|
+
`uvx deepset-mcp --workspace your_workspace --api-key your_api_key`
|
|
121
120
|
|
|
122
121
|
If you installed the deepset-mcp package globally and added it to your `PATH`, you can just run:
|
|
123
122
|
|
|
@@ -153,11 +152,8 @@ For example:
|
|
|
153
152
|
{
|
|
154
153
|
"mcpServers": {
|
|
155
154
|
"deepset": {
|
|
156
|
-
"command": "
|
|
155
|
+
"command": "uvx",
|
|
157
156
|
"args": [
|
|
158
|
-
"--directory",
|
|
159
|
-
"/path/to/your/clone/of/deepset-mcp-server",
|
|
160
|
-
"run",
|
|
161
157
|
"deepset-mcp",
|
|
162
158
|
"--workspace-mode",
|
|
163
159
|
"explicit"
|
|
@@ -233,7 +229,7 @@ If your pipeline is not deployed yet, the LLM can autonomously validate it and f
|
|
|
233
229
|
## CLI
|
|
234
230
|
You can use the MCP server as a Haystack Agent through a command-line interface.
|
|
235
231
|
|
|
236
|
-
Install with `
|
|
232
|
+
Install with `uvx tool install "deepset-mcp[cli]"`.
|
|
237
233
|
|
|
238
234
|
Start the interactive CLI with:
|
|
239
235
|
|
|
@@ -37,7 +37,7 @@ requires-python = ">=3.11"
|
|
|
37
37
|
|
|
38
38
|
dependencies = [
|
|
39
39
|
"fastapi",
|
|
40
|
-
"mcp",
|
|
40
|
+
"mcp>=1.10.1",
|
|
41
41
|
"httpx",
|
|
42
42
|
"pydantic>=2.0.0",
|
|
43
43
|
"pyyaml",
|
|
@@ -45,6 +45,7 @@ dependencies = [
|
|
|
45
45
|
"model2vec",
|
|
46
46
|
"glom",
|
|
47
47
|
"rich",
|
|
48
|
+
"pyjwt[crypto]",
|
|
48
49
|
]
|
|
49
50
|
|
|
50
51
|
[project.urls]
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from enum import StrEnum
|
|
2
|
+
from typing import Any
|
|
2
3
|
from uuid import UUID
|
|
3
4
|
|
|
4
|
-
from pydantic import BaseModel, Field
|
|
5
|
+
from pydantic import BaseModel, Field, model_validator
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class PipelineType(StrEnum):
|
|
@@ -28,10 +29,36 @@ class PipelineTemplate(BaseModel):
|
|
|
28
29
|
display_name: str = Field(alias="name")
|
|
29
30
|
pipeline_template_id: UUID = Field(alias="pipeline_template_id")
|
|
30
31
|
potential_applications: list[str] = Field(alias="potential_applications")
|
|
31
|
-
yaml_config: str | None =
|
|
32
|
+
yaml_config: str | None = None
|
|
32
33
|
tags: list[PipelineTemplateTag]
|
|
33
34
|
pipeline_type: PipelineType
|
|
34
35
|
|
|
36
|
+
@model_validator(mode="before")
|
|
37
|
+
@classmethod
|
|
38
|
+
def populate_yaml_config(cls, values: Any) -> Any:
|
|
39
|
+
"""Populate yaml_config from query_yaml or indexing_yaml based on pipeline_type."""
|
|
40
|
+
if not isinstance(values, dict):
|
|
41
|
+
return values
|
|
42
|
+
|
|
43
|
+
# Skip if yaml_config is already set
|
|
44
|
+
if values.get("yaml_config") is not None:
|
|
45
|
+
return values
|
|
46
|
+
|
|
47
|
+
# Get pipeline_type from the model data
|
|
48
|
+
pipeline_type = values.get("pipeline_type")
|
|
49
|
+
|
|
50
|
+
if pipeline_type == PipelineType.INDEXING or pipeline_type == "indexing":
|
|
51
|
+
yaml_config = values.get("indexing_yaml")
|
|
52
|
+
elif pipeline_type == PipelineType.QUERY or pipeline_type == "query":
|
|
53
|
+
yaml_config = values.get("query_yaml")
|
|
54
|
+
else:
|
|
55
|
+
yaml_config = None
|
|
56
|
+
|
|
57
|
+
if yaml_config is not None:
|
|
58
|
+
values["yaml_config"] = yaml_config
|
|
59
|
+
|
|
60
|
+
return values
|
|
61
|
+
|
|
35
62
|
|
|
36
63
|
class PipelineTemplateList(BaseModel):
|
|
37
64
|
"""Response model for listing pipeline templates."""
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""This module contains static configuration for the deepset MCP server."""
|
|
2
|
+
|
|
3
|
+
# We need this mapping to which environment variables integrations are mapped to
|
|
4
|
+
# The mapping is maintained in the pipeline operator:
|
|
5
|
+
# https://github.com/deepset-ai/dc-pipeline-operator/blob/main/dc_operators/config.py#L279
|
|
6
|
+
TOKEN_DOMAIN_MAPPING = {
|
|
7
|
+
"huggingface.co": ["HF_API_TOKEN", "HF_TOKEN"],
|
|
8
|
+
"api.openai.com": ["OPENAI_API_KEY"],
|
|
9
|
+
"bedrock.amazonaws.com": ["BEDROCK"],
|
|
10
|
+
"api.cohere.ai": ["COHERE_API_KEY"],
|
|
11
|
+
"openai.azure.com": ["AZURE_OPENAI_API_KEY"],
|
|
12
|
+
"cognitive-services.azure.com": ["AZURE_AI_API_KEY"],
|
|
13
|
+
"unstructured.io": ["UNSTRUCTURED_API_KEY"],
|
|
14
|
+
"api.deepl.com": ["DEEPL_API_KEY"],
|
|
15
|
+
"generativelanguage.googleapis.com": ["GOOGLE_API_KEY"],
|
|
16
|
+
"api.nvidia.com": ["NVIDIA_API_KEY"],
|
|
17
|
+
"api.voyageai.com": ["VOYAGE_API_KEY"],
|
|
18
|
+
"searchapi.io": ["SEARCHAPI_API_KEY"],
|
|
19
|
+
"snowflakecomputing.com": ["SNOWFLAKE_API_KEY"],
|
|
20
|
+
"wandb.ai": ["WANDB_API_KEY"],
|
|
21
|
+
"mongodb.com": ["MONGO_CONNECTION_STRING"],
|
|
22
|
+
"together.ai": ["TOGETHERAI_API_KEY"],
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
DEEPSET_DOCS_DEFAULT_SHARE_URL = "https://cloud.deepset.ai/shared_prototypes?share_token=prototype_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODM0MjE0OTguNTk5LCJhdWQiOiJleHRlcm5hbCB1c2VyIiwiaXNzIjoiZEMiLCJ3b3Jrc3BhY2VfaWQiOiI4YzI0ZjExMi1iMjljLTQ5MWMtOTkzOS1hZTkxMDRhNTQyMWMiLCJ3b3Jrc3BhY2VfbmFtZSI6ImRjLWRvY3MtY29udGVudCIsIm9yZ2FuaXphdGlvbl9pZCI6ImNhOWYxNGQ0LWMyYzktNDYwZC04ZDI2LWY4Y2IwYWNhMDI0ZiIsInNoYXJlX2lkIjoiY2Y3MTA3ODAtOThmNi00MzlmLThiNzYtMmMwNDkyODNiMDZhIiwibG9naW5fcmVxdWlyZWQiOmZhbHNlfQ.5j6DCNRQ1_KB8lhIJqHyw2hBIleEW1_Y_UBuH6MTYY0"
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from urllib.parse import parse_qs, urlparse
|
|
7
|
+
|
|
8
|
+
import jwt
|
|
9
|
+
from mcp.server.fastmcp import FastMCP
|
|
10
|
+
|
|
11
|
+
from deepset_mcp.api.client import AsyncDeepsetClient
|
|
12
|
+
from deepset_mcp.config import DEEPSET_DOCS_DEFAULT_SHARE_URL
|
|
13
|
+
from deepset_mcp.tool_factory import WorkspaceMode, register_tools
|
|
14
|
+
|
|
15
|
+
# Initialize MCP Server
|
|
16
|
+
mcp = FastMCP("Deepset Cloud MCP", settings={"log_level": "ERROR"})
|
|
17
|
+
|
|
18
|
+
logging.getLogger("uvicorn").setLevel(logging.WARNING)
|
|
19
|
+
logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
|
|
20
|
+
logging.getLogger("fastapi").setLevel(logging.WARNING)
|
|
21
|
+
logging.getLogger("httpx").setLevel(logging.WARNING)
|
|
22
|
+
logging.getLogger("httpcore").setLevel(logging.WARNING)
|
|
23
|
+
logging.getLogger("mcp").setLevel(logging.WARNING)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@mcp.prompt()
|
|
27
|
+
async def deepset_copilot() -> str:
|
|
28
|
+
"""System prompt for the deepset copilot."""
|
|
29
|
+
prompt_path = Path(__file__).parent / "prompts/deepset_copilot_prompt.md"
|
|
30
|
+
|
|
31
|
+
return prompt_path.read_text()
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@mcp.prompt()
|
|
35
|
+
async def deepset_recommended_prompt() -> str:
|
|
36
|
+
"""Recommended system prompt for the deepset copilot."""
|
|
37
|
+
prompt_path = Path(__file__).parent / "prompts/deepset_debugging_agent.md"
|
|
38
|
+
|
|
39
|
+
return prompt_path.read_text()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def fetch_shared_prototype_details(share_url: str) -> tuple[str, str, str]:
|
|
43
|
+
"""Gets the pipeline name, workspace name and an API token for a shared prototype url.
|
|
44
|
+
|
|
45
|
+
:param share_url: The URL of a shared prototype on the deepset platform.
|
|
46
|
+
|
|
47
|
+
:returns: A tuple containing the pipeline name, workspace name and an API token.
|
|
48
|
+
"""
|
|
49
|
+
parsed_url = urlparse(share_url)
|
|
50
|
+
query_params = parse_qs(parsed_url.query)
|
|
51
|
+
share_token = query_params.get("share_token", [None])[0]
|
|
52
|
+
if not share_token:
|
|
53
|
+
raise ValueError("Invalid share URL: missing share_token parameter.")
|
|
54
|
+
|
|
55
|
+
jwt_token = share_token.replace("prototype_", "")
|
|
56
|
+
|
|
57
|
+
decoded_token = jwt.decode(jwt_token, options={"verify_signature": False})
|
|
58
|
+
workspace_name = decoded_token.get("workspace_name")
|
|
59
|
+
if not workspace_name:
|
|
60
|
+
raise ValueError("Invalid JWT in share_token: missing 'workspace_name'.")
|
|
61
|
+
|
|
62
|
+
share_id = decoded_token.get("share_id")
|
|
63
|
+
if not share_id:
|
|
64
|
+
raise ValueError("Invalid JWT in share_token: missing 'share_id'.")
|
|
65
|
+
|
|
66
|
+
# For shared prototypes, we need to:
|
|
67
|
+
# 1. Fetch prototype details (pipeline name) using the information encoded in the JWT
|
|
68
|
+
# 2. Create a shared prototype user
|
|
69
|
+
async with AsyncDeepsetClient(api_key=share_token) as client:
|
|
70
|
+
response = await client.request(f"/v1/workspaces/{workspace_name}/shared_prototypes/{share_id}")
|
|
71
|
+
if not response.success:
|
|
72
|
+
raise ValueError(f"Failed to fetch shared prototype details: {response.status_code} {response.json}")
|
|
73
|
+
|
|
74
|
+
data = response.json or {}
|
|
75
|
+
pipeline_names: list[str] = data.get("pipeline_names", [])
|
|
76
|
+
if not pipeline_names:
|
|
77
|
+
raise ValueError("No pipeline names found in shared prototype response.")
|
|
78
|
+
|
|
79
|
+
user_info = await client.request("/v1/workspaces/dc-docs-content/shared_prototype_users", method="POST")
|
|
80
|
+
|
|
81
|
+
if not user_info.success:
|
|
82
|
+
raise ValueError("Failed to fetch user information from shared prototype response.")
|
|
83
|
+
|
|
84
|
+
user_data = user_info.json or {}
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
api_key = user_data["user_token"]
|
|
88
|
+
except KeyError:
|
|
89
|
+
raise ValueError("No user token in shared prototype response.") from None
|
|
90
|
+
|
|
91
|
+
return workspace_name, pipeline_names[0], api_key
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def main() -> None:
|
|
95
|
+
"""Entrypoint for the deepset MCP server."""
|
|
96
|
+
parser = argparse.ArgumentParser(description="Run the Deepset MCP server.")
|
|
97
|
+
parser.add_argument(
|
|
98
|
+
"--workspace",
|
|
99
|
+
"-w",
|
|
100
|
+
help="Deepset workspace (env DEEPSET_WORKSPACE)",
|
|
101
|
+
)
|
|
102
|
+
parser.add_argument(
|
|
103
|
+
"--api-key",
|
|
104
|
+
"-k",
|
|
105
|
+
help="Deepset API key (env DEEPSET_API_KEY)",
|
|
106
|
+
)
|
|
107
|
+
parser.add_argument(
|
|
108
|
+
"--docs-share-url",
|
|
109
|
+
default=DEEPSET_DOCS_DEFAULT_SHARE_URL,
|
|
110
|
+
help="Deepset docs search share URL (env DEEPSET_DOCS_SHARE_URL)",
|
|
111
|
+
)
|
|
112
|
+
parser.add_argument(
|
|
113
|
+
"--workspace-mode",
|
|
114
|
+
choices=[WorkspaceMode.STATIC, WorkspaceMode.DYNAMIC],
|
|
115
|
+
default=WorkspaceMode.STATIC,
|
|
116
|
+
help=(
|
|
117
|
+
"Whether workspace should be set statically or dynamically provided during a tool call. "
|
|
118
|
+
f"Default: '{WorkspaceMode.STATIC}'"
|
|
119
|
+
),
|
|
120
|
+
)
|
|
121
|
+
parser.add_argument(
|
|
122
|
+
"--tools",
|
|
123
|
+
nargs="*",
|
|
124
|
+
help="Space-separated list of tools to register (default: all)",
|
|
125
|
+
)
|
|
126
|
+
parser.add_argument(
|
|
127
|
+
"--list-tools",
|
|
128
|
+
action="store_true",
|
|
129
|
+
help="List all available tools and exit",
|
|
130
|
+
)
|
|
131
|
+
args = parser.parse_args()
|
|
132
|
+
|
|
133
|
+
# Handle --list-tools flag early
|
|
134
|
+
if args.list_tools:
|
|
135
|
+
from deepset_mcp.tool_factory import TOOL_REGISTRY
|
|
136
|
+
|
|
137
|
+
print("Available tools:")
|
|
138
|
+
for tool_name in sorted(TOOL_REGISTRY.keys()):
|
|
139
|
+
print(f" {tool_name}")
|
|
140
|
+
return
|
|
141
|
+
|
|
142
|
+
# prefer flags, fallback to env
|
|
143
|
+
workspace = args.workspace or os.getenv("DEEPSET_WORKSPACE")
|
|
144
|
+
api_key = args.api_key or os.getenv("DEEPSET_API_KEY")
|
|
145
|
+
docs_share_url = args.docs_share_url or os.getenv("DEEPSET_DOCS_SHARE_URL")
|
|
146
|
+
|
|
147
|
+
if docs_share_url:
|
|
148
|
+
try:
|
|
149
|
+
workspace_name, pipeline_name, api_key_docs = asyncio.run(fetch_shared_prototype_details(docs_share_url))
|
|
150
|
+
os.environ["DEEPSET_DOCS_WORKSPACE"] = workspace_name
|
|
151
|
+
os.environ["DEEPSET_DOCS_PIPELINE_NAME"] = pipeline_name
|
|
152
|
+
os.environ["DEEPSET_DOCS_API_KEY"] = api_key_docs
|
|
153
|
+
except (ValueError, jwt.DecodeError) as e:
|
|
154
|
+
parser.error(f"Error processing --docs-share-url: {e}")
|
|
155
|
+
|
|
156
|
+
# Create server configuration
|
|
157
|
+
workspace_mode = WorkspaceMode(args.workspace_mode)
|
|
158
|
+
|
|
159
|
+
if workspace_mode == WorkspaceMode.STATIC:
|
|
160
|
+
if not workspace:
|
|
161
|
+
parser.error("Missing workspace: set --workspace or DEEPSET_WORKSPACE")
|
|
162
|
+
|
|
163
|
+
if not api_key:
|
|
164
|
+
parser.error("Missing API key: set --api-key or DEEPSET_API_KEY")
|
|
165
|
+
|
|
166
|
+
# make sure downstream tools see them (for implicit mode)
|
|
167
|
+
if workspace:
|
|
168
|
+
os.environ["DEEPSET_WORKSPACE"] = workspace
|
|
169
|
+
os.environ["DEEPSET_API_KEY"] = api_key
|
|
170
|
+
|
|
171
|
+
# Parse tool names if provided
|
|
172
|
+
tool_names = None
|
|
173
|
+
if args.tools:
|
|
174
|
+
tool_names = set(args.tools)
|
|
175
|
+
|
|
176
|
+
# Register tools based on configuration
|
|
177
|
+
register_tools(mcp, workspace_mode, workspace, tool_names)
|
|
178
|
+
|
|
179
|
+
# run with SSE transport (HTTP+Server-Sent Events)
|
|
180
|
+
mcp.run(transport="stdio")
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
if __name__ == "__main__":
|
|
184
|
+
main()
|
|
@@ -19,7 +19,6 @@ from deepset_mcp.tools.custom_components import (
|
|
|
19
19
|
list_custom_component_installations as list_custom_component_installations_tool,
|
|
20
20
|
)
|
|
21
21
|
from deepset_mcp.tools.doc_search import (
|
|
22
|
-
get_docs_config,
|
|
23
22
|
search_docs as search_docs_tool,
|
|
24
23
|
)
|
|
25
24
|
from deepset_mcp.tools.haystack_service import (
|
|
@@ -48,9 +47,9 @@ from deepset_mcp.tools.pipeline import (
|
|
|
48
47
|
validate_pipeline as validate_pipeline_tool,
|
|
49
48
|
)
|
|
50
49
|
from deepset_mcp.tools.pipeline_template import (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
get_template as get_pipeline_template_tool,
|
|
51
|
+
list_templates as list_pipeline_templates_tool,
|
|
52
|
+
search_templates as search_pipeline_templates_tool,
|
|
54
53
|
)
|
|
55
54
|
from deepset_mcp.tools.secrets import (
|
|
56
55
|
get_secret as get_secret_tool,
|
|
@@ -63,6 +62,16 @@ from deepset_mcp.tools.workspace import (
|
|
|
63
62
|
list_workspaces as list_workspaces_tool,
|
|
64
63
|
)
|
|
65
64
|
|
|
65
|
+
|
|
66
|
+
def are_docs_available() -> bool:
|
|
67
|
+
"""Checks if documentation search is available."""
|
|
68
|
+
return bool(
|
|
69
|
+
os.environ.get("DEEPSET_DOCS_WORKSPACE", False)
|
|
70
|
+
and os.environ.get("DEEPSET_DOCS_PIPELINE_NAME", False)
|
|
71
|
+
and os.environ.get("DEEPSET_DOCS_API_KEY", False)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
|
|
66
75
|
EXPLORER = RichExplorer(store=STORE)
|
|
67
76
|
|
|
68
77
|
|
|
@@ -108,16 +117,11 @@ async def search_docs(query: str) -> str:
|
|
|
108
117
|
:param query: The search query to execute against the documentation.
|
|
109
118
|
:returns: The formatted search results from the documentation.
|
|
110
119
|
"""
|
|
111
|
-
|
|
112
|
-
if not docs_config:
|
|
113
|
-
raise RuntimeError("Documentation search configuration not available")
|
|
114
|
-
|
|
115
|
-
docs_workspace, docs_pipeline_name, docs_api_key = docs_config
|
|
116
|
-
async with AsyncDeepsetClient(api_key=docs_api_key) as client:
|
|
120
|
+
async with AsyncDeepsetClient(api_key=os.environ["DEEPSET_DOCS_API_KEY"]) as client:
|
|
117
121
|
response = await search_docs_tool(
|
|
118
122
|
client=client,
|
|
119
|
-
workspace=
|
|
120
|
-
pipeline_name=
|
|
123
|
+
workspace=os.environ["DEEPSET_DOCS_WORKSPACE"],
|
|
124
|
+
pipeline_name=os.environ["DEEPSET_DOCS_PIPELINE_NAME"],
|
|
121
125
|
query=query,
|
|
122
126
|
)
|
|
123
127
|
return response
|
|
@@ -126,8 +130,8 @@ async def search_docs(query: str) -> str:
|
|
|
126
130
|
class WorkspaceMode(StrEnum):
|
|
127
131
|
"""Configuration for how workspace is provided to tools."""
|
|
128
132
|
|
|
129
|
-
|
|
130
|
-
|
|
133
|
+
STATIC = "static" # workspace from env, no parameter in tool signature
|
|
134
|
+
DYNAMIC = "dynamic" # workspace as required parameter in tool signature
|
|
131
135
|
|
|
132
136
|
|
|
133
137
|
class MemoryType(StrEnum):
|
|
@@ -165,11 +169,21 @@ TOOL_REGISTRY: dict[str, tuple[Callable[..., Any], ToolConfig]] = {
|
|
|
165
169
|
),
|
|
166
170
|
"create_pipeline": (
|
|
167
171
|
create_pipeline_tool,
|
|
168
|
-
ToolConfig(
|
|
172
|
+
ToolConfig(
|
|
173
|
+
needs_client=True,
|
|
174
|
+
needs_workspace=True,
|
|
175
|
+
memory_type=MemoryType.BOTH,
|
|
176
|
+
custom_args={"skip_validation_errors": True},
|
|
177
|
+
),
|
|
169
178
|
),
|
|
170
179
|
"update_pipeline": (
|
|
171
180
|
update_pipeline_tool,
|
|
172
|
-
ToolConfig(
|
|
181
|
+
ToolConfig(
|
|
182
|
+
needs_client=True,
|
|
183
|
+
needs_workspace=True,
|
|
184
|
+
memory_type=MemoryType.BOTH,
|
|
185
|
+
custom_args={"skip_validation_errors": True},
|
|
186
|
+
),
|
|
173
187
|
),
|
|
174
188
|
"get_pipeline": (
|
|
175
189
|
get_pipeline_tool,
|
|
@@ -216,15 +230,20 @@ TOOL_REGISTRY: dict[str, tuple[Callable[..., Any], ToolConfig]] = {
|
|
|
216
230
|
deploy_index_tool,
|
|
217
231
|
ToolConfig(needs_client=True, needs_workspace=True, memory_type=MemoryType.EXPLORABLE),
|
|
218
232
|
),
|
|
219
|
-
"
|
|
233
|
+
"list_templates": (
|
|
220
234
|
list_pipeline_templates_tool,
|
|
221
|
-
ToolConfig(
|
|
235
|
+
ToolConfig(
|
|
236
|
+
needs_client=True,
|
|
237
|
+
needs_workspace=True,
|
|
238
|
+
memory_type=MemoryType.EXPLORABLE,
|
|
239
|
+
custom_args={"field": "created_at", "order": "DESC", "limit": 100},
|
|
240
|
+
),
|
|
222
241
|
),
|
|
223
|
-
"
|
|
242
|
+
"get_template": (
|
|
224
243
|
get_pipeline_template_tool,
|
|
225
244
|
ToolConfig(needs_client=True, needs_workspace=True, memory_type=MemoryType.EXPLORABLE),
|
|
226
245
|
),
|
|
227
|
-
"
|
|
246
|
+
"search_templates": (
|
|
228
247
|
search_pipeline_templates_tool,
|
|
229
248
|
ToolConfig(
|
|
230
249
|
needs_client=True,
|
|
@@ -290,8 +309,8 @@ def create_enhanced_tool(
|
|
|
290
309
|
Args:
|
|
291
310
|
base_func: The base tool function.
|
|
292
311
|
config: Tool configuration specifying dependencies and custom arguments.
|
|
293
|
-
workspace_mode: How the workspace should be handled
|
|
294
|
-
workspace: The workspace to use
|
|
312
|
+
workspace_mode: How the workspace should be handled.
|
|
313
|
+
workspace: The workspace to use when using a static workspace.
|
|
295
314
|
|
|
296
315
|
Returns:
|
|
297
316
|
An enhanced, awaitable tool function with an updated signature and docstring.
|
|
@@ -333,7 +352,7 @@ def create_enhanced_tool(
|
|
|
333
352
|
params_to_remove.update(config.custom_args.keys())
|
|
334
353
|
if config.needs_client:
|
|
335
354
|
params_to_remove.add("client")
|
|
336
|
-
if config.needs_workspace and workspace_mode == WorkspaceMode.
|
|
355
|
+
if config.needs_workspace and workspace_mode == WorkspaceMode.STATIC:
|
|
337
356
|
params_to_remove.add("workspace")
|
|
338
357
|
|
|
339
358
|
# Create the new signature from the original function
|
|
@@ -350,15 +369,15 @@ def create_enhanced_tool(
|
|
|
350
369
|
# Create the final wrapper function that handles client/workspace injection
|
|
351
370
|
if config.needs_client:
|
|
352
371
|
if config.needs_workspace:
|
|
353
|
-
if workspace_mode == WorkspaceMode.
|
|
372
|
+
if workspace_mode == WorkspaceMode.STATIC:
|
|
354
373
|
|
|
355
|
-
async def
|
|
374
|
+
async def workspace_environment_wrapper(**kwargs: Any) -> Any:
|
|
356
375
|
ws = workspace or get_workspace_from_env()
|
|
357
376
|
async with AsyncDeepsetClient() as client:
|
|
358
377
|
return await decorated_func(client=client, workspace=ws, **kwargs)
|
|
359
378
|
|
|
360
|
-
wrapper =
|
|
361
|
-
else: #
|
|
379
|
+
wrapper = workspace_environment_wrapper
|
|
380
|
+
else: # DYNAMIC mode
|
|
362
381
|
|
|
363
382
|
async def workspace_explicit_wrapper(**kwargs: Any) -> Any:
|
|
364
383
|
async with AsyncDeepsetClient() as client:
|
|
@@ -400,7 +419,7 @@ def create_enhanced_tool(
|
|
|
400
419
|
params_to_remove_from_doc = set()
|
|
401
420
|
if config.needs_client:
|
|
402
421
|
params_to_remove_from_doc.add("client")
|
|
403
|
-
if config.needs_workspace and workspace_mode == WorkspaceMode.
|
|
422
|
+
if config.needs_workspace and workspace_mode == WorkspaceMode.STATIC:
|
|
404
423
|
params_to_remove_from_doc.add("workspace")
|
|
405
424
|
if config.custom_args:
|
|
406
425
|
params_to_remove_from_doc.update(config.custom_args.keys())
|
|
@@ -428,11 +447,11 @@ def register_tools(
|
|
|
428
447
|
Args:
|
|
429
448
|
mcp: FastMCP server instance
|
|
430
449
|
workspace_mode: How workspace should be handled
|
|
431
|
-
workspace: Workspace to use for
|
|
450
|
+
workspace: Workspace to use for environment mode (if None, reads from env)
|
|
432
451
|
tool_names: Set of tool names to register (if None, registers all tools)
|
|
433
452
|
"""
|
|
434
453
|
# Check if docs search is available
|
|
435
|
-
docs_available =
|
|
454
|
+
docs_available = are_docs_available()
|
|
436
455
|
|
|
437
456
|
# Validate tool names if provided
|
|
438
457
|
if tool_names is not None:
|
|
@@ -446,8 +465,8 @@ def register_tools(
|
|
|
446
465
|
# Warn if search_docs was requested but config is missing
|
|
447
466
|
if "search_docs" in tool_names and not docs_available:
|
|
448
467
|
logging.warning(
|
|
449
|
-
"Documentation search tool requested but not available. To enable, set the
|
|
450
|
-
"
|
|
468
|
+
"Documentation search tool requested but not available. To enable, set the DEEPSET_DOCS_SHARE_URL "
|
|
469
|
+
"environment variable."
|
|
451
470
|
)
|
|
452
471
|
|
|
453
472
|
tools_to_register = tool_names.copy()
|
|
@@ -457,8 +476,7 @@ def register_tools(
|
|
|
457
476
|
# Warn if search_docs would be skipped in "all tools" mode
|
|
458
477
|
if not docs_available:
|
|
459
478
|
logging.warning(
|
|
460
|
-
"Documentation search tool not enabled. To enable, set the
|
|
461
|
-
"variables: DEEPSET_DOCS_WORKSPACE, DEEPSET_DOCS_PIPELINE_NAME, DEEPSET_DOCS_API_KEY"
|
|
479
|
+
"Documentation search tool not enabled. To enable, set the DEEPSET_DOCS_SHARE_URL environment variable."
|
|
462
480
|
)
|
|
463
481
|
|
|
464
482
|
# Remove search_docs if config is not available
|
|
@@ -470,4 +488,4 @@ def register_tools(
|
|
|
470
488
|
# Create enhanced tool
|
|
471
489
|
enhanced_tool = create_enhanced_tool(base_func, config, workspace_mode, workspace)
|
|
472
490
|
|
|
473
|
-
mcp.add_tool(enhanced_tool, name=tool_name)
|
|
491
|
+
mcp.add_tool(enhanced_tool, name=tool_name, structured_output=False)
|