python-docs-mcp-server 0.1.2__tar.gz → 0.1.4__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 (186) hide show
  1. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.github/workflows/ci.yml +4 -2
  2. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.github/workflows/e2e.yml +5 -3
  3. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.github/workflows/release.yml +46 -8
  4. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/PKG-INFO +2 -1
  5. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/README.md +1 -0
  6. python_docs_mcp_server-0.1.4/glama.json +6 -0
  7. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/pyproject.toml +1 -1
  8. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/server.json +2 -2
  9. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/server.py +54 -2
  10. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_stdio_hygiene.py +5 -1
  11. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_stdio_smoke.py +76 -11
  12. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/uv.lock +1 -1
  13. python_docs_mcp_server-0.1.2/.planning/FULL-CODEBASE-REVIEW.md +0 -318
  14. python_docs_mcp_server-0.1.2/.planning/PROJECT.md +0 -121
  15. python_docs_mcp_server-0.1.2/.planning/REQUIREMENTS.md +0 -342
  16. python_docs_mcp_server-0.1.2/.planning/ROADMAP.md +0 -144
  17. python_docs_mcp_server-0.1.2/.planning/STATE.md +0 -105
  18. python_docs_mcp_server-0.1.2/.planning/config.json +0 -51
  19. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-01-PLAN.md +0 -217
  20. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-01-SUMMARY.md +0 -18
  21. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-02-PLAN.md +0 -255
  22. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-02-SUMMARY.md +0 -14
  23. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-03-PLAN.md +0 -435
  24. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-03-SUMMARY.md +0 -17
  25. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-04-PLAN.md +0 -434
  26. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-04-SUMMARY.md +0 -20
  27. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-05-PLAN.md +0 -419
  28. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-05-SUMMARY.md +0 -15
  29. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-CONTEXT.md +0 -87
  30. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-DISCUSSION-LOG.md +0 -108
  31. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-RESEARCH.md +0 -217
  32. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-REVIEW-FIX.md +0 -85
  33. python_docs_mcp_server-0.1.2/.planning/phases/01-foundation-stdio-hygiene-symbol-slice/01-REVIEW.md +0 -176
  34. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-A-PLAN.md +0 -216
  35. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-A-SUMMARY.md +0 -32
  36. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-B-PLAN.md +0 -99
  37. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-B-SUMMARY.md +0 -32
  38. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-C-PLAN.md +0 -410
  39. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-C-SUMMARY.md +0 -31
  40. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-CONTEXT.md +0 -60
  41. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-RESEARCH.md +0 -212
  42. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-REVIEW-FIX.md +0 -50
  43. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-REVIEW.md +0 -101
  44. python_docs_mcp_server-0.1.2/.planning/phases/02-schema-storage/02-VERIFICATION.md +0 -67
  45. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-A-PLAN.md +0 -181
  46. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-A-SUMMARY.md +0 -29
  47. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-B-PLAN.md +0 -205
  48. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-B-SUMMARY.md +0 -26
  49. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-C-PLAN.md +0 -175
  50. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-C-SUMMARY.md +0 -24
  51. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-CONTEXT.md +0 -76
  52. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-D-PLAN.md +0 -201
  53. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-D-SUMMARY.md +0 -27
  54. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-RESEARCH.md +0 -299
  55. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-REVIEW-FIX.md +0 -56
  56. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-REVIEW.md +0 -148
  57. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-VALIDATION.md +0 -83
  58. python_docs_mcp_server-0.1.2/.planning/phases/03-retrieval-layer/03-VERIFICATION.md +0 -64
  59. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-A-PLAN.md +0 -182
  60. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-B-PLAN.md +0 -153
  61. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-C-PLAN.md +0 -225
  62. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-CONTEXT.md +0 -78
  63. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-D-PLAN.md +0 -555
  64. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-DISCUSSION-LOG.md +0 -46
  65. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-PATTERNS.md +0 -66
  66. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-RESEARCH.md +0 -189
  67. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-REVIEW-FIX.md +0 -62
  68. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-REVIEW.md +0 -139
  69. python_docs_mcp_server-0.1.2/.planning/phases/04-sphinx-json-ingestion-atomic-swap-publishing/04-VALIDATION.md +0 -83
  70. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-A-PLAN.md +0 -389
  71. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-B-PLAN.md +0 -248
  72. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-C-PLAN.md +0 -279
  73. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-CONTEXT.md +0 -64
  74. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-D-PLAN.md +0 -262
  75. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-E-PLAN.md +0 -114
  76. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-F-PLAN.md +0 -403
  77. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-PATTERNS.md +0 -103
  78. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-RESEARCH.md +0 -140
  79. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-REVIEW-FIX.md +0 -80
  80. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-REVIEW.md +0 -175
  81. python_docs_mcp_server-0.1.2/.planning/phases/05-services-tool-polish-caching/05-VALIDATION.md +0 -79
  82. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06-CONTEXT.md +0 -60
  83. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06-REVIEW-FIX.md +0 -59
  84. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06-REVIEW.md +0 -104
  85. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06-SUMMARY.md +0 -58
  86. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06a-PLAN.md +0 -411
  87. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06b-PLAN.md +0 -212
  88. python_docs_mcp_server-0.1.2/.planning/phases/06-multi-version-packaging-correctness/06c-PLAN.md +0 -246
  89. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07-CONTEXT.md +0 -63
  90. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07-REVIEW-FIX.md +0 -49
  91. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07-REVIEW.md +0 -116
  92. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07-VERIFICATION.md +0 -65
  93. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07a-PLAN.md +0 -170
  94. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07a-SUMMARY.md +0 -33
  95. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07b-PLAN.md +0 -179
  96. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07b-SUMMARY.md +0 -39
  97. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07c-PLAN.md +0 -217
  98. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07c-SUMMARY.md +0 -29
  99. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07d-PLAN.md +0 -337
  100. python_docs_mcp_server-0.1.2/.planning/phases/07-stability-tests-release-polish/07d-SUMMARY.md +0 -38
  101. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08-CONTEXT.md +0 -68
  102. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08-REVIEW-FIX.md +0 -66
  103. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08-REVIEW.md +0 -134
  104. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08-VERIFICATION.md +0 -49
  105. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08a-PLAN.md +0 -180
  106. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08a-SUMMARY.md +0 -33
  107. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08b-PLAN.md +0 -205
  108. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08b-SUMMARY.md +0 -31
  109. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08c-PLAN.md +0 -161
  110. python_docs_mcp_server-0.1.2/.planning/phases/08-ship/08c-SUMMARY.md +0 -32
  111. python_docs_mcp_server-0.1.2/.planning/research/ARCHITECTURE.md +0 -946
  112. python_docs_mcp_server-0.1.2/.planning/research/FEATURES.md +0 -435
  113. python_docs_mcp_server-0.1.2/.planning/research/PITFALLS.md +0 -843
  114. python_docs_mcp_server-0.1.2/.planning/research/STACK.md +0 -344
  115. python_docs_mcp_server-0.1.2/.planning/research/SUMMARY.md +0 -277
  116. python_docs_mcp_server-0.1.2/.planning/v0.1.0-MILESTONE-AUDIT.md +0 -120
  117. python_docs_mcp_server-0.1.2/PR9_MCP_TEST_PLAN.md +0 -393
  118. python_docs_mcp_server-0.1.2/PR9_SMOKE_FAILURE_FIX_PLAN.md +0 -445
  119. python_docs_mcp_server-0.1.2/docs/launch/reddit-posts.md +0 -110
  120. python_docs_mcp_server-0.1.2/docs/launch/show-hn.md +0 -89
  121. python_docs_mcp_server-0.1.2/docs/superpowers/plans/2026-05-11-pr22-coherence-fixes.md +0 -864
  122. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.cursorignore +0 -0
  123. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.github/INTEGRATION-TEST.md +0 -0
  124. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.github/RELEASE.md +0 -0
  125. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/.gitignore +0 -0
  126. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/AGENTS.md +0 -0
  127. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/CLAUDE.md +0 -0
  128. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/CONTRIBUTING.md +0 -0
  129. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/LICENSE +0 -0
  130. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/__init__.py +0 -0
  131. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/__main__.py +0 -0
  132. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/app_context.py +0 -0
  133. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/data/synonyms.yaml +0 -0
  134. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/detection.py +0 -0
  135. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/diagnostics.py +0 -0
  136. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/errors.py +0 -0
  137. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/ingestion/__init__.py +0 -0
  138. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/ingestion/cpython_versions.py +0 -0
  139. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/ingestion/inventory.py +0 -0
  140. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/ingestion/publish.py +0 -0
  141. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/ingestion/sphinx_json.py +0 -0
  142. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/models.py +0 -0
  143. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/py.typed +0 -0
  144. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/retrieval/__init__.py +0 -0
  145. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/retrieval/budget.py +0 -0
  146. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/retrieval/query.py +0 -0
  147. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/retrieval/ranker.py +0 -0
  148. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/__init__.py +0 -0
  149. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/cache.py +0 -0
  150. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/content.py +0 -0
  151. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/observability.py +0 -0
  152. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/package_docs.py +0 -0
  153. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/persistent_cache.py +0 -0
  154. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/search.py +0 -0
  155. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/version.py +0 -0
  156. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/services/version_resolution.py +0 -0
  157. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/storage/__init__.py +0 -0
  158. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/storage/db.py +0 -0
  159. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/src/mcp_server_python_docs/storage/schema.sql +0 -0
  160. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/__init__.py +0 -0
  161. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/conftest.py +0 -0
  162. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/retrieval_regression_cases.json +0 -0
  163. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/sample_broken.fjson +0 -0
  164. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/sample_library.fjson +0 -0
  165. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/schema-get_docs-input.json +0 -0
  166. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/schema-get_docs-output.json +0 -0
  167. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/schema-list_versions-output.json +0 -0
  168. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/schema-search_docs-input.json +0 -0
  169. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/fixtures/schema-search_docs-output.json +0 -0
  170. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_ci_workflows.py +0 -0
  171. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_doctor.py +0 -0
  172. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_ingestion.py +0 -0
  173. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_mcp_get_docs_cache_smoke.py +0 -0
  174. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_multi_version.py +0 -0
  175. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_package_docs.py +0 -0
  176. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_packaging.py +0 -0
  177. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_persistent_docs_cache.py +0 -0
  178. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_phase1_integration.py +0 -0
  179. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_publish.py +0 -0
  180. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_retrieval.py +0 -0
  181. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_retrieval_regression.py +0 -0
  182. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_schema.py +0 -0
  183. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_schema_snapshot.py +0 -0
  184. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_services.py +0 -0
  185. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_stability.py +0 -0
  186. {python_docs_mcp_server-0.1.2 → python_docs_mcp_server-0.1.4}/tests/test_synonyms.py +0 -0
