devrev-Python-SDK 2.6.0__tar.gz → 2.7.0__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 (349) hide show
  1. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/Dockerfile +2 -2
  2. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/PKG-INFO +1 -1
  3. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/changelog.md +15 -0
  4. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/hooks/copy_llms.py +7 -8
  5. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/llms-ctx-full.txt +1 -1
  6. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/llms-ctx.txt +1 -1
  7. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/llms-mcp.txt +1 -1
  8. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/llms.txt +1 -1
  9. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/pyproject.toml +1 -1
  10. devrev_python_sdk-2.7.0/src/devrev_mcp/resources/server_info.py +42 -0
  11. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/server.py +8 -0
  12. devrev_python_sdk-2.7.0/src/devrev_mcp/tools/server_info.py +108 -0
  13. devrev_python_sdk-2.7.0/tests/unit/mcp/test_server_info.py +336 -0
  14. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/bug-fixer.md +0 -0
  15. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/builder.md +0 -0
  16. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/documentation.md +0 -0
  17. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/foreman.md +0 -0
  18. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/pr-review-boss.md +0 -0
  19. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/release-manager.md +0 -0
  20. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/simplifier.md +0 -0
  21. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/agents/tester.md +0 -0
  22. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/commands/foreman-work.md +0 -0
  23. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/commands/release-prepare.md +0 -0
  24. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/commands/review-start.md +0 -0
  25. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/commands/simplify-code.md +0 -0
  26. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/code-quality.md +0 -0
  27. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/data-modeling.md +0 -0
  28. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/devrev-sdk.md +0 -0
  29. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/git-workflow.md +0 -0
  30. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/pull-requests.md +0 -0
  31. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/python-development.md +0 -0
  32. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/security.md +0 -0
  33. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.augment/rules/testing.md +0 -0
  34. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.dockerignore +0 -0
  35. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.env.sample +0 -0
  36. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  37. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  38. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  39. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  40. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/dependabot.yml +0 -0
  41. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/pull_request_template.md +0 -0
  42. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/api-check.yml +0 -0
  43. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/ci.yml +0 -0
  44. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/claude-code-review.yml +0 -0
  45. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/claude.yml +0 -0
  46. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/deploy.yml +0 -0
  47. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/docs.yml +0 -0
  48. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/integration-tests.yml +0 -0
  49. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/release.yml +0 -0
  50. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.github/workflows/sync-openapi.yml +0 -0
  51. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.gitignore +0 -0
  52. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/.pre-commit-config.yaml +0 -0
  53. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/CODE_OF_CONDUCT.md +0 -0
  54. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/CONTRIBUTING.md +0 -0
  55. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/DEPRECATIONS.md +0 -0
  56. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/KNOWN_ISSUES.md +0 -0
  57. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/OPENAPI_SPEC_DISCREPANCIES.md +0 -0
  58. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/README.md +0 -0
  59. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/SECURITY.md +0 -0
  60. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/augment-mcp-config-remote.json +0 -0
  61. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/augment-mcp-config.json +0 -0
  62. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/augment-settings.json +0 -0
  63. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/benchmarks/README.md +0 -0
  64. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/benchmarks/bench_http_client.py +0 -0
  65. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/benchmarks/bench_models.py +0 -0
  66. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/benchmarks/bench_pagination.py +0 -0
  67. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/benchmarks/conftest.py +0 -0
  68. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/context7.json +0 -0
  69. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/README.md +0 -0
  70. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/audit-logging-setup.sh +0 -0
  71. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/cloudbuild.yaml +0 -0
  72. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/monitoring/README.md +0 -0
  73. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/monitoring/alert-policies.yaml +0 -0
  74. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/monitoring/dashboard.json +0 -0
  75. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/monitoring/validate-config.sh +0 -0
  76. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/deploy/service.yaml +0 -0
  77. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docker-compose.yml +0 -0
  78. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/brands.md +0 -0
  79. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/engagements.md +0 -0
  80. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/incidents.md +0 -0
  81. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/index.md +0 -0
  82. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/question-answers.md +0 -0
  83. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/recommendations.md +0 -0
  84. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/search.md +0 -0
  85. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta/uoms.md +0 -0
  86. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/beta-api-differences.md +0 -0
  87. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/client.md +0 -0
  88. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/config.md +0 -0
  89. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/exceptions.md +0 -0
  90. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/index.md +0 -0
  91. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/models/accounts.md +0 -0
  92. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/models/base.md +0 -0
  93. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/models/index.md +0 -0
  94. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/models/users.md +0 -0
  95. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/models/works.md +0 -0
  96. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/accounts.md +0 -0
  97. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/articles.md +0 -0
  98. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/code-changes.md +0 -0
  99. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/conversations.md +0 -0
  100. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/dev-users.md +0 -0
  101. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/groups.md +0 -0
  102. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/index.md +0 -0
  103. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/links.md +0 -0
  104. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/parts.md +0 -0
  105. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/rev-users.md +0 -0
  106. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/slas.md +0 -0
  107. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/tags.md +0 -0
  108. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/timeline-entries.md +0 -0
  109. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/webhooks.md +0 -0
  110. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/api/services/works.md +0 -0
  111. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/examples/advanced.md +0 -0
  112. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/examples/basic.md +0 -0
  113. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/examples/beta-features.md +0 -0
  114. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/examples/index.md +0 -0
  115. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/examples/integrations.md +0 -0
  116. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/getting-started/authentication.md +0 -0
  117. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/getting-started/index.md +0 -0
  118. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/getting-started/installation.md +0 -0
  119. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/getting-started/quickstart.md +0 -0
  120. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/beta-api.md +0 -0
  121. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/compatibility.md +0 -0
  122. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/configuration.md +0 -0
  123. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/error-handling.md +0 -0
  124. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/github-actions-setup.md +0 -0
  125. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/index.md +0 -0
  126. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/logging.md +0 -0
  127. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/pagination.md +0 -0
  128. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/sync-vs-async.md +0 -0
  129. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/testing.md +0 -0
  130. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/version-support.md +0 -0
  131. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/guides/write-integration-testing-strategy.md +0 -0
  132. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/index.md +0 -0
  133. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/mcp/deployment.md +0 -0
  134. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/mcp/index.md +0 -0
  135. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/mcp/quickstart.md +0 -0
  136. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/mcp/tools-reference.md +0 -0
  137. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/docs/stylesheets/extra.css +0 -0
  138. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/README.md +0 -0
  139. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/README.md +0 -0
  140. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/async_example.py +0 -0
  141. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/create_work.py +0 -0
  142. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/error_handling.py +0 -0
  143. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/list_accounts.py +0 -0
  144. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/pagination.py +0 -0
  145. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/basic/search_users.py +0 -0
  146. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/cloud_functions/README.md +0 -0
  147. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/cloud_functions/main.py +0 -0
  148. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/cloud_functions/requirements.txt +0 -0
  149. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/fastapi/README.md +0 -0
  150. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/fastapi/main.py +0 -0
  151. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/fastapi/requirements.txt +0 -0
  152. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/flask/README.md +0 -0
  153. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/flask/app.py +0 -0
  154. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/examples/integrations/flask/requirements.txt +0 -0
  155. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/mkdocs.yml +0 -0
  156. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/openapi-beta.yaml +0 -0
  157. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/openapi-public.yaml +0 -0
  158. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/openapi-spec-corrections.yaml +0 -0
  159. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/scripts/build_ai_docs.py +0 -0
  160. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/scripts/setup-github-secrets.sh +0 -0
  161. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/__init__.py +0 -0
  162. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/client.py +0 -0
  163. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/config.py +0 -0
  164. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/exceptions.py +0 -0
  165. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/__init__.py +0 -0
  166. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/accounts.py +0 -0
  167. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/articles.py +0 -0
  168. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/base.py +0 -0
  169. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/brands.py +0 -0
  170. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/code_changes.py +0 -0
  171. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/conversations.py +0 -0
  172. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/dev_users.py +0 -0
  173. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/engagements.py +0 -0
  174. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/groups.py +0 -0
  175. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/incidents.py +0 -0
  176. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/links.py +0 -0
  177. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/notifications.py +0 -0
  178. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/parts.py +0 -0
  179. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/preferences.py +0 -0
  180. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/question_answers.py +0 -0
  181. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/recommendations.py +0 -0
  182. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/rev_users.py +0 -0
  183. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/search.py +0 -0
  184. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/slas.py +0 -0
  185. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/sync.py +0 -0
  186. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/tags.py +0 -0
  187. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/tasks.py +0 -0
  188. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/timeline_entries.py +0 -0
  189. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/timeline_events.py +0 -0
  190. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/track_events.py +0 -0
  191. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/uoms.py +0 -0
  192. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/webhooks.py +0 -0
  193. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/widgets.py +0 -0
  194. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/models/works.py +0 -0
  195. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/py.typed +0 -0
  196. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/__init__.py +0 -0
  197. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/accounts.py +0 -0
  198. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/articles.py +0 -0
  199. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/base.py +0 -0
  200. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/brands.py +0 -0
  201. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/code_changes.py +0 -0
  202. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/conversations.py +0 -0
  203. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/dev_users.py +0 -0
  204. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/engagements.py +0 -0
  205. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/groups.py +0 -0
  206. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/incidents.py +0 -0
  207. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/links.py +0 -0
  208. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/notifications.py +0 -0
  209. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/parts.py +0 -0
  210. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/preferences.py +0 -0
  211. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/question_answers.py +0 -0
  212. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/recommendations.py +0 -0
  213. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/rev_users.py +0 -0
  214. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/search.py +0 -0
  215. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/slas.py +0 -0
  216. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/tags.py +0 -0
  217. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/timeline_entries.py +0 -0
  218. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/track_events.py +0 -0
  219. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/uoms.py +0 -0
  220. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/webhooks.py +0 -0
  221. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/services/works.py +0 -0
  222. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/utils/__init__.py +0 -0
  223. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/utils/deprecation.py +0 -0
  224. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/utils/http.py +0 -0
  225. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/utils/logging.py +0 -0
  226. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev/utils/pagination.py +0 -0
  227. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/__init__.py +0 -0
  228. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/__main__.py +0 -0
  229. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/config.py +0 -0
  230. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/middleware/__init__.py +0 -0
  231. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/middleware/audit.py +0 -0
  232. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/middleware/auth.py +0 -0
  233. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/middleware/health.py +0 -0
  234. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/middleware/rate_limit.py +0 -0
  235. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/__init__.py +0 -0
  236. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/escalation.py +0 -0
  237. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/investigate.py +0 -0
  238. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/response.py +0 -0
  239. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/summarize.py +0 -0
  240. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/prompts/triage.py +0 -0
  241. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/__init__.py +0 -0
  242. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/account.py +0 -0
  243. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/article.py +0 -0
  244. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/conversation.py +0 -0
  245. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/part.py +0 -0
  246. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/ticket.py +0 -0
  247. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/resources/user.py +0 -0
  248. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/__init__.py +0 -0
  249. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/accounts.py +0 -0
  250. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/articles.py +0 -0
  251. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/conversations.py +0 -0
  252. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/engagements.py +0 -0
  253. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/groups.py +0 -0
  254. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/incidents.py +0 -0
  255. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/links.py +0 -0
  256. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/parts.py +0 -0
  257. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/recommendations.py +0 -0
  258. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/search.py +0 -0
  259. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/slas.py +0 -0
  260. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/tags.py +0 -0
  261. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/timeline.py +0 -0
  262. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/users.py +0 -0
  263. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/tools/works.py +0 -0
  264. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/utils/__init__.py +0 -0
  265. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/utils/errors.py +0 -0
  266. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/utils/formatting.py +0 -0
  267. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/src/devrev_mcp/utils/pagination.py +0 -0
  268. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/__init__.py +0 -0
  269. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/conftest.py +0 -0
  270. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/__init__.py +0 -0
  271. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/conftest.py +0 -0
  272. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_accounts_e2e.py +0 -0
  273. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_all_readonly_endpoints.py +0 -0
  274. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_backwards_compatibility.py +0 -0
  275. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_contacts_e2e.py +0 -0
  276. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_core_services_phase1.py +0 -0
  277. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_extended_services_phase2.py +0 -0
  278. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_get_endpoints.py +0 -0
  279. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_issues_e2e.py +0 -0
  280. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_kb_articles_e2e.py +0 -0
  281. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_ping.py +0 -0
  282. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_question_answers_e2e.py +0 -0
  283. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_readonly_endpoints.py +0 -0
  284. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_specialized_services_phase3.py +0 -0
  285. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_tickets_e2e.py +0 -0
  286. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/test_write_operations.py +0 -0
  287. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/utils/__init__.py +0 -0
  288. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/utils/cleanup.py +0 -0
  289. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/utils/constants.py +0 -0
  290. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/integration/utils/data_manager.py +0 -0
  291. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/__init__.py +0 -0
  292. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/__init__.py +0 -0
  293. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/conftest.py +0 -0
  294. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_audit.py +0 -0
  295. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_config.py +0 -0
  296. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_phase4_transport.py +0 -0
  297. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_prompts.py +0 -0
  298. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_resources.py +0 -0
  299. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_accounts.py +0 -0
  300. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_articles.py +0 -0
  301. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_conversations.py +0 -0
  302. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_engagements.py +0 -0
  303. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_groups.py +0 -0
  304. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_incidents.py +0 -0
  305. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_links.py +0 -0
  306. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_parts.py +0 -0
  307. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_recommendations.py +0 -0
  308. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_search.py +0 -0
  309. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_slas.py +0 -0
  310. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_tags.py +0 -0
  311. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_timeline.py +0 -0
  312. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_users.py +0 -0
  313. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_tools_works.py +0 -0
  314. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/mcp/test_utils.py +0 -0
  315. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/models/__init__.py +0 -0
  316. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/models/test_user_state_regression.py +0 -0
  317. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/__init__.py +0 -0
  318. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/conftest.py +0 -0
  319. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_articles.py +0 -0
  320. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_async_services.py +0 -0
  321. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_brands.py +0 -0
  322. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_code_changes.py +0 -0
  323. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_conversations.py +0 -0
  324. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_engagements.py +0 -0
  325. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_groups.py +0 -0
  326. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_incidents.py +0 -0
  327. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_links.py +0 -0
  328. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_notifications.py +0 -0
  329. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_parts.py +0 -0
  330. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_preferences.py +0 -0
  331. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_question_answers.py +0 -0
  332. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_recommendations.py +0 -0
  333. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_search.py +0 -0
  334. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_slas.py +0 -0
  335. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_tags.py +0 -0
  336. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_timeline_entries.py +0 -0
  337. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_track_events.py +0 -0
  338. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_uoms.py +0 -0
  339. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_webhooks.py +0 -0
  340. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/services/test_works.py +0 -0
  341. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_base_service.py +0 -0
  342. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_client.py +0 -0
  343. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_config.py +0 -0
  344. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_deprecation.py +0 -0
  345. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_exceptions.py +0 -0
  346. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_http.py +0 -0
  347. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_logging.py +0 -0
  348. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/tests/unit/test_pagination.py +0 -0
  349. {devrev_python_sdk-2.6.0 → devrev_python_sdk-2.7.0}/uv.lock +0 -0
