kodit 0.3.6__tar.gz → 0.3.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kodit might be problematic. Click here for more details.

Files changed (245) hide show
  1. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/docker.yaml +2 -2
  2. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/test.yaml +3 -0
  3. {kodit-0.3.6 → kodit-0.3.8}/CLAUDE.md +3 -4
  4. {kodit-0.3.6 → kodit-0.3.8}/Dockerfile +4 -0
  5. {kodit-0.3.6 → kodit-0.3.8}/PKG-INFO +3 -2
  6. kodit-0.3.8/docs/getting-started/integration/index.md +58 -0
  7. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/deployment/docker-compose.yaml +12 -3
  8. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/mcp/index.md +205 -22
  9. {kodit-0.3.6 → kodit-0.3.8}/pyproject.toml +4 -14
  10. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/_version.py +2 -2
  11. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/app.py +12 -5
  12. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/cli.py +20 -10
  13. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/config.py +3 -2
  14. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/bm25/local_bm25_repository.py +3 -3
  15. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/cloning/git/working_copy.py +23 -2
  16. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_factory.py +8 -3
  17. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/enrichment/enrichment_factory.py +5 -1
  18. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/enrichment/local_enrichment_provider.py +5 -5
  19. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/slicing/slicer.py +12 -3
  20. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/ui/progress.py +1 -1
  21. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/log.py +1 -1
  22. kodit-0.3.8/src/kodit/mcp.py +228 -0
  23. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/middleware.py +2 -2
  24. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/application/test_code_indexing_application_service.py +3 -2
  25. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/cli_test.py +154 -0
  26. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/config_test.py +10 -4
  27. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/services/index_service_test.py +1 -1
  28. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/cloning/git_cloning/working_copy_test.py +137 -1
  29. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_hash_embedding_provider.py +1 -1
  30. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_local_embedding_provider.py +1 -1
  31. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_local_enrichment_provider.py +1 -1
  32. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_null_enrichment_provider.py +1 -1
  33. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/test_openai_enrichment_provider.py +1 -1
  34. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/python/models.py +1 -1
  35. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/slicer_test.py +24 -0
  36. kodit-0.3.8/tests/kodit/mcp_stdio_test.py +22 -0
  37. kodit-0.3.8/tests/kodit/mcp_test.py +88 -0
  38. {kodit-0.3.6 → kodit-0.3.8}/tests/performance/similarity.py +3 -1
  39. {kodit-0.3.6 → kodit-0.3.8}/tests/smoke.sh +3 -0
  40. {kodit-0.3.6 → kodit-0.3.8}/uv.lock +290 -19
  41. kodit-0.3.6/docs/MIGRATION_TO_INDEX_AGGREGATE.md +0 -222
  42. kodit-0.3.6/docs/getting-started/integration/index.md +0 -97
  43. kodit-0.3.6/src/kodit/infrastructure/indexing/indexing_factory.py +0 -30
  44. kodit-0.3.6/src/kodit/mcp.py +0 -200
  45. kodit-0.3.6/tests/kodit/mcp_test.py +0 -111
  46. {kodit-0.3.6 → kodit-0.3.8}/.claude/commands/debug.md +0 -0
  47. {kodit-0.3.6 → kodit-0.3.8}/.claude/commands/new-requirement.md +0 -0
  48. {kodit-0.3.6 → kodit-0.3.8}/.claude/commands/refactor.md +0 -0
  49. {kodit-0.3.6 → kodit-0.3.8}/.claude/commands/update-docs.md +0 -0
  50. {kodit-0.3.6 → kodit-0.3.8}/.claude/settings.json +0 -0
  51. {kodit-0.3.6 → kodit-0.3.8}/.cursor/rules/kodit.mdc +0 -0
  52. {kodit-0.3.6 → kodit-0.3.8}/.cursor/rules/style.mdc +0 -0
  53. {kodit-0.3.6 → kodit-0.3.8}/.dockerignore +0 -0
  54. {kodit-0.3.6 → kodit-0.3.8}/.github/CODE_OF_CONDUCT.md +0 -0
  55. {kodit-0.3.6 → kodit-0.3.8}/.github/CONTRIBUTING.md +0 -0
  56. {kodit-0.3.6 → kodit-0.3.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  57. {kodit-0.3.6 → kodit-0.3.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  58. {kodit-0.3.6 → kodit-0.3.8}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  59. {kodit-0.3.6 → kodit-0.3.8}/.github/dependabot.yml +0 -0
  60. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/docs.yaml +0 -0
  61. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/pull_request.yaml +0 -0
  62. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/pypi-test.yaml +0 -0
  63. {kodit-0.3.6 → kodit-0.3.8}/.github/workflows/pypi.yaml +0 -0
  64. {kodit-0.3.6 → kodit-0.3.8}/.gitignore +0 -0
  65. {kodit-0.3.6 → kodit-0.3.8}/.python-version +0 -0
  66. {kodit-0.3.6 → kodit-0.3.8}/.vscode/launch.json +0 -0
  67. {kodit-0.3.6 → kodit-0.3.8}/.vscode/settings.json +0 -0
  68. {kodit-0.3.6 → kodit-0.3.8}/LICENSE +0 -0
  69. {kodit-0.3.6 → kodit-0.3.8}/README.md +0 -0
  70. {kodit-0.3.6 → kodit-0.3.8}/alembic.ini +0 -0
  71. {kodit-0.3.6 → kodit-0.3.8}/docs/_index.md +0 -0
  72. {kodit-0.3.6 → kodit-0.3.8}/docs/demos/_index.md +0 -0
  73. {kodit-0.3.6 → kodit-0.3.8}/docs/demos/go-simple-microservice/index.md +0 -0
  74. {kodit-0.3.6 → kodit-0.3.8}/docs/demos/knock-knock-auth/index.md +0 -0
  75. {kodit-0.3.6 → kodit-0.3.8}/docs/developer/index.md +0 -0
  76. {kodit-0.3.6 → kodit-0.3.8}/docs/getting-started/_index.md +0 -0
  77. {kodit-0.3.6 → kodit-0.3.8}/docs/getting-started/installation/index.md +0 -0
  78. {kodit-0.3.6 → kodit-0.3.8}/docs/getting-started/quick-start/index.md +0 -0
  79. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/_index.md +0 -0
  80. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/configuration/index.md +0 -0
  81. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/deployment/index.md +0 -0
  82. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/deployment/kubernetes.yaml +0 -0
  83. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/indexing/index.md +0 -0
  84. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/sync/index.md +0 -0
  85. {kodit-0.3.6 → kodit-0.3.8}/docs/reference/telemetry/index.md +0 -0
  86. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/.gitignore +0 -0
  87. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/__init__.py +0 -0
  88. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/__init__.py +0 -0
  89. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/factories/__init__.py +0 -0
  90. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/factories/code_indexing_factory.py +0 -0
  91. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/services/__init__.py +0 -0
  92. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/services/code_indexing_application_service.py +0 -0
  93. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/application/services/sync_scheduler.py +0 -0
  94. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/database.py +0 -0
  95. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/__init__.py +0 -0
  96. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/entities.py +0 -0
  97. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/errors.py +0 -0
  98. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/interfaces.py +0 -0
  99. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/protocols.py +0 -0
  100. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/__init__.py +0 -0
  101. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/bm25_service.py +0 -0
  102. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/embedding_service.py +0 -0
  103. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/enrichment_service.py +0 -0
  104. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/index_query_service.py +0 -0
  105. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/services/index_service.py +0 -0
  106. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/domain/value_objects.py +0 -0
  107. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/__init__.py +0 -0
  108. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/bm25/__init__.py +0 -0
  109. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/bm25/bm25_factory.py +0 -0
  110. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/bm25/vectorchord_bm25_repository.py +0 -0
  111. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/cloning/__init__.py +0 -0
  112. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/cloning/git/__init__.py +0 -0
  113. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/cloning/metadata.py +0 -0
  114. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/__init__.py +0 -0
  115. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_providers/__init__.py +0 -0
  116. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_providers/batching.py +0 -0
  117. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_providers/hash_embedding_provider.py +0 -0
  118. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_providers/local_embedding_provider.py +0 -0
  119. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/embedding_providers/openai_embedding_provider.py +0 -0
  120. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/local_vector_search_repository.py +0 -0
  121. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/embedding/vectorchord_vector_search_repository.py +0 -0
  122. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/enrichment/__init__.py +0 -0
  123. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/enrichment/null_enrichment_provider.py +0 -0
  124. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/enrichment/openai_enrichment_provider.py +0 -0
  125. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/git/__init__.py +0 -0
  126. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/git/git_utils.py +0 -0
  127. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/ignore/__init__.py +0 -0
  128. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/ignore/ignore_pattern_provider.py +0 -0
  129. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/indexing/__init__.py +0 -0
  130. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/indexing/auto_indexing_service.py +0 -0
  131. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/indexing/fusion_service.py +0 -0
  132. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/mappers/__init__.py +0 -0
  133. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/mappers/index_mapper.py +0 -0
  134. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/slicing/__init__.py +0 -0
  135. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/slicing/language_detection_service.py +0 -0
  136. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
  137. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/sqlalchemy/embedding_repository.py +0 -0
  138. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/sqlalchemy/entities.py +0 -0
  139. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/sqlalchemy/index_repository.py +0 -0
  140. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/ui/__init__.py +0 -0
  141. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/infrastructure/ui/spinner.py +0 -0
  142. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/README +0 -0
  143. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/__init__.py +0 -0
  144. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/env.py +0 -0
  145. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/script.py.mako +0 -0
  146. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/4073b33f9436_add_file_processing_flag.py +0 -0
  147. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/4552eb3f23ce_add_summary.py +0 -0
  148. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py +0 -0
  149. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/85155663351e_initial.py +0 -0
  150. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/9e53ea8bb3b0_add_authors.py +0 -0
  151. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/__init__.py +0 -0
  152. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py +0 -0
  153. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/reporting.py +0 -0
  154. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/utils/__init__.py +0 -0
  155. {kodit-0.3.6 → kodit-0.3.8}/src/kodit/utils/path_utils.py +0 -0
  156. {kodit-0.3.6 → kodit-0.3.8}/tests/__init__.py +0 -0
  157. {kodit-0.3.6 → kodit-0.3.8}/tests/conftest.py +0 -0
  158. {kodit-0.3.6 → kodit-0.3.8}/tests/docker-smoke.sh +0 -0
  159. {kodit-0.3.6 → kodit-0.3.8}/tests/experiments/__init__.py +0 -0
  160. {kodit-0.3.6 → kodit-0.3.8}/tests/experiments/cline_prompt_tests/__init__.py +0 -0
  161. {kodit-0.3.6 → kodit-0.3.8}/tests/experiments/cline_prompt_tests/cline_prompt.txt +0 -0
  162. {kodit-0.3.6 → kodit-0.3.8}/tests/experiments/cline_prompt_tests/cline_prompt_test.py +0 -0
  163. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/__init__.py +0 -0
  164. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/application/__init__.py +0 -0
  165. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/application/services/__init__.py +0 -0
  166. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/application/services/test_sync_scheduler.py +0 -0
  167. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/__init__.py +0 -0
  168. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/bm25_domain_service_test.py +0 -0
  169. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/enrichment_domain_service_test.py +0 -0
  170. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/entities_test.py +0 -0
  171. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/services/__init__.py +0 -0
  172. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/test_embedding_service.py +0 -0
  173. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/test_language_mapping.py +0 -0
  174. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/domain/test_multi_search_result.py +0 -0
  175. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/e2e.py +0 -0
  176. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/__init__.py +0 -0
  177. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/bm25/__init__.py +0 -0
  178. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/bm25/local_bm25_repository_test.py +0 -0
  179. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/bm25/vectorchord_bm25_repository_test.py +0 -0
  180. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/cloning/git_cloning/__init__.py +0 -0
  181. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/__init__.py +0 -0
  182. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/embedding_factory_test.py +0 -0
  183. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/embedding_provider/__init__.py +0 -0
  184. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/embedding_provider/test_openai_embedding_provider.py +0 -0
  185. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/test_batching.py +0 -0
  186. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/test_embedding_integration.py +0 -0
  187. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/test_local_vector_search_repository.py +0 -0
  188. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/embedding/test_vectorchord_vector_search_repository.py +0 -0
  189. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/__init__.py +0 -0
  190. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/enrichment_provider/__init__.py +0 -0
  191. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/enrichment/test_enrichment_factory.py +0 -0
  192. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/indexing/__init__.py +0 -0
  193. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/indexing/test_auto_indexing_service.py +0 -0
  194. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/mappers/__init__.py +0 -0
  195. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/mappers/test_index_mapper.py +0 -0
  196. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/__init__.py +0 -0
  197. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/__init__.py +0 -0
  198. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/c/main.c +0 -0
  199. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/c/models.c +0 -0
  200. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/c/models.h +0 -0
  201. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/c/utils.c +0 -0
  202. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/c/utils.h +0 -0
  203. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/cpp/main.cpp +0 -0
  204. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/cpp/models.cpp +0 -0
  205. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/cpp/models.hpp +0 -0
  206. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/cpp/utils.cpp +0 -0
  207. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/cpp/utils.hpp +0 -0
  208. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/csharp/Main.cs +0 -0
  209. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/csharp/Models.cs +0 -0
  210. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/csharp/Utils.cs +0 -0
  211. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/css/components.css +0 -0
  212. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/css/main.css +0 -0
  213. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/css/utilities.css +0 -0
  214. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/go/main.go +0 -0
  215. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/go/models.go +0 -0
  216. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/go/utils.go +0 -0
  217. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/html/components.html +0 -0
  218. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/html/forms.html +0 -0
  219. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/html/main.html +0 -0
  220. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/java/Main.java +0 -0
  221. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/java/Models.java +0 -0
  222. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/java/Utils.java +0 -0
  223. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/javascript/main.js +0 -0
  224. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/javascript/models.js +0 -0
  225. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/javascript/utils.js +0 -0
  226. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/python/__init__.py +0 -0
  227. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/python/main.py +0 -0
  228. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/python/utils.py +0 -0
  229. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/rust/main.rs +0 -0
  230. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/rust/models.rs +0 -0
  231. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/slicing/data/rust/utils.rs +0 -0
  232. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/__init__.py +0 -0
  233. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/csharp.cs +0 -0
  234. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/golang.go +0 -0
  235. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/javascript.js +0 -0
  236. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/knock_knock_server.py +0 -0
  237. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/python.py +0 -0
  238. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/snippets/typescript.tsx +0 -0
  239. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/sqlalchemy/__init__.py +0 -0
  240. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/infrastructure/sqlalchemy/test_embedding_repository.py +0 -0
  241. {kodit-0.3.6 → kodit-0.3.8}/tests/kodit/log_test.py +0 -0
  242. {kodit-0.3.6 → kodit-0.3.8}/tests/performance/__init__.py +0 -0
  243. {kodit-0.3.6 → kodit-0.3.8}/tests/utils/__init__.py +0 -0
  244. {kodit-0.3.6 → kodit-0.3.8}/tests/utils/test_path_utils.py +0 -0
  245. {kodit-0.3.6 → kodit-0.3.8}/tests/vectorchord-smoke.sh +0 -0
@@ -1,9 +1,9 @@
1
1
  name: Publish Docker image
2
2
 
3
3
  on:
4
+ workflow_dispatch:
4
5
  push:
5
- pull_request_target:
6
- types: [opened, synchronize, reopened]
6
+ workflow_call:
7
7
 
8
8
  env:
9
9
  TEST_TAG: user/app:test
@@ -35,6 +35,9 @@ jobs:
35
35
  - name: Lint
36
36
  run: uv run ruff check
37
37
 
38
+ - name: Run type checks
39
+ run: uv run mypy --config-file pyproject.toml .
40
+
38
41
  - name: Run tests
39
42
  run: uv run pytest -s --cov=src --cov-report=xml tests/kodit
40
43
 
@@ -14,11 +14,10 @@ Kodit is a code indexing MCP (Model Context Protocol) server that connects AI co
14
14
  - `uv run pytest tests/path/to/test.py` - Run specific test file
15
15
  - `uv run pytest -k "test_name"` - Run specific test by name
16
16
 
17
- ### Code Quality
17
+ ### Linting and Typing
18
18
 
19
- - `uv run ruff check --fix` - Run linting
20
- - `uv run ruff format` - Format code
21
- - `uv run mypy src/` - Type checking
19
+ - `uv run ruff check --fix --unsafe-fixes` - Run linting and format code
20
+ - `uv run mypy --config-file pyproject.toml ...` - Type checking
22
21
 
23
22
  ### Application
24
23
 
@@ -86,6 +86,10 @@ EOT
86
86
 
87
87
  STOPSIGNAL SIGINT
88
88
 
89
+ # Configure a default data directory so the app can write to it and volumes can be mounted to it
90
+ RUN mkdir -p /data && chown -R app:app /data
91
+ ENV DATA_DIR=/data
92
+
89
93
  USER app
90
94
  WORKDIR /app
91
95
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kodit
3
- Version: 0.3.6
3
+ Version: 0.3.8
4
4
  Summary: Code indexing for better AI code generation
5
5
  Project-URL: Homepage, https://docs.helixml.tech/kodit/
6
6
  Project-URL: Documentation, https://docs.helixml.tech/kodit/
@@ -30,7 +30,7 @@ Requires-Dist: click>=8.1.8
30
30
  Requires-Dist: colorama>=0.4.6
31
31
  Requires-Dist: dotenv>=0.9.9
32
32
  Requires-Dist: fastapi[standard]>=0.115.12
33
- Requires-Dist: fastmcp>=2.3.3
33
+ Requires-Dist: fastmcp>=2.10.4
34
34
  Requires-Dist: gitpython>=3.1.44
35
35
  Requires-Dist: hf-xet>=1.1.2
36
36
  Requires-Dist: httpx-retries>=0.3.2
@@ -38,6 +38,7 @@ Requires-Dist: httpx>=0.28.1
38
38
  Requires-Dist: openai>=1.82.0
39
39
  Requires-Dist: pathspec>=0.12.1
40
40
  Requires-Dist: pydantic-settings>=2.9.1
41
+ Requires-Dist: pystemmer>=3.0.0
41
42
  Requires-Dist: pytable-formatter>=0.1.1
42
43
  Requires-Dist: rudder-sdk-python>=2.1.4
43
44
  Requires-Dist: sentence-transformers>=4.1.0
@@ -0,0 +1,58 @@
1
+ ---
2
+ title: Integration With Coding Assistants
3
+ description: How to integrate Kodit with AI coding assistants.
4
+ weight: 3
5
+ ---
6
+
7
+ The core goal of Kodit is to make your AI coding experience more accurate by providing better context. That means you need to integrate Kodit with your favourite assistant.
8
+
9
+ ## MCP Connection Methods
10
+
11
+ Kodit supports three different ways to run the MCP server, depending on your integration
12
+ needs. Each method exposes the same code search capabilities, but differs in how the
13
+ connection is established and which assistants/tools it is compatible with.
14
+
15
+ See the [MCP Reference](../../reference/mcp/index.md) for comprehensive integration
16
+ instructions for popular coding assistants like Cursor, Claude, Cline, etc.
17
+
18
+ ### 1. HTTP Streaming (Recommended)
19
+
20
+ This is the default and recommended method for most users. Kodit runs an HTTP server
21
+ that streams responses to connected AI coding assistants over the `/mcp` endpoint.
22
+
23
+ 1. Start the Kodit server:
24
+
25
+ ```sh
26
+ kodit serve
27
+ ```
28
+
29
+ _The Kodit container runs this command by default._
30
+
31
+ 2. Configure your AI coding assistant to connect to `http://localhost:8080/mcp`
32
+
33
+ ### 2. STDIO Mode
34
+
35
+ Kodit can run as an MCP server over standard input/output (STDIO) for direct integration
36
+ with local AI coding assistants that support MCP stdio transport. No network port is
37
+ opened.
38
+
39
+ 1. Configure your AI coding assistant to start Kodit's STDIO server:
40
+
41
+ ```sh
42
+ kodit stdio
43
+ ```
44
+
45
+ ### 3. SSE (Server-Sent Events) [Deprecated]
46
+
47
+ Kodit also supports the older SSE protocol on the `/sse` endpoint. This is provided for
48
+ backward compatibility with tools that require SSE.
49
+
50
+ 1. Start the Kodit server:
51
+
52
+ ```sh
53
+ kodit serve
54
+ ```
55
+
56
+ _The Kodit container runs this command by default._
57
+
58
+ 2. Configure your AI coding assistant to connect to `http://localhost:8080/sse`
@@ -2,9 +2,9 @@ version: "3.9"
2
2
 
3
3
  services:
4
4
  kodit:
5
- image: registry.helix.ml/helix/kodit:latest # Replace with a version
5
+ image: test:latest
6
6
  ports:
7
- - "8080:8080" # Expose the MCP server
7
+ - "8080:8080" # You may wish to pick a less common port
8
8
  # Start the Kodit MCP server and bind to all interfaces
9
9
  command: ["serve", "--host", "0.0.0.0", "--port", "8080"]
10
10
  restart: unless-stopped
@@ -39,11 +39,20 @@ services:
39
39
  SYNC_PERIODIC_INTERVAL_SECONDS: 1800 # 30 minutes
40
40
  SYNC_PERIODIC_RETRY_ATTEMPTS: 3
41
41
 
42
+ # Logging configuration
43
+ LOG_LEVEL: INFO # Set to DEBUG for more detailed logging
44
+
45
+ volumes:
46
+ - kodit-data:/data
47
+
42
48
  vectorchord:
43
49
  image: tensorchord/vchord-suite:pg17-20250601
44
50
  environment:
45
51
  - POSTGRES_DB=kodit
46
52
  - POSTGRES_PASSWORD=mysecretpassword
47
53
  ports:
48
- - "5432:5432"
54
+ - "5432"
49
55
  restart: unless-stopped
56
+
57
+ volumes:
58
+ kodit-data:
@@ -4,43 +4,226 @@ description: Model Context Protocol (MCP) server implementation for AI coding as
4
4
  weight: 2
5
5
  ---
6
6
 
7
- Kodit provides an MCP (Model Context Protocol) server that enables AI coding assistants to search and retrieve relevant code snippets from your indexed codebases. This allows AI assistants to provide more accurate and contextually relevant code suggestions.
7
+ The [Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) is a
8
+ standard that enables AI assistants to communicate with external tools and data sources.
8
9
 
9
- ## What is MCP?
10
+ Kodit provides an MCP (Model Context Protocol) server that enables AI coding assistants
11
+ to search and retrieve relevant code snippets from your indexed codebases. This allows
12
+ AI assistants to provide more accurate and contextually relevant code suggestions.
10
13
 
11
- The Model Context Protocol (MCP) is a standard that enables AI assistants to communicate with external tools and data sources. Kodit implements an MCP server that exposes your indexed codebases to AI assistants, allowing them to:
14
+ ## MCP Server Connection Methods
12
15
 
13
- - Search for relevant code examples
14
- - Retrieve specific code snippets
15
- - Filter results by various criteria
16
- - Provide context-aware code suggestions
16
+ Kodit supports three different ways to run the MCP server, depending on your integration
17
+ needs. Each method exposes the same code search capabilities, but differs in how the
18
+ connection is established and which assistants/tools it is compatible with.
17
19
 
18
- ## How Kodit MCP Works
20
+ ### HTTP Streaming (Recommended)
19
21
 
20
- The Kodit MCP server runs as a separate service that:
22
+ This is the default and recommended method for most users. Kodit runs an HTTP server
23
+ that streams responses to connected AI coding assistants over the `/mcp` endpoint.
21
24
 
22
- 1. **Connects to your indexed codebases** - Uses the same database and indexes created by the `kodit index` command
23
- 2. **Exposes search functionality** - Provides a `search` tool that AI assistants can call
24
- 3. **Handles filtering** - Supports filtering by language, author, date range, and source repository
25
- 4. **Returns relevant snippets** - Combines keyword, semantic code, and semantic text search for optimal results
25
+ - **How it works:** Kodit starts a local web server and listens for HTTP requests from
26
+ your AI assistant. Responses are streamed for low-latency, real-time results.
27
+ - **When to use:** Most modern AI coding assistants (like Cursor, Cline, etc.) support
28
+ HTTP streaming. Use this for best compatibility and performance.
29
+ - **How to start:**
30
+
31
+ ```sh
32
+ kodit serve
33
+ ```
34
+
35
+ The server will listen on `http://localhost:8080/mcp` by default. If you're using the
36
+ Kodit container, `kodit serve` is the default command.
37
+
38
+ ### STDIO
39
+
40
+ Kodit can run as an MCP server over standard input/output (STDIO) for direct integration
41
+ with local AI coding assistants that support MCP stdio transport. No network port is
42
+ opened.
43
+
44
+ - **How it works:** Kodit communicates with your AI assistant via standard input and
45
+ output streams, making it ideal for local, low-latency, and networkless setups.
46
+ - **When to use:** Use this mode if your coding assistant supports MCP stdio (for
47
+ example, some local LLM tools or advanced IDE integrations), or if you want to avoid
48
+ network configuration entirely.
49
+ - **How to start:**
50
+
51
+ Configure your AI assistant to run the following command:
52
+
53
+ ```sh
54
+ kodit stdio
55
+ ```
56
+
57
+ ### SSE (Server-Sent Events) [Deprecated]
58
+
59
+ Kodit also supports the older SSE protocol on the `/sse` endpoint. This is provided for
60
+ backward compatibility with tools that require SSE.
61
+
62
+ - **How it works:** Kodit starts a local web server and streams results using the SSE
63
+ protocol, which is less efficient and less widely supported than HTTP streaming.
64
+ - **When to use:** Only if your assistant specifically requires SSE and does not support
65
+ HTTP streaming.
66
+ - **How to start:**
67
+
68
+ ```sh
69
+ kodit serve
70
+ ```
71
+
72
+ The server will listen on `http://localhost:8080/sse`.
26
73
 
27
74
  ## Integration with AI Assistants
28
75
 
29
- To use Kodit with your AI coding assistant, you need to:
76
+ You need to connect your AI coding assistant to take advantage of Kodit. The
77
+ instructions to do this depend on how you've deployed it. This section provides
78
+ comprehensive instructions for all popular coding assistants.
79
+
80
+ ### Integration With Claude Code
81
+
82
+ #### Claude Code Streaming HTTP Mode (recommended)
83
+
84
+ ```sh
85
+ claude mcp add --transport http kodit http://localhost:8080/mcp
86
+ ```
87
+
88
+ #### Claude Code STDIO Mode
89
+
90
+ ```sh
91
+ claude mcp add kodit -- kodit stdio
92
+ ```
93
+
94
+ ### Integration With Cursor
95
+
96
+ #### Cursor Streaming HTTP Mode (recommended)
97
+
98
+ ![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)
99
+ {class="h-8 inline-block" href="cursor://anysphere.cursor-deeplink/mcp/install?name=kodit&config=eyJ1cmwiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvbWNwIn0%3D"}
100
+
101
+ Add the following to `$HOME/.cursor/mcp.json`:
102
+
103
+ ```json
104
+ {
105
+ "mcpServers": {
106
+ "kodit": {
107
+ "url": "http://localhost:8080/mcp"
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ Or find this configuration in `Cursor Settings` -> `MCP`. Replace localhost with domain
114
+ where Kodit is hosted.
30
115
 
31
- 1. **Start the Kodit MCP server**:
116
+ #### Cursor STDIO
32
117
 
33
- ```sh
34
- kodit serve
35
- ```
118
+ ![Install MCP Server](https://cursor.com/deeplink/mcp-install-light.svg)
119
+ {class="h-8 inline-block" href="cursor://anysphere.cursor-deeplink/mcp/install?name=kodit&config=eyJjb21tYW5kIjoicGlweCBydW4ga29kaXQgc3RkaW8ifQ%3D%3D"}
36
120
 
37
- 2. **Configure your AI assistant** to connect to the MCP server. See the [Integration Guide](../../getting-started/integration/index.md) for detailed instructions for:
38
- - Cursor
39
- - Cline
40
- - Other MCP-compatible assistants
121
+ Add the following to `$HOME/.cursor/mcp.json`:
122
+
123
+ ```json
124
+ {
125
+ "mcpServers": {
126
+ "kodit": {
127
+ "command": "kodit stdio"
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ ### Integration With Cline
134
+
135
+ 1. Open Cline from the side menu
136
+ 2. Click the `MCP Servers` button at the top right of the Cline window (the icon looks
137
+ like a server)
138
+ 3. Click the `Remote Servers` tab.
139
+ 4. Click `Edit Configuration`
140
+
141
+ #### Cline Streaming HTTP Mode (recommended)
142
+
143
+ Add the following configuration:
144
+
145
+ ```json
146
+ {
147
+ "mcpServers": {
148
+ "kodit": {
149
+ "autoApprove": [],
150
+ "disabled": true,
151
+ "timeout": 60,
152
+ "url": "http://localhost:8080/mcp",
153
+ "transportType": "http"
154
+ }
155
+ }
156
+ }
157
+ ```
158
+
159
+ Note that some cline users are still [reporting issues with HTTP
160
+ streaming](https://github.com/cline/cline/issues/3315), so you may need to use sse
161
+ instead.
162
+
163
+ #### Cline STDIO Mode
164
+
165
+ For STDIO mode, please use:
166
+
167
+ ```json
168
+ {
169
+ "mcpServers": {
170
+ "kodit": {
171
+ "autoApprove": [],
172
+ "command": "kodit",
173
+ "args": ["stdio"],
174
+ "disabled": false,
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ ## Forcing AI Assistants to use Kodit
181
+
182
+ Although Kodit has been developed to work well out of the box with popular AI coding
183
+ assistants, they sometimes still think they know better.
184
+
185
+ You can force your assistant to use Kodit by editing the system prompt used by the
186
+ assistant. Each assistant exposes this slightly differently, but it's usually in the
187
+ settings.
188
+
189
+ Try using this system prompt:
190
+
191
+ ```txt
192
+ ⚠️ **ENFORCEMENT:**
193
+ For *every* user request that involves writing or modifying code (of any language or
194
+ domain), the assistant's *first* action **must** be to call the kodit.search MCP tool.
195
+ You may only produce or edit code *after* that tool call and its successful
196
+ result.
197
+ ```
198
+
199
+ Feel free to alter that to suit your specific circumstances.
200
+
201
+ ### Forcing Cursor to Use Kodit
202
+
203
+ Add the following prompt to `.cursor/rules/kodit.mdc` in your project directory:
204
+
205
+ ```markdown
206
+ ---
207
+ alwaysApply: true
208
+ ---
209
+ ⚠️ **ENFORCEMENT:**
210
+ For *every* user request that involves writing or modifying code (of any language or
211
+ domain), the assistant's *first* action **must** be to call the kodit.search MCP tool.
212
+ You may only produce or edit code *after* that tool call and its successful
213
+ result.
214
+ ```
215
+
216
+ Alternatively, you can browse to the Cursor settings and set this prompt globally.
217
+
218
+ ### Forcing Cline to Use Kodit
219
+
220
+ 1. Go to `Settings` -> `API Configuration`
221
+ 2. At the bottom there is a `Custom Instructions` section.
41
222
 
42
223
  ## Search Tool
43
224
 
225
+ <!--Future: move this to a dedicated reference page-->
226
+
44
227
  The primary tool exposed by the Kodit MCP server is the `search` function, which provides comprehensive code search capabilities.
45
228
 
46
229
  ### Search Parameters
@@ -40,7 +40,7 @@ dependencies = [
40
40
  "uritools>=5.0.0",
41
41
  "tree-sitter-language-pack>=0.7.3",
42
42
  "tree-sitter>=0.24.0",
43
- "fastmcp>=2.3.3",
43
+ "fastmcp>=2.10.4",
44
44
  "pydantic-settings>=2.9.1",
45
45
  "bm25s[core]>=0.2.12",
46
46
  "gitpython>=3.1.44",
@@ -53,6 +53,7 @@ dependencies = [
53
53
  "transformers>=4.51.3",
54
54
  "accelerate>=1.7.0",
55
55
  "rudder-sdk-python>=2.1.4",
56
+ "pystemmer>=3.0.0",
56
57
  ]
57
58
 
58
59
  [dependency-groups]
@@ -64,6 +65,8 @@ dev = [
64
65
  "pytest-cov>=6.1.1",
65
66
  "ruff>=0.11.8",
66
67
  "snakeviz>=2.2.2",
68
+ "types-tqdm>=4.67.0.20250516",
69
+ "types-aiofiles>=24.1.0.20250708",
67
70
  ]
68
71
 
69
72
  [project.urls]
@@ -142,16 +145,3 @@ package = true
142
145
 
143
146
  [tool.mypy]
144
147
  plugins = ["sqlalchemy.ext.mypy.plugin"]
145
- warn_return_any = true
146
- warn_unused_configs = true
147
- disallow_untyped_defs = true
148
- disallow_incomplete_defs = true
149
- check_untyped_defs = true
150
- disallow_untyped_decorators = true
151
- no_implicit_optional = true
152
- warn_redundant_casts = true
153
- warn_unused_ignores = true
154
- warn_no_return = true
155
- warn_unreachable = true
156
- strict_optional = true
157
-
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.3.6'
21
- __version_tuple__ = version_tuple = (0, 3, 6)
20
+ __version__ = version = '0.3.8'
21
+ __version_tuple__ = version_tuple = (0, 3, 8)
@@ -51,14 +51,19 @@ async def app_lifespan(_: FastAPI) -> AsyncIterator[None]:
51
51
  await _auto_indexing_service.stop()
52
52
 
53
53
 
54
- # See https://gofastmcp.com/deployment/asgi#fastapi-integration
55
- mcp_app = mcp.sse_app()
54
+ # See https://gofastmcp.com/integrations/fastapi#mounting-an-mcp-server
55
+ mcp_sse_app = mcp.http_app(transport="sse", path="/")
56
+ mcp_http_app = mcp.http_app(transport="http", path="/")
56
57
 
57
58
 
58
59
  @asynccontextmanager
59
60
  async def combined_lifespan(app: FastAPI) -> AsyncIterator[None]:
60
61
  """Combine app and MCP lifespans."""
61
- async with app_lifespan(app), mcp_app.router.lifespan_context(app):
62
+ async with (
63
+ app_lifespan(app),
64
+ mcp_sse_app.router.lifespan_context(app),
65
+ mcp_http_app.router.lifespan_context(app),
66
+ ):
62
67
  yield
63
68
 
64
69
 
@@ -82,8 +87,10 @@ async def healthz() -> dict[str, str]:
82
87
 
83
88
 
84
89
  # Add mcp routes last, otherwise previous routes aren't added
85
- app.mount("", mcp_app)
90
+ # Mount both apps at root - they have different internal paths
91
+ app.mount("/sse", mcp_sse_app)
92
+ app.mount("/mcp", mcp_http_app)
86
93
 
87
94
  # Wrap the entire app with ASGI middleware after all routes are added to suppress
88
95
  # CancelledError at the ASGI level
89
- app = ASGICancelledErrorMiddleware(app)
96
+ app = ASGICancelledErrorMiddleware(app) # type: ignore[assignment]
@@ -1,13 +1,14 @@
1
1
  """Command line interface for kodit."""
2
2
 
3
3
  import signal
4
+ import warnings
4
5
  from pathlib import Path
5
6
  from typing import Any
6
7
 
7
8
  import click
8
9
  import structlog
9
10
  import uvicorn
10
- from pytable_formatter import Cell, Table
11
+ from pytable_formatter import Cell, Table # type: ignore[import-untyped]
11
12
  from sqlalchemy.ext.asyncio import AsyncSession
12
13
 
13
14
  from kodit.application.factories.code_indexing_factory import (
@@ -32,6 +33,7 @@ from kodit.infrastructure.ui.progress import (
32
33
  create_multi_stage_progress_callback,
33
34
  )
34
35
  from kodit.log import configure_logging, configure_telemetry, log_event
36
+ from kodit.mcp import create_stdio_mcp_server
35
37
 
36
38
 
37
39
  @click.group(context_settings={"max_content_width": 100})
@@ -54,7 +56,7 @@ def cli(
54
56
  config = AppContext()
55
57
  # First check if env-file is set and reload config if it is
56
58
  if env_file:
57
- config = AppContext(_env_file=env_file) # type: ignore[reportCallIssue]
59
+ config = AppContext(_env_file=env_file) # type: ignore[call-arg]
58
60
 
59
61
  configure_logging(config)
60
62
  configure_telemetry(config)
@@ -100,7 +102,8 @@ async def _handle_sync(
100
102
  # Filter indexes that match the provided sources
101
103
  source_uris = set(sources)
102
104
  indexes_to_sync = [
103
- index for index in all_indexes
105
+ index
106
+ for index in all_indexes
104
107
  if str(index.source.working_copy.remote_uri) in source_uris
105
108
  ]
106
109
 
@@ -124,9 +127,7 @@ async def _handle_sync(
124
127
  click.echo(f"✓ Sync completed: {index.source.working_copy.remote_uri}")
125
128
  except Exception as e:
126
129
  log.exception("Sync failed", index_id=index.id, error=e)
127
- click.echo(
128
- f"✗ Sync failed: {index.source.working_copy.remote_uri} - {e}"
129
- )
130
+ click.echo(f"✗ Sync failed: {index.source.working_copy.remote_uri} - {e}")
130
131
 
131
132
 
132
133
  async def _handle_list_indexes(index_query_service: IndexQueryService) -> None:
@@ -159,9 +160,7 @@ async def _handle_list_indexes(index_query_service: IndexQueryService) -> None:
159
160
  @click.option(
160
161
  "--auto-index", is_flag=True, help="Index all configured auto-index sources"
161
162
  )
162
- @click.option(
163
- "--sync", is_flag=True, help="Sync existing indexes with their remotes"
164
- )
163
+ @click.option("--sync", is_flag=True, help="Sync existing indexes with their remotes")
165
164
  @with_app_context
166
165
  @with_session
167
166
  async def index(
@@ -561,11 +560,15 @@ def serve(
561
560
  host: str,
562
561
  port: int,
563
562
  ) -> None:
564
- """Start the kodit server, which hosts the MCP server and the kodit API."""
563
+ """Start the kodit HTTP/SSE server with FastAPI integration."""
565
564
  log = structlog.get_logger(__name__)
566
565
  log.info("Starting kodit server", host=host, port=port)
567
566
  log_event("kodit.cli.serve")
568
567
 
568
+ # Disable uvicorn's websockets deprecation warnings
569
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module="websockets")
570
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module="uvicorn")
571
+
569
572
  # Configure uvicorn with graceful shutdown
570
573
  config = uvicorn.Config(
571
574
  "kodit.app:app",
@@ -587,6 +590,13 @@ def serve(
587
590
  server.run()
588
591
 
589
592
 
593
+ @cli.command()
594
+ def stdio() -> None:
595
+ """Start the kodit MCP server in STDIO mode."""
596
+ log_event("kodit.cli.stdio")
597
+ create_stdio_mcp_server()
598
+
599
+
590
600
  @cli.command()
591
601
  def version() -> None:
592
602
  """Show the version of kodit."""
@@ -23,7 +23,6 @@ if TYPE_CHECKING:
23
23
  from kodit.database import Database
24
24
 
25
25
  DEFAULT_BASE_DIR = Path.home() / ".kodit"
26
- DEFAULT_DB_URL = f"sqlite+aiosqlite:///{DEFAULT_BASE_DIR}/kodit.db"
27
26
  DEFAULT_LOG_LEVEL = "INFO"
28
27
  DEFAULT_LOG_FORMAT = "pretty"
29
28
  DEFAULT_DISABLE_TELEMETRY = False
@@ -160,7 +159,9 @@ class AppContext(BaseSettings):
160
159
  )
161
160
 
162
161
  data_dir: Path = Field(default=DEFAULT_BASE_DIR)
163
- db_url: str = Field(default=DEFAULT_DB_URL)
162
+ db_url: str = Field(
163
+ default_factory=lambda data: f"sqlite+aiosqlite:///{data['data_dir']}/kodit.db"
164
+ )
164
165
  log_level: str = Field(default=DEFAULT_LOG_LEVEL)
165
166
  log_format: str = Field(default=DEFAULT_LOG_FORMAT)
166
167
  disable_telemetry: bool = Field(default=DEFAULT_DISABLE_TELEMETRY)
@@ -7,7 +7,7 @@ from pathlib import Path
7
7
  from typing import TYPE_CHECKING
8
8
 
9
9
  import aiofiles
10
- import Stemmer
10
+ import Stemmer # type: ignore[import-not-found]
11
11
  import structlog
12
12
 
13
13
  from kodit.domain.services.bm25_service import BM25Repository
@@ -19,8 +19,8 @@ from kodit.domain.value_objects import (
19
19
  )
20
20
 
21
21
  if TYPE_CHECKING:
22
- import bm25s
23
- from bm25s.tokenization import Tokenized
22
+ import bm25s # type: ignore[import-untyped]
23
+ from bm25s.tokenization import Tokenized # type: ignore[import-untyped]
24
24
 
25
25
  SNIPPET_IDS_FILE = "snippet_ids.jsonl"
26
26
 
@@ -1,6 +1,7 @@
1
1
  """Working copy provider for git-based sources."""
2
2
 
3
3
  import hashlib
4
+ import shutil
4
5
  from pathlib import Path
5
6
 
6
7
  import git
@@ -47,6 +48,26 @@ class GitWorkingCopyProvider:
47
48
  async def sync(self, uri: str) -> Path:
48
49
  """Refresh a Git working copy."""
49
50
  clone_path = self.get_clone_path(uri)
50
- repo = git.Repo(clone_path)
51
- repo.remotes.origin.pull()
51
+
52
+ # Check if the clone directory exists and is a valid Git repository
53
+ if not clone_path.exists() or not (clone_path / ".git").exists():
54
+ self.log.info(
55
+ "Clone directory does not exist or is not a Git repository, "
56
+ "preparing...",
57
+ uri=uri, clone_path=str(clone_path)
58
+ )
59
+ return await self.prepare(uri)
60
+
61
+ try:
62
+ repo = git.Repo(clone_path)
63
+ repo.remotes.origin.pull()
64
+ except git.InvalidGitRepositoryError:
65
+ self.log.warning(
66
+ "Invalid Git repository found, re-cloning...",
67
+ uri=uri, clone_path=str(clone_path)
68
+ )
69
+ # Remove the invalid directory and re-clone
70
+ shutil.rmtree(clone_path)
71
+ return await self.prepare(uri)
72
+
52
73
  return clone_path