@@ -18,10 +18,12 @@ jobs:
18
18
  name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
19
19
 
20
20
  steps:
21
- - uses: actions/checkout@v4
21
+ - uses: actions/checkout@v6
22
22
 
23
23
  - name: Install uv
24
- uses: astral-sh/setup-uv@v4
24
+ uses: astral-sh/setup-uv@v8.1.0
25
+ with:
26
+ cache-suffix: py${{ matrix.python-version }}
25
27
 
26
28
  - name: Set up Python ${{ matrix.python-version }}
27
29
  run: uv python install ${{ matrix.python-version }}
@@ -17,10 +17,12 @@ jobs:
17
17
  python-version: ["3.13", "3.14"]
18
18
 
19
19
  steps:
20
- - uses: actions/checkout@v4
20
+ - uses: actions/checkout@v6
21
21
 
22
22
  - name: Install uv
23
- uses: astral-sh/setup-uv@v4
23
+ uses: astral-sh/setup-uv@v8.1.0
24
+ with:
25
+ cache-suffix: py${{ matrix.python-version }}
24
26
 
25
27
  - name: Set up Python ${{ matrix.python-version }}
26
28
  run: uv python install ${{ matrix.python-version }}
@@ -48,7 +50,7 @@ jobs:
48
50
 
49
51
  - name: Upload E2E logs and cache artifacts