@@ -39,11 +39,11 @@ FROM python:3.11-slim AS runtime
39
39
  # Metadata labels
40
40
  LABEL maintainer="Matthew G. Monteleone <matthewm@augmentcode.com>" \
41
41
  description="DevRev MCP Server - A Model Context Protocol server for the DevRev platform" \
42
- version="2.4.1" \
42
+ version="2.6.0" \
43
43
  org.opencontainers.image.source="https://github.com/mgmonteleone/py-dev-rev" \
44
44
  org.opencontainers.image.title="DevRev MCP Server" \
45
45
  org.opencontainers.image.description="Production-ready MCP server for DevRev API integration" \
46
- org.opencontainers.image.version="2.4.1" \
46
+ org.opencontainers.image.version="2.6.0" \
47
47
  org.opencontainers.image.licenses="MIT"
48
48
 
49
49
  # Set environment variables for Python
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devrev-Python-SDK
3
- Version: 2.6.0
3
+ Version: 2.7.0
4
4
  Summary: A modern, type-safe Python SDK for the DevRev API
5
5
  Project-URL: Homepage, https://github.com/mgmonteleone/py-dev-rev
6
6
  Project-URL: Documentation, https://github.com/mgmonteleone/py-dev-rev
@@ -5,6 +5,20 @@ All notable changes to the DevRev Python SDK will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.7.0] - 2026-02-28
9
+
10
+ ### Added
11
+
12
+ - **Server Version Discoverability**: AI agents can now discover the server's version, capabilities, and update status dynamically
13
+ - **Server Instructions**: `FastMCP` constructor includes `instructions` parameter with version info, delivered to agents on connection
14
+ - **`devrev_server_info` Tool**: Returns server version, uptime, Python version, platform, enabled capabilities, and checks PyPI for the latest published version
15
+ - **`devrev://server/info` Resource**: Static server metadata resource for agents preferring resource-based discovery
16
+ - **PyPI Version Check**: Runtime check against PyPI to determine if the server is running the latest version, with graceful degradation on network failure
17
+
18
+ ### Fixed
19
+
20
+ - **Version Comparison**: `_compare_versions` now catches `InvalidVersion` from the `packaging` library for graceful degradation with malformed version strings
21
+
8
22
  ## [2.6.0] - 2026-02-28
9
23
 
10
24
  ### Added
@@ -474,6 +488,7 @@ This release marks the completion of all four development phases, providing a pr
474
488
 
475
489
  | Version | Date | Highlights |
476
490
  |---------|------|------------|
491
+ | 2.7.0 | 2026-02-28 | 🔍 Server version discoverability for AI agents |
477
492
  | 2.6.0 | 2026-02-28 | 🔐 Compliance-grade audit logging, MCP documentation |
478
493
  | 2.4.1 | 2026-02-27 | 🐛 CI: mypy strict-mode type errors, test collection |
479
494
  | 2.4.0 | 2026-02-25 | 🔑 MCP Server: Per-user DevRev PAT authentication |
@@ -10,16 +10,16 @@ import shutil
10
10
  from pathlib import Path
11
11
 
12
12
 
13
- def on_post_build(config, **kwargs):
13
+ def on_post_build(config, **_kwargs):
14
14
  """Copy llms*.txt files from repo root to site output directory.
15
-
15
+
16
16
  This hook runs after MkDocs builds the site and copies all llms*.txt files
17
17
  from the repository root to the site output directory, making them accessible
18
18
  at the root URL of the documentation site.
19
-
19
+
20
20
  Args:
21
21
  config: MkDocs configuration dictionary.
22
- **kwargs: Additional keyword arguments (unused).
22
+ **_kwargs: Additional keyword arguments (unused).
23
23
  """