50
52
  if: always()
51
- uses: actions/upload-artifact@v4
53
+ uses: actions/upload-artifact@v7
52
54
  with:
53
55
  name: e2e-python-${{ matrix.python-version }}
54
56
  path: |
@@ -16,10 +16,10 @@ jobs:
16
16
  timeout-minutes: 15
17
17
 
18
18
  steps:
19
- - uses: actions/checkout@v4
19
+ - uses: actions/checkout@v6
20
20
 
21
21
  - name: Install uv
22
- uses: astral-sh/setup-uv@v4
22
+ uses: astral-sh/setup-uv@v8.1.0
23
23
 
24
24
  - name: Set up Python 3.13
25
25
  run: uv python install 3.13
@@ -35,6 +35,16 @@ jobs:
35
35
  echo "::error::Tag ${GITHUB_REF_NAME} does not match pyproject.toml version ${PKG_VERSION}"
36
36
  exit 1
37
37
  fi
38
+ SERVER_VERSION=$(uv run python -c "import json; print(json.load(open('server.json'))['version'])")
39
+ PACKAGE_VERSION=$(uv run python -c "import json; print(json.load(open('server.json'))['packages'][0]['version'])")
40
+ if [ "$TAG_VERSION" != "$SERVER_VERSION" ]; then
41
+ echo "::error::Tag ${GITHUB_REF_NAME} does not match server.json version ${SERVER_VERSION}"
42
+ exit 1
43
+ fi
44
+ if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then
45
+ echo "::error::Tag ${GITHUB_REF_NAME} does not match server.json package version ${PACKAGE_VERSION}"
46
+ exit 1
47
+ fi
38
48
  echo "Version check passed: ${PKG_VERSION}"