24
24
  # Get paths from config
25
25
  repo_root = Path(config["config_file_path"]).parent
@@ -27,10 +27,10 @@ def on_post_build(config, **kwargs):
27
27
 
28
28
  # List of llms.txt files to copy
29
29
  llms_files = [
30
- "llms.txt", # Main llms.txt file
31
- "llms-ctx.txt", # Context-focused version
30
+ "llms.txt", # Main llms.txt file
31
+ "llms-ctx.txt", # Context-focused version
32
32
  "llms-ctx-full.txt", # Full context version
33
- "llms-mcp.txt", # MCP-specific version
33
+ "llms-mcp.txt", # MCP-specific version
34
34
  ]
35
35
 
36
36
  # Copy each file if it exists
@@ -42,4 +42,3 @@ def on_post_build(config, **kwargs):
42
42
  print(f"[OK] Copied {filename} to site root")
43
43
  else:
44
44
  print(f"[WARNING] {filename} not found in repo root")
45
-
@@ -13,7 +13,7 @@ A modern, type-safe Python SDK and MCP Server for the DevRev API with:
13
13
  **Install**: `pip install devrev-python-sdk`
14
14
  **Install with MCP**: `pip install devrev-python-sdk[mcp]`
15
15
  **Docs**: https://mgmonteleone.github.io/py-dev-rev/
16
- **Version**: 2.5.0
16
+ **Version**: 2.7.0
17
17
 
18
18
  ## Authentication
19
19
 
@@ -6,7 +6,7 @@ A modern, type-safe Python SDK and MCP Server for the DevRev API. Requires Pytho
6
6
  **Install SDK**: `pip install devrev-python-sdk`
7
7
  **Install with MCP**: `pip install devrev-python-sdk[mcp]`
8
8
  **Docs**: https://mgmonteleone.github.io/py-dev-rev/
9
- **Version**: 2.5.0
9
+ **Version**: 2.7.0
10
10
 
11
11
  ## SDK Quick Start
12
12
 
@@ -5,7 +5,7 @@
5
5
  **Install**: `pip install devrev-python-sdk[mcp]`
6
6
  **Run**: `devrev-mcp-server`
7
7
  **Docs**: https://mgmonteleone.github.io/py-dev-rev/mcp/
8
- **Version**: 2.5.0
8
+ **Version**: 2.7.0
9
9
  **Protocol**: MCP 2025-06-18
10
10
 
11
11
  ## Quick Setup
@@ -10,7 +10,7 @@ Key information:
10
10
  - Both sync and async clients available (DevRevClient, AsyncDevRevClient)