39
49
 
40
50
  - name: Run linter
@@ -66,7 +76,7 @@ jobs:
66
76
  "
67
77
 
68
78
  - name: Upload dist artifacts
69
- uses: actions/upload-artifact@v4
79
+ uses: actions/upload-artifact@v7
70
80
  with:
71
81
  name: dist
72
82
  path: dist/
@@ -84,22 +94,50 @@ jobs:
84
94
 
85
95
  steps:
86
96
  - name: Download dist artifacts
87
- uses: actions/download-artifact@v4
97
+ uses: actions/download-artifact@v8
88
98
  with:
89
99
  name: dist
90
100
  path: dist/
91
101
 
92
102
  - name: Generate artifact attestation
93
- uses: actions/attest-build-provenance@v2
103
+ uses: actions/attest-build-provenance@v4
94
104
  with:
95
105
  subject-path: 'dist/*'
96
106
 
97
107
  - name: Publish to PyPI
98
108
  uses: pypa/gh-action-pypi-publish@release/v1
99
109
 
100
- github-release:
110
+ publish-mcp-registry:
101
111
  needs: publish
102
112
  runs-on: ubuntu-latest
113
+ name: Publish to MCP Registry
114
+ timeout-minutes: 10
115
+ permissions:
116
+ id-token: write
117
+ contents: read
118
+
119
+ steps:
120
+ - uses: actions/checkout@v6
121
+
122
+ - name: Install mcp-publisher
123
+ run: |
124
+ curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" \
125
+ | tar xz mcp-publisher
126
+
127
+ - name: Validate server.json
128
+ run: ./mcp-publisher validate server.json
129
+
130
+ - name: Authenticate to MCP Registry
131
+ run: ./mcp-publisher login github-oidc
132
+
133
+ - name: Publish to MCP Registry
134
+ run: ./mcp-publisher publish
135
+
136
+ github-release:
137
+ needs:
138
+ - publish
139
+ - publish-mcp-registry
140
+ runs-on: ubuntu-latest
103
141
  name: Create GitHub Release
104
142
  timeout-minutes: 10
105
143
  permissions:
@@ -107,13 +145,13 @@ jobs:
107
145
 
108
146
  steps:
109
147
  - name: Download dist artifacts
110
- uses: actions/download-artifact@v4
148
+ uses: actions/download-artifact@v8
111
149
  with:
112
150
  name: dist
113
151
  path: dist/
114
152
 
115
153
  - name: Create GitHub Release
116
- uses: softprops/action-gh-release@v2
154
+ uses: softprops/action-gh-release@v3
117
155
  with:
118
156
  files: dist/*
119
157
  generate_release_notes: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-docs-mcp-server
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: A read-only, version-aware MCP retrieval server over Python standard library documentation
5
5
  Author-email: Aymen Hammouda <hammouda.aymen@gmail.com>
6
6
  License-Expression: MIT
@@ -31,6 +31,7 @@ Description-Content-Type: text/markdown
31
31
  <!-- mcp-name: io.github.ayhammouda/python-docs-mcp-server -->
32
32
 
33
33
  [![CI](https://github.com/ayhammouda/python-docs-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/ayhammouda/python-docs-mcp-server/actions/workflows/ci.yml)
34
+ [![python-docs-mcp-server MCP server](https://glama.ai/mcp/servers/ayhammouda/python-docs-mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/ayhammouda/python-docs-mcp-server)
34
35
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
35
36
  [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)
36
37
  [![No API Keys](https://img.shields.io/badge/API%20keys-none-success)](#why-teams-like-this)
@@ -3,6 +3,7 @@
3
3
  <!-- mcp-name: io.github.ayhammouda/python-docs-mcp-server -->
4
4
 
5
5
  [![CI](https://github.com/ayhammouda/python-docs-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/ayhammouda/python-docs-mcp-server/actions/workflows/ci.yml)
6
+ [![python-docs-mcp-server MCP server](https://glama.ai/mcp/servers/ayhammouda/python-docs-mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/ayhammouda/python-docs-mcp-server)
6
7
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
7
8
  [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)
8
9
  [![No API Keys](https://img.shields.io/badge/API%20keys-none-success)](#why-teams-like-this)
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "ayhammouda"
5
+ ]
6
+ }
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-docs-mcp-server"
7
- version = "0.1.2"
7
+ version = "0.1.4"
8
8
  description = "A read-only, version-aware MCP retrieval server over Python standard library documentation"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -8,13 +8,13 @@
8
8
  "url": "https://github.com/ayhammouda/python-docs-mcp-server",
9
9
  "source": "github"
10
10
  },
11
- "version": "0.1.1",
11
+ "version": "0.1.4",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "registryBaseUrl": "https://pypi.org",
16
16
  "identifier": "python-docs-mcp-server",
17
- "version": "0.1.1",
17
+ "version": "0.1.4",
18
18
  "runtimeHint": "uvx",
19
19
  "transport": {
20
20
  "type": "stdio"
@@ -9,7 +9,9 @@ from __future__ import annotations
9
9
  import asyncio
10
10
  import importlib.resources
11
11
  import logging
12
+ import os
12
13
  import sqlite3
14
+ import subprocess
13
15
  import sys
14
16
  import traceback
15
17
  from collections.abc import AsyncIterator
@@ -61,6 +63,55 @@ def _assert_fts5(conn: sqlite3.Connection) -> None:
61
63
  assert_fts5_available(conn)
62
64
 
63
65
 
66
+ def _auto_build_symbol_index(index_path) -> bool:
67
+ """Build a small symbol-only index when the server starts without one.
68
+
69
+ This keeps hosted scanners/directories such as Glama from failing MCP
70
+ introspection on a fresh container while preserving the documented full
71
+ corpus command for normal users. Set PYTHON_DOCS_MCP_DISABLE_AUTO_INDEX=1
72
+ to require an explicitly prebuilt index.
73
+ """
74
+ if os.environ.get("PYTHON_DOCS_MCP_DISABLE_AUTO_INDEX") == "1":
75
+ return False
76
+
77
+ versions = os.environ.get("PYTHON_DOCS_MCP_AUTO_INDEX_VERSIONS", "3.13")
78
+ logger.warning(
79
+ "No index found at %s; auto-building symbol-only Python docs index for %s",
80
+ index_path,
81
+ versions,
82
+ )
83
+ try:
84
+ result = subprocess.run(
85
+ [
86
+ sys.executable,
87
+ "-m",
88
+ "mcp_server_python_docs",
89
+ "build-index",
90
+ "--versions",
91
+ versions,
92
+ "--skip-content",
93
+ ],
94
+ check=False,
95
+ capture_output=True,
96
+ text=True,
97
+ timeout=180,
98
+ )
99
+ except (OSError, subprocess.TimeoutExpired) as e:
100
+ logger.error("Auto index build failed to start or timed out: %s", e)
101
+ return False
102
+
103
+ if result.returncode != 0:
104
+ logger.error(
105
+ "Auto index build failed with exit code %s:\n%s",
106
+ result.returncode,
107
+ (result.stderr or result.stdout)[-4000:],
108
+ )
109
+ return False
110
+
111
+ logger.info("Auto index build complete at %s", index_path)
112
+ return index_path.exists()
113
+
114
+
64
115
  @asynccontextmanager
65
116
  async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
66
117
  """Manage application lifecycle with typed context (SRVR-01).
@@ -72,8 +123,9 @@ async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
72
123
  cache_dir = get_cache_dir()
73
124
  index_path = get_index_path()
74
125
 
75
- # Fail fast on missing index (SRVR-10)
76
- if not index_path.exists():
126
+ # Fail fast on missing index unless a small symbol-only auto-index succeeds
127
+ # (SRVR-10 plus hosted-directory scanner compatibility).
128
+ if not index_path.exists() and not _auto_build_symbol_index(index_path):
77
129
  from mcp_server_python_docs.ingestion.cpython_versions import (
78
130
  SUPPORTED_DOC_VERSIONS_CSV,
79
131
  )
@@ -67,12 +67,16 @@ class TestStdioHygiene:
67
67
  import tempfile
68
68
 
69
69
  with tempfile.TemporaryDirectory() as tmpdir:
70
+ env = {
71
+ **_isolated_cache_env(tmpdir),
72
+ "PYTHON_DOCS_MCP_DISABLE_AUTO_INDEX": "1",
73
+ }
70
74
  result = subprocess.run(
71
75
  [sys.executable, "-m", "mcp_server_python_docs", "serve"],
72
76
  capture_output=True,
73
77
  text=True,
74
78
  timeout=10,
75
- env=_isolated_cache_env(tmpdir),
79
+ env=env,
76
80
  )
77
81
  # Server should exit with error (missing index)
78
82
  assert result.returncode != 0
@@ -16,6 +16,7 @@ import json
16
16
  import os
17
17
  import subprocess
18
18
  import sys
19
+ import threading
19
20
  import time
20
21
  from pathlib import Path
21
22
 
@@ -100,17 +101,17 @@ def _create_test_index(cache_dir: Path) -> Path:
100
101
  return db_path
101
102
 
102
103
 
103
- def _make_request(method: str, params: dict | None = None, req_id: int = 1) -> bytes:
104
+ def _make_request(method: str, params: dict[str, object] | None = None, req_id: int = 1) -> bytes:
104
105
  """Build a JSON-RPC 2.0 request as newline-terminated bytes."""
105
- msg = {"jsonrpc": "2.0", "id": req_id, "method": method}
106
+ msg: dict[str, object] = {"jsonrpc": "2.0", "id": req_id, "method": method}
106
107
  if params is not None:
107
108
  msg["params"] = params
108
109
  return json.dumps(msg).encode() + b"\n"
109
110
 
110
111
 
111
- def _make_notification(method: str, params: dict | None = None) -> bytes:
112
+ def _make_notification(method: str, params: dict[str, object] | None = None) -> bytes:
112
113
  """Build a JSON-RPC 2.0 notification (no id) as newline-terminated bytes."""
113
- msg = {"jsonrpc": "2.0", "method": method}
114
+ msg: dict[str, object] = {"jsonrpc": "2.0", "method": method}
114
115
  if params is not None:
115
116
  msg["params"] = params
116
117
  return json.dumps(msg).encode() + b"\n"
@@ -170,6 +171,19 @@ def _find_response(responses: list[dict], req_id: int) -> dict | None:
170
171
  return None
171
172
 
172
173
 
174
+ def _request_ids(stdin_data: bytes) -> list[int]:
175
+ """Return request ids present in newline-delimited JSON-RPC input."""
176
+ request_ids: list[int] = []
177
+ for line in stdin_data.splitlines():
178
+ try:
179
+ parsed = json.loads(line)
180
+ except json.JSONDecodeError:
181
+ continue
182
+ if isinstance(parsed, dict) and "id" in parsed:
183
+ request_ids.append(parsed["id"])
184
+ return request_ids
185
+
186
+
173
187
  class TestStdioSmoke:
174
188
  """Spawn the MCP server as a subprocess and verify protocol compliance."""
175
189
 
@@ -192,13 +206,64 @@ class TestStdioSmoke:
192
206
  env=self.env,
193
207
  )
194
208
  assert proc.stdin is not None
195
- for index, line in enumerate(stdin_data.splitlines(keepends=True)):
196
- proc.stdin.write(line)
197
- proc.stdin.flush()
198
- time.sleep(0.3 if index == 0 else 0.05)
199
- proc.stdin.close()
200
- proc.stdin = None
201
- stdout, stderr = proc.communicate(timeout=timeout)
209
+ assert proc.stdout is not None
210
+ assert proc.stderr is not None
211
+
212
+ stdout_lines: list[bytes] = []
213
+ stderr_lines: list[bytes] = []
214
+ output_lock = threading.Lock()
215
+
216
+ def read_stream(stream, sink: list[bytes]) -> None:
217
+ for line in iter(stream.readline, b""):
218
+ with output_lock:
219
+ sink.append(line)
220
+
221
+ stdout_thread = threading.Thread(
222
+ target=read_stream,
223
+ args=(proc.stdout, stdout_lines),
224
+ daemon=True,
225
+ )
226
+ stderr_thread = threading.Thread(
227
+ target=read_stream,
228
+ args=(proc.stderr, stderr_lines),
229
+ daemon=True,
230
+ )
231
+ stdout_thread.start()
232
+ stderr_thread.start()
233
+
234
+ expected_ids = _request_ids(stdin_data)
235
+ deadline = time.monotonic() + timeout
236
+ try:
237
+ for line in stdin_data.splitlines(keepends=True):
238
+ proc.stdin.write(line)
239
+ proc.stdin.flush()
240
+
241
+ while time.monotonic() < deadline:
242
+ with output_lock:
243
+ responses = _read_responses(b"".join(stdout_lines))
244
+ if all(_find_response(responses, req_id) is not None for req_id in expected_ids):
245
+ break
246
+ if proc.poll() is not None:
247
+ break
248
+ time.sleep(0.02)
249
+ finally:
250
+ try:
251
+ proc.stdin.close()
252
+ except BrokenPipeError:
253
+ pass
254
+ proc.stdin = None
255
+
256
+ remaining = max(0.1, deadline - time.monotonic())
257
+ try:
258
+ proc.wait(timeout=remaining)
259
+ except subprocess.TimeoutExpired:
260
+ proc.kill()
261
+ proc.wait(timeout=5)
262
+
263
+ stdout_thread.join(timeout=1)
264
+ stderr_thread.join(timeout=1)
265
+ stdout = b"".join(stdout_lines)
266
+ stderr = b"".join(stderr_lines)
202
267
  return subprocess.CompletedProcess(proc.args, proc.returncode, stdout, stderr)
203
268
 
204
269
  def test_server_lists_tools_no_stdout_pollution(self):
@@ -541,7 +541,7 @@ wheels = [
541
541
 
542
542
  [[package]]
543
543
  name = "python-docs-mcp-server"
544
- version = "0.1.2"
544
+ version = "0.1.4"
545
545
  source = { editable = "." }
546
546
  dependencies = [
547
547
  { name = "beautifulsoup4" },