11
11
  - Uses Pydantic v2 for all request/response models
12
12
  - MCP Server command: `devrev-mcp-server`
13
- - Version 2.5.0 (current)
13
+ - Version 2.7.0 (current)
14
14
 
15
15
  ## SDK Quick Start
16
16
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "devrev-Python-SDK"
7
- version = "2.6.0"
7
+ version = "2.7.0"
8
8
  description = "A modern, type-safe Python SDK for the DevRev API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -0,0 +1,42 @@
1
+ """MCP resource for DevRev server information."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import logging
7
+ import platform
8
+ import sys
9
+
10
+ from devrev_mcp import __version__
11
+ from devrev_mcp.server import mcp
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ @mcp.resource("devrev://server/info")
17
+ async def get_server_info_resource() -> str:
18
+ """Get DevRev MCP Server information as a resource.
19
+
20
+ Returns static server metadata including version, Python version,
21
+ and links. For dynamic information like uptime and latest PyPI version,
22
+ use the devrev_server_info tool instead.
23
+
24
+ Returns:
25
+ JSON string containing server metadata.
26
+ """
27
+ return json.dumps(
28
+ {
29
+ "uri": "devrev://server/info",
30
+ "type": "server_info",
31
+ "name": "DevRev MCP Server",
32
+ "version": __version__,
33
+ "python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
34
+ "platform": platform.system(),
35
+ "links": {
36
+ "github": "https://github.com/mgmonteleone/py-dev-rev",
37
+ "documentation": "https://mgmonteleone.github.io/py-dev-rev/",
38
+ "pypi": "https://pypi.org/project/devrev-Python-SDK/",
39
+ },
40
+ "note": "Use devrev_server_info tool for dynamic info (uptime, latest version check).",
41
+ }
42
+ )
@@ -140,6 +140,12 @@ _transport_security = _build_transport_security(_config)
140
140
 
141
141
  mcp = FastMCP(
142
142
  _config.server_name,
143
+ instructions=(
144
+ f"DevRev MCP Server v{__version__} — provides AI access to the DevRev platform "
145
+ f"for managing support tickets, customer accounts, knowledge bases, and workflows. "
146
+ f"Use the devrev_server_info tool to check version details, capabilities, and whether "
147
+ f"this is the latest version."
148
+ ),
143
149
  lifespan=app_lifespan,
144
150
  host=_config.host,
145
151
  port=_config.port,
@@ -237,6 +243,7 @@ from devrev_mcp.tools import groups as _groups_tools # noqa: E402, F401
237
243
  from devrev_mcp.tools import incidents as _incidents_tools # noqa: E402, F401
238
244
  from devrev_mcp.tools import links as _links_tools # noqa: E402, F401
239
245
  from devrev_mcp.tools import parts as _parts_tools # noqa: E402, F401
246
+ from devrev_mcp.tools import server_info as _server_info_tools # noqa: E402, F401
240
247
  from devrev_mcp.tools import slas as _slas_tools # noqa: E402, F401
241
248
  from devrev_mcp.tools import tags as _tags_tools # noqa: E402, F401
242
249
  from devrev_mcp.tools import timeline as _timeline_tools # noqa: E402, F401
@@ -259,6 +266,7 @@ from devrev_mcp.resources import account as _account_resources # noqa: E402, F4
259
266
  from devrev_mcp.resources import article as _article_resources # noqa: E402, F401
260
267
  from devrev_mcp.resources import conversation as _conversation_resources # noqa: E402, F401
261
268
  from devrev_mcp.resources import part as _part_resources # noqa: E402, F401
269
+ from devrev_mcp.resources import server_info as _server_info_resources # noqa: E402, F401
262
270
  from devrev_mcp.resources import ticket as _ticket_resources # noqa: E402, F401
263
271
  from devrev_mcp.resources import user as _user_resources # noqa: E402, F401
264
272
 
@@ -0,0 +1,108 @@
1
+ """MCP tool for DevRev server information and version checking."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import platform
7
+ import sys
8
+ import time
9
+ from typing import Any
10
+
11
+ import httpx
12
+ from mcp.server.fastmcp import Context
13
+
14
+ from devrev_mcp import __version__
15
+ from devrev_mcp.server import mcp
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # PyPI package name for version lookups
20
+ _PYPI_PACKAGE_NAME = "devrev-Python-SDK"
21
+ _PYPI_URL = f"https://pypi.org/pypi/{_PYPI_PACKAGE_NAME}/json"
22
+ _PYPI_TIMEOUT = 5.0
23
+
24
+ # Static metadata
25
+ _GITHUB_URL = "https://github.com/mgmonteleone/py-dev-rev"
26
+ _DOCS_URL = "https://mgmonteleone.github.io/py-dev-rev/"
27
+
28
+
29
+ def _compare_versions(current: str, latest: str) -> bool | None:
30
+ """Compare two version strings. Returns True if current >= latest."""
31
+ try:
32
+ from packaging.version import Version
33
+
34
+ return Version(current) >= Version(latest)
35
+ except Exception:
36
+ # Catches ImportError (packaging not installed) and InvalidVersion (malformed version)
37
+ pass
38
+ # Fallback: simple tuple comparison
39
+ try:
40
+ current_parts = tuple(int(x) for x in current.split("."))
41
+ latest_parts = tuple(int(x) for x in latest.split("."))
42
+ return current_parts >= latest_parts
43
+ except (ValueError, AttributeError):
44
+ return None
45
+
46
+
47
+ async def _fetch_latest_pypi_version() -> str | None:
48
+ """Fetch the latest version from PyPI. Returns None on failure."""
49
+ try:
50
+ async with httpx.AsyncClient() as client:
51
+ response = await client.get(_PYPI_URL, timeout=_PYPI_TIMEOUT)
52
+ response.raise_for_status()
53
+ data = response.json()
54
+ version = data.get("info", {}).get("version")
55
+ return str(version) if version is not None else None
56
+ except Exception:
57
+ logger.debug("Failed to fetch latest version from PyPI", exc_info=True)
58
+ return None
59
+
60
+
61
+ @mcp.tool()
62
+ async def devrev_server_info(ctx: Context[Any, Any, Any]) -> dict[str, Any]:
63
+ """Get DevRev MCP Server information including version, capabilities, and update status.
64
+
65
+ Returns server version, enabled features, uptime, and checks PyPI for the
66
+ latest published version so you can tell the user whether they are up to date.
67
+
68
+ Use this tool when asked about the MCP server version, capabilities, or status.
69
+ """
70
+ from devrev_mcp.middleware.health import _start_time
71
+
72
+ app = ctx.request_context.lifespan_context
73
+
74
+ # Calculate uptime
75
+ uptime_seconds = int(time.monotonic() - _start_time) if _start_time is not None else 0
76
+
77
+ # Fetch latest version from PyPI
78
+ latest_version = await _fetch_latest_pypi_version()
79
+ is_latest = _compare_versions(__version__, latest_version) if latest_version else None
80
+
81
+ return {
82
+ "server": {
83
+ "name": app.config.server_name,
84
+ "version": __version__,
85
+ "uptime_seconds": uptime_seconds,
86
+ "python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
87
+ "platform": platform.system(),
88
+ },
89
+ "capabilities": {
90
+ "beta_tools_enabled": app.config.enable_beta_tools,
91
+ "destructive_tools_enabled": app.config.enable_destructive_tools,
92
+ "auth_mode": app.config.auth_mode,
93
+ "transport": app.config.transport,
94
+ "audit_logging": app.config.audit_log_enabled,
95
+ "rate_limit_rpm": app.config.rate_limit_rpm,
96
+ },
97
+ "update_status": {
98
+ "current_version": __version__,
99
+ "latest_version": latest_version or "unknown",
100
+ "is_latest": is_latest,
101
+ "pypi_package": _PYPI_PACKAGE_NAME,
102
+ },
103
+ "links": {
104
+ "github": _GITHUB_URL,
105
+ "documentation": _DOCS_URL,
106
+ "pypi": f"https://pypi.org/project/{_PYPI_PACKAGE_NAME}/",
107
+ },
108
+ }
@@ -0,0 +1,336 @@
1
+ """Tests for DevRev MCP server info tool and resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from unittest.mock import AsyncMock, MagicMock, patch
7
+
8
+ import pytest
9
+
10
+
11
+ class TestServerInfoResource:
12
+ """Tests for the devrev://server/info resource."""
13
+
14
+ @pytest.mark.asyncio
15
+ async def test_returns_valid_json(self):
16
+ """Test that the resource returns valid JSON."""
17
+ from devrev_mcp.resources.server_info import get_server_info_resource
18
+
19
+ result = await get_server_info_resource()
20
+ data = json.loads(result)
21
+ assert isinstance(data, dict)
22
+
23
+ @pytest.mark.asyncio
24
+ async def test_contains_required_fields(self):
25
+ """Test that the resource contains all required fields."""
26
+ from devrev_mcp.resources.server_info import get_server_info_resource
27
+
28
+ result = await get_server_info_resource()
29
+ data = json.loads(result)
30
+ assert data["uri"] == "devrev://server/info"
31
+ assert data["type"] == "server_info"
32
+ assert "version" in data
33
+ assert "python_version" in data
34
+ assert "platform" in data
35
+ assert "links" in data
36
+ assert "note" in data
37
+
38
+ @pytest.mark.asyncio
39
+ async def test_links_contain_urls(self):
40
+ """Test that links contain expected URLs."""
41
+ from devrev_mcp.resources.server_info import get_server_info_resource
42
+
43
+ result = await get_server_info_resource()
44
+ data = json.loads(result)
45
+ assert "github" in data["links"]
46
+ assert "documentation" in data["links"]
47
+ assert "pypi" in data["links"]
48
+ assert data["links"]["github"].startswith("https://")
49
+
50
+ @pytest.mark.asyncio
51
+ async def test_version_matches_package(self):
52
+ """Test that the version matches the package version."""
53
+ from devrev_mcp import __version__
54
+ from devrev_mcp.resources.server_info import get_server_info_resource
55
+
56
+ result = await get_server_info_resource()
57
+ data = json.loads(result)
58
+ assert data["version"] == __version__
59
+
60
+ @pytest.mark.asyncio
61
+ async def test_python_version_format(self):
62
+ """Test that python_version is in X.Y.Z format."""
63
+ from devrev_mcp.resources.server_info import get_server_info_resource
64
+
65
+ result = await get_server_info_resource()
66
+ data = json.loads(result)
67
+ parts = data["python_version"].split(".")
68
+ assert len(parts) == 3
69
+ assert all(p.isdigit() for p in parts)
70
+
71
+ @pytest.mark.asyncio
72
+ async def test_note_mentions_tool(self):
73
+ """Test that the note directs users to the tool for dynamic info."""
74
+ from devrev_mcp.resources.server_info import get_server_info_resource
75
+
76
+ result = await get_server_info_resource()
77
+ data = json.loads(result)
78
+ assert "devrev_server_info" in data["note"]
79
+
80
+
81
+ class TestServerInfoTool:
82
+ """Tests for the devrev_server_info tool."""
83
+
84
+ @pytest.mark.asyncio
85
+ async def test_returns_server_section(self, mock_ctx):
86
+ """Test that the tool returns server information."""
87
+ from devrev_mcp.tools.server_info import devrev_server_info
88
+
89
+ with (
90
+ patch(
91
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
92
+ new_callable=AsyncMock,
93
+ return_value="2.6.0",
94
+ ),
95
+ patch("devrev_mcp.middleware.health._start_time", 0.0),
96
+ ):
97
+ result = await devrev_server_info(mock_ctx)
98
+
99
+ assert "server" in result
100
+ assert "version" in result["server"]
101
+ assert "name" in result["server"]
102
+ assert "uptime_seconds" in result["server"]
103
+ assert "python_version" in result["server"]
104
+ assert "platform" in result["server"]
105
+
106
+ @pytest.mark.asyncio
107
+ async def test_returns_capabilities_section(self, mock_ctx):
108
+ """Test that the tool returns capabilities information."""
109
+ from devrev_mcp.tools.server_info import devrev_server_info
110
+
111
+ with patch(
112
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
113
+ new_callable=AsyncMock,
114
+ return_value="2.6.0",
115
+ ):
116
+ result = await devrev_server_info(mock_ctx)
117
+
118
+ assert "capabilities" in result
119
+ caps = result["capabilities"]
120
+ assert "beta_tools_enabled" in caps
121
+ assert "destructive_tools_enabled" in caps
122
+ assert "auth_mode" in caps
123
+ assert "transport" in caps
124
+ assert "audit_logging" in caps
125
+ assert "rate_limit_rpm" in caps
126
+
127
+ @pytest.mark.asyncio
128
+ async def test_returns_update_status_section(self, mock_ctx):
129
+ """Test that the tool returns update status information."""
130
+ from devrev_mcp.tools.server_info import devrev_server_info
131
+
132
+ with patch(
133
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
134
+ new_callable=AsyncMock,
135
+ return_value="2.6.0",
136
+ ):
137
+ result = await devrev_server_info(mock_ctx)
138
+
139
+ assert "update_status" in result
140
+ status = result["update_status"]
141
+ assert "current_version" in status
142
+ assert "latest_version" in status
143
+ assert "is_latest" in status
144
+ assert "pypi_package" in status
145
+
146
+ @pytest.mark.asyncio
147
+ async def test_returns_links_section(self, mock_ctx):
148
+ """Test that the tool returns links."""
149
+ from devrev_mcp.tools.server_info import devrev_server_info
150
+
151
+ with patch(
152
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
153
+ new_callable=AsyncMock,
154
+ return_value="2.6.0",
155
+ ):
156
+ result = await devrev_server_info(mock_ctx)
157
+
158
+ assert "links" in result
159
+ assert "github" in result["links"]
160
+ assert "documentation" in result["links"]
161
+ assert "pypi" in result["links"]
162
+
163
+ @pytest.mark.asyncio
164
+ async def test_pypi_failure_returns_unknown(self, mock_ctx):
165
+ """Test graceful handling when PyPI is unreachable."""
166
+ from devrev_mcp.tools.server_info import devrev_server_info
167
+
168
+ with patch(
169
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
170
+ new_callable=AsyncMock,
171
+ return_value=None,
172
+ ):
173
+ result = await devrev_server_info(mock_ctx)
174
+
175
+ assert result["update_status"]["latest_version"] == "unknown"
176
+ assert result["update_status"]["is_latest"] is None
177
+
178
+ @pytest.mark.asyncio
179
+ async def test_is_latest_true_when_current_equals_latest(self, mock_ctx):
180
+ """Test is_latest is True when versions match."""
181
+ from devrev_mcp import __version__
182
+ from devrev_mcp.tools.server_info import devrev_server_info
183
+
184
+ with patch(
185
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
186
+ new_callable=AsyncMock,
187
+ return_value=__version__,
188
+ ):
189
+ result = await devrev_server_info(mock_ctx)
190
+
191
+ assert result["update_status"]["is_latest"] is True
192
+
193
+ @pytest.mark.asyncio
194
+ async def test_is_latest_false_when_behind(self, mock_ctx):
195
+ """Test is_latest is False when a newer version exists."""
196
+ from devrev_mcp.tools.server_info import devrev_server_info
197
+
198
+ with patch(
199
+ "devrev_mcp.tools.server_info._fetch_latest_pypi_version",
200
+ new_callable=AsyncMock,
201
+ return_value="99.99.99",
202
+ ):
203
+ result = await devrev_server_info(mock_ctx)
204
+
205
+ assert result["update_status"]["is_latest"] is False
206
+
207
+
208
+ class TestVersionComparison:
209
+ """Tests for the _compare_versions helper."""
210
+
211
+ def test_equal_versions(self):
212
+ from devrev_mcp.tools.server_info import _compare_versions
213
+
214
+ assert _compare_versions("2.6.0", "2.6.0") is True
215
+
216
+ def test_current_newer(self):
217
+ from devrev_mcp.tools.server_info import _compare_versions
218
+
219
+ assert _compare_versions("2.7.0", "2.6.0") is True
220
+
221
+ def test_current_older(self):
222
+ from devrev_mcp.tools.server_info import _compare_versions
223
+
224
+ assert _compare_versions("2.5.0", "2.6.0") is False
225
+
226
+ def test_major_version_difference(self):
227
+ from devrev_mcp.tools.server_info import _compare_versions
228
+
229
+ assert _compare_versions("3.0.0", "2.99.99") is True
230
+ assert _compare_versions("1.99.99", "2.0.0") is False
231
+
232
+ def test_invalid_version_returns_none(self):
233
+ """Test that invalid versions return None when packaging is not available."""
234
+ import sys
235
+ from unittest.mock import patch
236
+
237
+ from devrev_mcp.tools.server_info import _compare_versions
238
+
239
+ # Mock ImportError to force fallback to simple comparison
240
+ # We need to patch the import at the point where it's used
241
+ with patch.dict(sys.modules, {"packaging.version": None}):
242
+ result = _compare_versions("invalid", "also-invalid")
243
+ assert result is None
244
+
245
+ def test_invalid_version_with_packaging_degrades_gracefully(self):
246
+ """Test that invalid versions degrade gracefully even when packaging is available."""
247
+ from devrev_mcp.tools.server_info import _compare_versions
248
+
249
+ # When packaging is available but version strings are invalid, should return None
250
+ result = _compare_versions("invalid", "also-invalid")
251
+ assert result is None
252
+
253
+
254
+ class TestFetchLatestPyPIVersion:
255
+ """Tests for the _fetch_latest_pypi_version helper."""
256
+
257
+ @pytest.mark.asyncio
258
+ async def test_successful_fetch(self):
259
+ """Test successful PyPI version fetch."""
260
+ from devrev_mcp.tools.server_info import _fetch_latest_pypi_version
261
+
262
+ mock_response = MagicMock()
263
+ mock_response.json.return_value = {"info": {"version": "2.6.0"}}
264
+ mock_response.raise_for_status = MagicMock()
265
+
266
+ with patch("devrev_mcp.tools.server_info.httpx.AsyncClient") as mock_client_cls:
267
+ mock_client = AsyncMock()
268
+ mock_client.get = AsyncMock(return_value=mock_response)
269
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
270
+ mock_client.__aexit__ = AsyncMock(return_value=None)
271
+ mock_client_cls.return_value = mock_client
272
+
273
+ result = await _fetch_latest_pypi_version()
274
+ assert result == "2.6.0"
275
+
276
+ @pytest.mark.asyncio
277
+ async def test_network_error_returns_none(self):
278
+ """Test that network errors return None."""
279
+ from devrev_mcp.tools.server_info import _fetch_latest_pypi_version
280
+
281
+ with patch("devrev_mcp.tools.server_info.httpx.AsyncClient") as mock_client_cls:
282
+ mock_client = AsyncMock()
283
+ mock_client.get = AsyncMock(side_effect=Exception("Network error"))
284
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
285
+ mock_client.__aexit__ = AsyncMock(return_value=None)
286
+ mock_client_cls.return_value = mock_client
287
+
288
+ result = await _fetch_latest_pypi_version()
289
+ assert result is None
290
+
291
+ @pytest.mark.asyncio
292
+ async def test_malformed_response_returns_none(self):
293
+ """Test that malformed JSON responses return None gracefully."""
294
+ from devrev_mcp.tools.server_info import _fetch_latest_pypi_version
295
+
296
+ mock_response = MagicMock()
297
+ mock_response.json.return_value = {} # Missing 'info' key
298
+ mock_response.raise_for_status = MagicMock()
299
+
300
+ with patch("devrev_mcp.tools.server_info.httpx.AsyncClient") as mock_client_cls:
301
+ mock_client = AsyncMock()
302
+ mock_client.get = AsyncMock(return_value=mock_response)
303
+ mock_client.__aenter__ = AsyncMock(return_value=mock_client)
304
+ mock_client.__aexit__ = AsyncMock(return_value=None)
305
+ mock_client_cls.return_value = mock_client
306
+
307
+ result = await _fetch_latest_pypi_version()
308
+ assert result is None # .get("info", {}).get("version") returns None
309
+
310
+
311
+ class TestServerInstructions:
312
+ """Tests for the server instructions parameter."""
313
+
314
+ def test_mcp_server_has_instructions(self):
315
+ """Test that the MCP server instance has instructions set."""
316
+ import os
317
+ from unittest.mock import patch as mock_patch
318
+
319
+ with mock_patch.dict(os.environ, {"DEVREV_API_TOKEN": "test-token"}, clear=False):
320
+ from devrev_mcp.server import mcp
321
+
322
+ # FastMCP stores instructions - check it's set and contains version info
323
+ assert mcp.instructions is not None
324
+ assert "DevRev MCP Server" in mcp.instructions
325
+ assert "devrev_server_info" in mcp.instructions
326
+
327
+ def test_instructions_contain_version(self):
328
+ """Test that instructions include the version string."""
329
+ import os
330
+ from unittest.mock import patch as mock_patch
331
+
332
+ with mock_patch.dict(os.environ, {"DEVREV_API_TOKEN": "test-token"}, clear=False):
333
+ from devrev_mcp import __version__
334
+ from devrev_mcp.server import mcp
335
+
336
+ assert __version__ in mcp.instructions