futuresearch 0.6.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 (234) hide show
  1. futuresearch-0.6.0/.claude/skills/deploy-mcp/SKILL.md +118 -0
  2. futuresearch-0.6.0/.claude/skills/run-mcp-local/SKILL.md +229 -0
  3. futuresearch-0.6.0/.claude-plugin/marketplace.json +17 -0
  4. futuresearch-0.6.0/.claude-plugin/plugin.json +18 -0
  5. futuresearch-0.6.0/.dockerignore +17 -0
  6. futuresearch-0.6.0/.env.example +12 -0
  7. futuresearch-0.6.0/.gitattributes +10 -0
  8. futuresearch-0.6.0/.github/workflows/ci.yaml +91 -0
  9. futuresearch-0.6.0/.github/workflows/claude-code-review.yml +72 -0
  10. futuresearch-0.6.0/.github/workflows/deploy-mcp.yaml +198 -0
  11. futuresearch-0.6.0/.github/workflows/docs-sync-check.yml +81 -0
  12. futuresearch-0.6.0/.github/workflows/integration-tests.yml +32 -0
  13. futuresearch-0.6.0/.github/workflows/pr-content-check.yaml +178 -0
  14. futuresearch-0.6.0/.github/workflows/publish.yaml +86 -0
  15. futuresearch-0.6.0/.github/workflows/skill-version-check.yaml +27 -0
  16. futuresearch-0.6.0/.gitignore +232 -0
  17. futuresearch-0.6.0/CITATION.cff +22 -0
  18. futuresearch-0.6.0/LICENSE.txt +21 -0
  19. futuresearch-0.6.0/PKG-INFO +284 -0
  20. futuresearch-0.6.0/README.md +271 -0
  21. futuresearch-0.6.0/docs/case_studies/llm-powered-screening-at-scale/notebook.ipynb +709 -0
  22. futuresearch-0.6.0/docs/case_studies/match-software-vendors-to-requirements/notebook.ipynb +499 -0
  23. futuresearch-0.6.0/docs/case_studies/merge-contacts-with-company-data/notebook.ipynb +962 -0
  24. futuresearch-0.6.0/docs/case_studies/merge-overlapping-contact-lists/notebook.ipynb +940 -0
  25. futuresearch-0.6.0/docs/case_studies/multi-stage-lead-qualification/notebook.ipynb +949 -0
  26. futuresearch-0.6.0/docs/case_studies/research-and-rank-permit-times/notebook.ipynb +815 -0
  27. futuresearch-0.6.0/docs/case_studies/score-leads-from-fragmented-data/notebook.ipynb +742 -0
  28. futuresearch-0.6.0/docs/case_studies/score-leads-without-crm-history/notebook.ipynb +752 -0
  29. futuresearch-0.6.0/docs/case_studies/screen-job-postings-by-criteria/notebook.ipynb +535 -0
  30. futuresearch-0.6.0/futuresearch-mcp/.mcpbignore +13 -0
  31. futuresearch-0.6.0/futuresearch-mcp/README.md +181 -0
  32. futuresearch-0.6.0/futuresearch-mcp/deploy/.dockerignore +15 -0
  33. futuresearch-0.6.0/futuresearch-mcp/deploy/.env.example +8 -0
  34. futuresearch-0.6.0/futuresearch-mcp/deploy/Dockerfile +36 -0
  35. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/.gitignore +4 -0
  36. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/.sops.yaml +2 -0
  37. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/Chart.yaml +6 -0
  38. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/secrets.enc.yaml +15 -0
  39. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/secrets.staging.enc.yaml +14 -0
  40. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/deployment.yaml +96 -0
  41. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/gcpbackendpolicy.yaml +15 -0
  42. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/httproute.yaml +19 -0
  43. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/networkpolicy.yaml +90 -0
  44. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/secrets.yaml +13 -0
  45. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/service.yaml +17 -0
  46. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/templates/serviceaccount.yaml +5 -0
  47. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/values.staging.yaml +16 -0
  48. futuresearch-0.6.0/futuresearch-mcp/deploy/chart/values.yaml +91 -0
  49. futuresearch-0.6.0/futuresearch-mcp/deploy/docker-compose.local.yaml +12 -0
  50. futuresearch-0.6.0/futuresearch-mcp/deploy/docker-compose.multi.yaml +22 -0
  51. futuresearch-0.6.0/futuresearch-mcp/deploy/docker-compose.yaml +62 -0
  52. futuresearch-0.6.0/futuresearch-mcp/deploy/nginx.conf +13 -0
  53. futuresearch-0.6.0/futuresearch-mcp/images/future-search-logo-128.png +3 -0
  54. futuresearch-0.6.0/futuresearch-mcp/manifest.json +115 -0
  55. futuresearch-0.6.0/futuresearch-mcp/pyproject.toml +69 -0
  56. futuresearch-0.6.0/futuresearch-mcp/server.json +33 -0
  57. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/__init__.py +1 -0
  58. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/app.py +183 -0
  59. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/auth.py +712 -0
  60. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/config.py +193 -0
  61. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/http_config.py +264 -0
  62. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/middleware.py +189 -0
  63. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/models.py +792 -0
  64. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/redis_store.py +322 -0
  65. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/result_store.py +425 -0
  66. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/routes.py +326 -0
  67. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/server.py +160 -0
  68. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/templates.py +898 -0
  69. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/tool_helpers.py +570 -0
  70. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/tools.py +1433 -0
  71. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/uploads.py +274 -0
  72. futuresearch-0.6.0/futuresearch-mcp/src/futuresearch_mcp/utils.py +457 -0
  73. futuresearch-0.6.0/futuresearch-mcp/tests/__init__.py +1 -0
  74. futuresearch-0.6.0/futuresearch-mcp/tests/conftest.py +284 -0
  75. futuresearch-0.6.0/futuresearch-mcp/tests/test_auth.py +904 -0
  76. futuresearch-0.6.0/futuresearch-mcp/tests/test_http_integration.py +599 -0
  77. futuresearch-0.6.0/futuresearch-mcp/tests/test_http_real.py +255 -0
  78. futuresearch-0.6.0/futuresearch-mcp/tests/test_http_transport.py +353 -0
  79. futuresearch-0.6.0/futuresearch-mcp/tests/test_integration.py +559 -0
  80. futuresearch-0.6.0/futuresearch-mcp/tests/test_manifest_sync.py +66 -0
  81. futuresearch-0.6.0/futuresearch-mcp/tests/test_mcp_e2e.py +469 -0
  82. futuresearch-0.6.0/futuresearch-mcp/tests/test_middleware.py +239 -0
  83. futuresearch-0.6.0/futuresearch-mcp/tests/test_redis_utils.py +77 -0
  84. futuresearch-0.6.0/futuresearch-mcp/tests/test_result_store.py +1112 -0
  85. futuresearch-0.6.0/futuresearch-mcp/tests/test_routes.py +498 -0
  86. futuresearch-0.6.0/futuresearch-mcp/tests/test_security_hardening.py +100 -0
  87. futuresearch-0.6.0/futuresearch-mcp/tests/test_server.py +2152 -0
  88. futuresearch-0.6.0/futuresearch-mcp/tests/test_state_redis.py +126 -0
  89. futuresearch-0.6.0/futuresearch-mcp/tests/test_stdio_content.py +829 -0
  90. futuresearch-0.6.0/futuresearch-mcp/tests/test_tool_helpers.py +162 -0
  91. futuresearch-0.6.0/futuresearch-mcp/tests/test_ua_detection.py +72 -0
  92. futuresearch-0.6.0/futuresearch-mcp/tests/test_uploads.py +404 -0
  93. futuresearch-0.6.0/futuresearch-mcp/tests/test_utils.py +504 -0
  94. futuresearch-0.6.0/gemini-extension.json +14 -0
  95. futuresearch-0.6.0/generate_openapi.sh +19 -0
  96. futuresearch-0.6.0/images/future-search-logo-128.webp +3 -0
  97. futuresearch-0.6.0/lefthook.yml +33 -0
  98. futuresearch-0.6.0/openapi-python-client.yaml +2 -0
  99. futuresearch-0.6.0/pyproject.toml +87 -0
  100. futuresearch-0.6.0/skills/futuresearch-python/SKILL.md +606 -0
  101. futuresearch-0.6.0/src/futuresearch/__init__.py +28 -0
  102. futuresearch-0.6.0/src/futuresearch/api_utils.py +65 -0
  103. futuresearch-0.6.0/src/futuresearch/billing.py +29 -0
  104. futuresearch-0.6.0/src/futuresearch/built_in_lists.py +104 -0
  105. futuresearch-0.6.0/src/futuresearch/constants.py +13 -0
  106. futuresearch-0.6.0/src/futuresearch/generated/__init__.py +8 -0
  107. futuresearch-0.6.0/src/futuresearch/generated/api/__init__.py +1 -0
  108. futuresearch-0.6.0/src/futuresearch/generated/api/artifacts/__init__.py +1 -0
  109. futuresearch-0.6.0/src/futuresearch/generated/api/artifacts/upload_data_artifacts_upload_post.py +212 -0
  110. futuresearch-0.6.0/src/futuresearch/generated/api/billing/__init__.py +1 -0
  111. futuresearch-0.6.0/src/futuresearch/generated/api/billing/get_billing_balance_billing_get.py +131 -0
  112. futuresearch-0.6.0/src/futuresearch/generated/api/built_in_lists/__init__.py +1 -0
  113. futuresearch-0.6.0/src/futuresearch/generated/api/built_in_lists/list_built_in_lists_endpoint_built_in_lists_get.py +198 -0
  114. futuresearch-0.6.0/src/futuresearch/generated/api/built_in_lists/use_built_in_list_endpoint_built_in_lists_use_post.py +174 -0
  115. futuresearch-0.6.0/src/futuresearch/generated/api/default/__init__.py +1 -0
  116. futuresearch-0.6.0/src/futuresearch/generated/api/default/whoami_whoami_get.py +135 -0
  117. futuresearch-0.6.0/src/futuresearch/generated/api/health/__init__.py +1 -0
  118. futuresearch-0.6.0/src/futuresearch/generated/api/health/health_health_get.py +123 -0
  119. futuresearch-0.6.0/src/futuresearch/generated/api/operations/__init__.py +1 -0
  120. futuresearch-0.6.0/src/futuresearch/generated/api/operations/agent_map_operations_agent_map_post.py +219 -0
  121. futuresearch-0.6.0/src/futuresearch/generated/api/operations/classify_operations_classify_post.py +195 -0
  122. futuresearch-0.6.0/src/futuresearch/generated/api/operations/dedupe_operations_dedupe_post.py +195 -0
  123. futuresearch-0.6.0/src/futuresearch/generated/api/operations/forecast_operations_forecast_post.py +195 -0
  124. futuresearch-0.6.0/src/futuresearch/generated/api/operations/merge_operations_merge_post.py +195 -0
  125. futuresearch-0.6.0/src/futuresearch/generated/api/operations/rank_operations_rank_post.py +195 -0
  126. futuresearch-0.6.0/src/futuresearch/generated/api/operations/single_agent_operations_single_agent_post.py +251 -0
  127. futuresearch-0.6.0/src/futuresearch/generated/api/sessions/__init__.py +1 -0
  128. futuresearch-0.6.0/src/futuresearch/generated/api/sessions/create_session_endpoint_sessions_post.py +174 -0
  129. futuresearch-0.6.0/src/futuresearch/generated/api/sessions/list_session_tasks_sessions_session_id_tasks_get.py +169 -0
  130. futuresearch-0.6.0/src/futuresearch/generated/api/sessions/list_sessions_endpoint_sessions_get.py +188 -0
  131. futuresearch-0.6.0/src/futuresearch/generated/api/tasks/__init__.py +1 -0
  132. futuresearch-0.6.0/src/futuresearch/generated/api/tasks/cancel_task_tasks_task_id_cancel_post.py +175 -0
  133. futuresearch-0.6.0/src/futuresearch/generated/api/tasks/get_task_result_tasks_task_id_result_get.py +179 -0
  134. futuresearch-0.6.0/src/futuresearch/generated/api/tasks/get_task_status_tasks_task_id_status_get.py +175 -0
  135. futuresearch-0.6.0/src/futuresearch/generated/api/uploads/__init__.py +1 -0
  136. futuresearch-0.6.0/src/futuresearch/generated/api/uploads/request_upload_uploads_request_post.py +178 -0
  137. futuresearch-0.6.0/src/futuresearch/generated/api/uploads/upload_csv_presigned_uploads_upload_id_put.py +173 -0
  138. futuresearch-0.6.0/src/futuresearch/generated/client.py +268 -0
  139. futuresearch-0.6.0/src/futuresearch/generated/errors.py +16 -0
  140. futuresearch-0.6.0/src/futuresearch/generated/models/__init__.py +141 -0
  141. futuresearch-0.6.0/src/futuresearch/generated/models/agent_map_operation.py +356 -0
  142. futuresearch-0.6.0/src/futuresearch/generated/models/agent_map_operation_input_type_1_item.py +46 -0
  143. futuresearch-0.6.0/src/futuresearch/generated/models/agent_map_operation_input_type_2.py +46 -0
  144. futuresearch-0.6.0/src/futuresearch/generated/models/agent_map_operation_response_schema_type_0.py +46 -0
  145. futuresearch-0.6.0/src/futuresearch/generated/models/billing_response.py +62 -0
  146. futuresearch-0.6.0/src/futuresearch/generated/models/built_in_list_item.py +86 -0
  147. futuresearch-0.6.0/src/futuresearch/generated/models/built_in_lists_response.py +83 -0
  148. futuresearch-0.6.0/src/futuresearch/generated/models/cancel_task_response.py +72 -0
  149. futuresearch-0.6.0/src/futuresearch/generated/models/classify_operation.py +198 -0
  150. futuresearch-0.6.0/src/futuresearch/generated/models/classify_operation_input_type_1_item.py +46 -0
  151. futuresearch-0.6.0/src/futuresearch/generated/models/classify_operation_input_type_2.py +46 -0
  152. futuresearch-0.6.0/src/futuresearch/generated/models/create_artifact_response.py +102 -0
  153. futuresearch-0.6.0/src/futuresearch/generated/models/create_session.py +61 -0
  154. futuresearch-0.6.0/src/futuresearch/generated/models/dedupe_operation.py +209 -0
  155. futuresearch-0.6.0/src/futuresearch/generated/models/dedupe_operation_input_type_1_item.py +46 -0
  156. futuresearch-0.6.0/src/futuresearch/generated/models/dedupe_operation_input_type_2.py +46 -0
  157. futuresearch-0.6.0/src/futuresearch/generated/models/dedupe_operation_strategy.py +10 -0
  158. futuresearch-0.6.0/src/futuresearch/generated/models/error_response.py +109 -0
  159. futuresearch-0.6.0/src/futuresearch/generated/models/error_response_details_type_0.py +46 -0
  160. futuresearch-0.6.0/src/futuresearch/generated/models/forecast_operation.py +172 -0
  161. futuresearch-0.6.0/src/futuresearch/generated/models/forecast_operation_input_type_1_item.py +46 -0
  162. futuresearch-0.6.0/src/futuresearch/generated/models/forecast_operation_input_type_2.py +46 -0
  163. futuresearch-0.6.0/src/futuresearch/generated/models/health_response.py +61 -0
  164. futuresearch-0.6.0/src/futuresearch/generated/models/http_validation_error.py +79 -0
  165. futuresearch-0.6.0/src/futuresearch/generated/models/insufficient_balance_response.py +88 -0
  166. futuresearch-0.6.0/src/futuresearch/generated/models/llm_enum_public.py +50 -0
  167. futuresearch-0.6.0/src/futuresearch/generated/models/merge_breakdown_response.py +215 -0
  168. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation.py +333 -0
  169. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_left_input_type_1_item.py +46 -0
  170. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_left_input_type_2.py +46 -0
  171. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_relationship_type_type_0.py +11 -0
  172. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_right_input_type_1_item.py +46 -0
  173. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_right_input_type_2.py +46 -0
  174. futuresearch-0.6.0/src/futuresearch/generated/models/merge_operation_use_web_search_type_0.py +10 -0
  175. futuresearch-0.6.0/src/futuresearch/generated/models/operation_response.py +131 -0
  176. futuresearch-0.6.0/src/futuresearch/generated/models/public_effort_level.py +10 -0
  177. futuresearch-0.6.0/src/futuresearch/generated/models/public_task_type.py +15 -0
  178. futuresearch-0.6.0/src/futuresearch/generated/models/rank_operation.py +223 -0
  179. futuresearch-0.6.0/src/futuresearch/generated/models/rank_operation_input_type_1_item.py +46 -0
  180. futuresearch-0.6.0/src/futuresearch/generated/models/rank_operation_input_type_2.py +46 -0
  181. futuresearch-0.6.0/src/futuresearch/generated/models/rank_operation_response_schema_type_0.py +46 -0
  182. futuresearch-0.6.0/src/futuresearch/generated/models/request_upload_request.py +94 -0
  183. futuresearch-0.6.0/src/futuresearch/generated/models/request_upload_response.py +94 -0
  184. futuresearch-0.6.0/src/futuresearch/generated/models/session_list_item.py +88 -0
  185. futuresearch-0.6.0/src/futuresearch/generated/models/session_list_response.py +99 -0
  186. futuresearch-0.6.0/src/futuresearch/generated/models/session_response.py +62 -0
  187. futuresearch-0.6.0/src/futuresearch/generated/models/session_task_item.py +200 -0
  188. futuresearch-0.6.0/src/futuresearch/generated/models/session_tasks_response.py +84 -0
  189. futuresearch-0.6.0/src/futuresearch/generated/models/single_agent_operation.py +345 -0
  190. futuresearch-0.6.0/src/futuresearch/generated/models/single_agent_operation_input_type_1_item.py +46 -0
  191. futuresearch-0.6.0/src/futuresearch/generated/models/single_agent_operation_input_type_2.py +46 -0
  192. futuresearch-0.6.0/src/futuresearch/generated/models/single_agent_operation_response_schema_type_0.py +46 -0
  193. futuresearch-0.6.0/src/futuresearch/generated/models/task_progress_info.py +93 -0
  194. futuresearch-0.6.0/src/futuresearch/generated/models/task_result_response.py +218 -0
  195. futuresearch-0.6.0/src/futuresearch/generated/models/task_result_response_data_type_0_item.py +46 -0
  196. futuresearch-0.6.0/src/futuresearch/generated/models/task_result_response_data_type_1.py +46 -0
  197. futuresearch-0.6.0/src/futuresearch/generated/models/task_status.py +12 -0
  198. futuresearch-0.6.0/src/futuresearch/generated/models/task_status_response.py +225 -0
  199. futuresearch-0.6.0/src/futuresearch/generated/models/upload_complete_response.py +94 -0
  200. futuresearch-0.6.0/src/futuresearch/generated/models/upload_data_artifacts_upload_post_files_body.py +95 -0
  201. futuresearch-0.6.0/src/futuresearch/generated/models/upload_data_artifacts_upload_post_json_body.py +130 -0
  202. futuresearch-0.6.0/src/futuresearch/generated/models/upload_data_artifacts_upload_post_json_body_data_type_0_item.py +46 -0
  203. futuresearch-0.6.0/src/futuresearch/generated/models/upload_data_artifacts_upload_post_json_body_data_type_1.py +46 -0
  204. futuresearch-0.6.0/src/futuresearch/generated/models/use_built_in_list_request.py +94 -0
  205. futuresearch-0.6.0/src/futuresearch/generated/models/use_built_in_list_response.py +78 -0
  206. futuresearch-0.6.0/src/futuresearch/generated/models/validation_error.py +90 -0
  207. futuresearch-0.6.0/src/futuresearch/generated/models/whoami_whoami_get_response_whoami_whoami_get.py +46 -0
  208. futuresearch-0.6.0/src/futuresearch/generated/py.typed +1 -0
  209. futuresearch-0.6.0/src/futuresearch/generated/types.py +54 -0
  210. futuresearch-0.6.0/src/futuresearch/ops.py +887 -0
  211. futuresearch-0.6.0/src/futuresearch/result.py +94 -0
  212. futuresearch-0.6.0/src/futuresearch/session.py +167 -0
  213. futuresearch-0.6.0/src/futuresearch/task.py +381 -0
  214. futuresearch-0.6.0/stubs/everyrow/README.md +9 -0
  215. futuresearch-0.6.0/stubs/everyrow/pyproject.toml +14 -0
  216. futuresearch-0.6.0/stubs/everyrow/src/everyrow/__init__.py +36 -0
  217. futuresearch-0.6.0/stubs/everyrow-mcp/README.md +9 -0
  218. futuresearch-0.6.0/stubs/everyrow-mcp/pyproject.toml +17 -0
  219. futuresearch-0.6.0/stubs/everyrow-mcp/src/everyrow_mcp/__init__.py +8 -0
  220. futuresearch-0.6.0/tests/__init__.py +0 -0
  221. futuresearch-0.6.0/tests/integration/__init__.py +0 -0
  222. futuresearch-0.6.0/tests/integration/conftest.py +108 -0
  223. futuresearch-0.6.0/tests/integration/test_agent_map.py +82 -0
  224. futuresearch-0.6.0/tests/integration/test_classify.py +68 -0
  225. futuresearch-0.6.0/tests/integration/test_dedupe.py +203 -0
  226. futuresearch-0.6.0/tests/integration/test_forecast.py +38 -0
  227. futuresearch-0.6.0/tests/integration/test_merge.py +135 -0
  228. futuresearch-0.6.0/tests/integration/test_rank.py +111 -0
  229. futuresearch-0.6.0/tests/integration/test_single_agent.py +83 -0
  230. futuresearch-0.6.0/tests/test_ops.py +597 -0
  231. futuresearch-0.6.0/tests/test_session.py +376 -0
  232. futuresearch-0.6.0/tests/test_task.py +293 -0
  233. futuresearch-0.6.0/tests/test_version.py +92 -0
  234. futuresearch-0.6.0/uv.lock +2890 -0
@@ -0,0 +1,118 @@
1
+ ---
2
+ name: deploy-mcp
3
+ description: Deploy the FutureSearch MCP server to staging or production on GKE. Use when the user wants to deploy, redeploy, roll back, scale replicas, or check deployment status. Triggers on deploy, redeploy, staging, production, rollout, scale, replicas.
4
+ ---
5
+
6
+ # Deploying the MCP Server
7
+
8
+ ## Quick Deploy
9
+
10
+ ### Staging (from main)
11
+
12
+ ```bash
13
+ gh workflow run "Deploy MCP Server" -f branch=main -f deploy_staging=true
14
+ ```
15
+
16
+ ### Production (from main)
17
+
18
+ ```bash
19
+ gh workflow run "Deploy MCP Server" -f branch=main -f deploy_production=true
20
+ ```
21
+
22
+ ### Both environments
23
+
24
+ ```bash
25
+ gh workflow run "Deploy MCP Server" -f branch=main -f deploy_staging=true -f deploy_production=true
26
+ ```
27
+
28
+ ### From a feature branch
29
+
30
+ ```bash
31
+ gh workflow run "Deploy MCP Server" -f branch=feat/my-branch -f deploy_staging=true
32
+ ```
33
+
34
+ ## Monitoring a Deploy
35
+
36
+ ```bash
37
+ # Watch the workflow run
38
+ gh run list --workflow="Deploy MCP Server" --limit 3
39
+ gh run watch <run-id>
40
+
41
+ # Check pod rollout
42
+ kubectl rollout status deploy/futuresearch-mcp-staging -n futuresearch-mcp-staging --timeout=5m
43
+
44
+ # Verify pods are running
45
+ kubectl get pods -n futuresearch-mcp-staging -o wide
46
+ ```
47
+
48
+ ## How It Works
49
+
50
+ The GitHub Actions workflow (`.github/workflows/deploy-mcp.yaml`) does:
51
+
52
+ 1. **Checks** — ruff lint + pytest on the target branch
53
+ 2. **Build & push** — Docker image to GAR, tagged with short SHA (+ `latest` on main)
54
+ 3. **Deploy** — Helm upgrade with layered values:
55
+ - `values.yaml` — base config
56
+ - `values.staging.yaml` — staging overrides (MCP_SERVER_URL, REDIS_DB, replicaCount, host)
57
+ - `values.secrets.staging.yaml` — SOPS-decrypted secrets (Supabase, API keys)
58
+
59
+ The deploy uses `--atomic` so it auto-rolls back on failure.
60
+
61
+ ## Scaling Replicas
62
+
63
+ ### Via Helm values (persistent)
64
+
65
+ Edit `futuresearch-mcp/deploy/chart/values.staging.yaml`:
66
+ ```yaml
67
+ replicaCount: 2 # Change this
68
+ ```
69
+ Commit, push, and redeploy.
70
+
71
+ ### Via kubectl (temporary, resets on next deploy)
72
+
73
+ ```bash
74
+ # Staging
75
+ kubectl scale deploy futuresearch-mcp-staging -n futuresearch-mcp-staging --replicas=3
76
+
77
+ # Take offline
78
+ kubectl scale deploy futuresearch-mcp-staging -n futuresearch-mcp-staging --replicas=0
79
+ ```
80
+
81
+ ## Environments
82
+
83
+ | Environment | Namespace | Host | Redis DB |
84
+ |---|---|---|---|
85
+ | Staging | `futuresearch-mcp-staging` | `mcp-staging.everyrow.io` | 14 |
86
+ | Production | `futuresearch-mcp` | `mcp.everyrow.io` | (default in values.yaml) |
87
+
88
+ Both environments hit the **same production FutureSearch API** — there is no staging API.
89
+
90
+ ## Updating Secrets
91
+
92
+ ```bash
93
+ # View current secrets
94
+ sops -d futuresearch-mcp/deploy/chart/secrets.staging.enc.yaml
95
+
96
+ # Update a value
97
+ sops --set '["secrets"]["data"]["KEY_NAME"] "new-value"' futuresearch-mcp/deploy/chart/secrets.staging.enc.yaml
98
+ ```
99
+
100
+ Commit the encrypted file and redeploy.
101
+
102
+ ## Key Files
103
+
104
+ | File | Purpose |
105
+ |------|---------|
106
+ | `.github/workflows/deploy-mcp.yaml` | CI/CD workflow (checks → build → deploy) |
107
+ | `futuresearch-mcp/deploy/chart/values.yaml` | Base Helm values |
108
+ | `futuresearch-mcp/deploy/chart/values.staging.yaml` | Staging overrides |
109
+ | `futuresearch-mcp/deploy/chart/secrets.enc.yaml` | Production secrets (SOPS) |
110
+ | `futuresearch-mcp/deploy/chart/secrets.staging.enc.yaml` | Staging secrets (SOPS) |
111
+ | `futuresearch-mcp/deploy/Dockerfile` | Server container image |
112
+
113
+ ## Gotchas
114
+
115
+ - **Branch protection on main**: Can't push directly — create a PR and merge first, then deploy from main.
116
+ - **SOPS decryption requires GCP IAM**: Run `gcloud auth application-default login` if decryption fails.
117
+ - **Concurrent deploys**: Workflow uses `cancel-in-progress: false` — if a deploy is running, the next one queues.
118
+ - **Atomic rollback**: `--atomic` means a failed deploy auto-reverts to the previous release. Check `helm history` if this happens.
@@ -0,0 +1,229 @@
1
+ ---
2
+ name: run-mcp-local
3
+ description: Run the FutureSearch HTTP MCP server locally with Docker Compose and optionally expose it via Cloudflare tunnel. Use when starting/stopping the local MCP server, debugging startup issues, connecting Claude.ai or Claude Desktop to a local instance, or checking server logs. Triggers on mcp local, mcp server, run mcp, mcp docker, mcp tunnel, cloudflare tunnel, mcp logs.
4
+ ---
5
+
6
+ # Running the FutureSearch MCP Server Locally
7
+
8
+ Two-container stack: **mcp-server** (FastAPI on :8000) and **redis** (on :6379), orchestrated by `futuresearch-mcp/deploy/docker-compose.yaml` with local overrides.
9
+
10
+ ## Pre-flight Checks
11
+
12
+ **CRITICAL: Always check for stale processes on port 8000 before starting.**
13
+
14
+ A leftover `futuresearch-mcp --no-auth` or similar process on the host will shadow the Docker container's port binding. All requests hit the stale process instead of the container — this can look like auth routes are broken, sheets tools are missing, etc.
15
+
16
+ ```bash
17
+ # Check for anything on port 8000
18
+ lsof -i :8000
19
+
20
+ # Kill if needed
21
+ lsof -ti :8000 | xargs kill -9
22
+ ```
23
+
24
+ Also check Docker is running:
25
+ ```bash
26
+ docker info --format '{{.ServerVersion}}' || colima start
27
+ ```
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ cd futuresearch-mcp/deploy
33
+
34
+ REDIS_PASSWORD=testpass \
35
+ MCP_SERVER_URL=http://localhost:8000 \
36
+ docker compose \
37
+ -f docker-compose.yaml \
38
+ -f docker-compose.local.yaml \
39
+ up -d --build
40
+ ```
41
+
42
+ Verify: `curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/health` should return `200`.
43
+
44
+ ### Optional env vars
45
+
46
+ Pass these alongside `REDIS_PASSWORD` and `MCP_SERVER_URL`:
47
+
48
+ | Env var | Default | Purpose |
49
+ |---------|---------|---------|
50
+ | `ENABLE_SHEETS_TOOLS` | `false` | Register Google Sheets tools |
51
+ | `TRUST_PROXY_HEADERS` | `false` | Trust X-Forwarded-For (required behind tunnel) |
52
+ | `EXTRA_ALLOWED_HOSTS` | (empty) | Extra hostnames for DNS rebinding allowlist |
53
+
54
+ These are templated in `docker-compose.local.yaml` as `${VAR:-default}` — the container must be **recreated** (not just restarted) for env var changes to take effect.
55
+
56
+ ## Secrets
57
+
58
+ The `.env` file at `futuresearch-mcp/deploy/.env` contains production secrets (Supabase, API keys, upload secret). It is already present and should NOT be committed or overwritten.
59
+
60
+ `REDIS_PASSWORD` is intentionally NOT in `.env` — always pass it as an env var (`testpass` for local dev).
61
+
62
+ ### Worktrees
63
+
64
+ The `.env` file is gitignored and won't exist in worktrees. Symlink it:
65
+
66
+ ```bash
67
+ ln -s /Users/rafaelpoyiadzi/Documents/git/futuresearch-python/futuresearch-mcp/deploy/.env \
68
+ <worktree-path>/futuresearch-mcp/deploy/.env
69
+ ```
70
+
71
+ ## Exposing via Cloudflare Tunnel
72
+
73
+ Required when testing with Claude.ai or Claude Desktop, which can't reach `localhost`.
74
+
75
+ ### Step 1: Kill stale tunnels and processes
76
+
77
+ ```bash
78
+ pkill -f cloudflared 2>/dev/null
79
+ rm -f /tmp/cf-tunnel.log
80
+ lsof -ti :8000 | xargs kill -9 2>/dev/null
81
+ ```
82
+
83
+ ### Step 2: Start the tunnel
84
+
85
+ ```bash
86
+ cloudflared tunnel --url http://localhost:8000 2>/tmp/cf-tunnel.log &
87
+ sleep 6
88
+ grep -oE 'https://[a-z0-9-]+\.trycloudflare\.com' /tmp/cf-tunnel.log | head -1
89
+ ```
90
+
91
+ This prints a URL like `https://something-something.trycloudflare.com`.
92
+
93
+ ### Step 3: Start (or restart) the MCP server with the tunnel URL
94
+
95
+ The server must know its public URL for OAuth redirects to work:
96
+
97
+ ```bash
98
+ cd futuresearch-mcp/deploy
99
+
100
+ REDIS_PASSWORD=testpass \
101
+ MCP_SERVER_URL=https://something-something.trycloudflare.com \
102
+ TRUST_PROXY_HEADERS=true \
103
+ ENABLE_SHEETS_TOOLS=true \
104
+ docker compose \
105
+ -f docker-compose.yaml \
106
+ -f docker-compose.local.yaml \
107
+ up -d --build
108
+ ```
109
+
110
+ Key: `MCP_SERVER_URL` must match the tunnel URL exactly, and `TRUST_PROXY_HEADERS=true` is required so the server trusts the forwarded headers from Cloudflare.
111
+
112
+ ### Step 4: Verify OAuth discovery works end-to-end
113
+
114
+ ```bash
115
+ # Through the tunnel (what Claude.ai sees)
116
+ curl -s https://<tunnel-url>/.well-known/oauth-authorization-server | python3 -m json.tool | head -5
117
+
118
+ # Locally
119
+ curl -s http://localhost:8000/.well-known/oauth-authorization-server | python3 -m json.tool | head -5
120
+ ```
121
+
122
+ Both should return JSON with `issuer`, `authorization_endpoint`, etc. If local returns 404 but tunnel works (or vice versa), check for stale processes on port 8000.
123
+
124
+ ### Step 5: Connect clients
125
+
126
+ **Claude.ai / Claude Desktop**: Use the tunnel URL as the MCP server URL in the client config.
127
+
128
+ **Claude Code**: Add a project-scoped MCP server (writes to `.claude/settings.local.json` in the current dir, not the global config):
129
+
130
+ ```bash
131
+ claude mcp add futuresearch --scope project --transport http <TUNNEL_URL>/mcp
132
+ ```
133
+
134
+ Then restart Claude Code. Remove with `claude mcp remove futuresearch --scope project`.
135
+
136
+ ## Logs
137
+
138
+ ```bash
139
+ # All logs
140
+ docker logs deploy-mcp-server-1 -f
141
+
142
+ # Filter for errors
143
+ docker logs deploy-mcp-server-1 2>&1 | grep -iE "error|warn|401|500"
144
+
145
+ # Check User-Agent strings (for widget/client detection work)
146
+ docker logs deploy-mcp-server-1 2>&1 | grep "User-Agent"
147
+ ```
148
+
149
+ ## Teardown
150
+
151
+ ```bash
152
+ cd futuresearch-mcp/deploy
153
+
154
+ REDIS_PASSWORD=testpass MCP_SERVER_URL=http://localhost:8000 \
155
+ docker compose -f docker-compose.yaml -f docker-compose.local.yaml down
156
+ ```
157
+
158
+ Kill the tunnel: `pkill -f cloudflared` or `kill %1` if it was backgrounded.
159
+
160
+ ## No-Auth Mode (without Docker)
161
+
162
+ Run the server directly with `uv run` — no Docker needed. Useful for quick local testing with the MCP Inspector.
163
+
164
+ **WARNING:** If you leave this running and later start the Docker stack, the local process will shadow Docker's port 8000. Always kill it first: `lsof -ti :8000 | xargs kill -9`
165
+
166
+ ### Prerequisites
167
+
168
+ - Redis running on localhost:6379 (e.g. `docker run -d --name test-redis -p 6379:6379 redis:7-alpine`)
169
+ - `FUTURESEARCH_API_KEY` (or legacy `FUTURESEARCH_API_KEY`) in `~/.claude/secrets/remote.env`
170
+
171
+ ### Start the server
172
+
173
+ ```bash
174
+ cd futuresearch-mcp
175
+ ALLOW_NO_AUTH=1 \
176
+ UPLOAD_SECRET=$(python -c "import secrets; print(secrets.token_urlsafe(32))") \
177
+ EXTRA_ALLOWED_HOSTS="host.docker.internal,localhost" \
178
+ bash scripts/run-no-auth.sh
179
+ ```
180
+
181
+ ### Connect with MCP Inspector
182
+
183
+ 1. Start the Inspector: `npx @modelcontextprotocol/inspector`
184
+ 2. Open the URL it prints (includes `MCP_PROXY_AUTH_TOKEN`)
185
+ 3. Settings:
186
+ - Transport: **Streamable HTTP**
187
+ - Mode: **Via Proxy**
188
+ - URL: `http://localhost:8000/mcp`
189
+ - Leave all OAuth fields **blank**
190
+ 4. Click **Connect**
191
+
192
+ Note: Direct mode won't work (CORS). Auth mode won't work (Inspector v0.21.0 doesn't handle the OAuth flow). Use Via Proxy with no-auth.
193
+
194
+ ### Connect with SDK client
195
+
196
+ ```bash
197
+ uv run python scripts/mcp_call.py list
198
+ uv run python scripts/mcp_call.py call futuresearch_balance
199
+ uv run python scripts/mcp_call.py call futuresearch_agent '{"params": {"task": "...", "data": [...]}}'
200
+ ```
201
+
202
+ Note: `mcp_call.py` only works against `--no-auth` servers. It doesn't do OAuth, so authenticated servers will show a subset of tools or fail.
203
+
204
+ ## Common Issues
205
+
206
+ | Problem | Solution |
207
+ |---------|----------|
208
+ | `required variable REDIS_PASSWORD is missing` | Pass `REDIS_PASSWORD=testpass` as env var |
209
+ | `required variable MCP_SERVER_URL is missing` | Pass `MCP_SERVER_URL=http://localhost:8000` (or tunnel URL) |
210
+ | OAuth 401 when connecting via tunnel | `MCP_SERVER_URL` doesn't match the tunnel URL, or `TRUST_PROXY_HEADERS=true` is missing |
211
+ | OAuth discovery returns 404 | **Check `lsof -i :8000`** — a stale local process is likely shadowing Docker. Kill it and restart containers with `down`/`up` (not just `restart`) |
212
+ | Port 8000 already in use | `lsof -ti :8000 | xargs kill -9` then restart |
213
+ | Redis connection refused | Check redis container is healthy: `docker ps | grep redis` |
214
+ | cloudflared output is empty | It writes to stderr: use `2>/tmp/cf-tunnel.log` redirect |
215
+ | Container doesn't pick up code changes | Add `--build` to the `docker compose up` command |
216
+ | Container doesn't pick up env var changes | Must recreate: `docker compose ... down && docker compose ... up -d` |
217
+ | `.env` not found in worktree | Symlink from main repo: `ln -s <main>/futuresearch-mcp/deploy/.env <worktree>/futuresearch-mcp/deploy/.env` |
218
+ | Sheets tools not showing in tool list | Pass `ENABLE_SHEETS_TOOLS=true` and recreate the container |
219
+ | `mcp_call.py` shows fewer tools than expected | It connects without auth — authenticated servers may filter tools |
220
+ | Docker daemon not running | `colima start` (may need `colima stop && colima start` if socket is stale) |
221
+
222
+ ## Key Files
223
+
224
+ | File | Purpose |
225
+ |------|---------|
226
+ | `futuresearch-mcp/deploy/docker-compose.yaml` | Base compose (server + redis) |
227
+ | `futuresearch-mcp/deploy/docker-compose.local.yaml` | Local overrides (ports, env passthrough) |
228
+ | `futuresearch-mcp/deploy/.env` | Production secrets (DO NOT commit changes) |
229
+ | `futuresearch-mcp/deploy/Dockerfile` | Server container build |
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "futuresearch",
3
+ "owner": {
4
+ "name": "FutureSearch"
5
+ },
6
+ "metadata": {
7
+ "description": "futuresearch plugins from FutureSearch"
8
+ },
9
+ "plugins": [
10
+ {
11
+ "name": "futuresearch",
12
+ "source": "./",
13
+ "description": "Give Claude Code a research team. Forecast, score, classify, or research every row of a dataset.",
14
+ "version": "0.6.0"
15
+ }
16
+ ]
17
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "futuresearch",
3
+ "description": "Give Claude Code a research team. Forecast, score, classify, or research every row of a dataset.",
4
+ "version": "0.6.0",
5
+ "author": {
6
+ "name": "FutureSearch"
7
+ },
8
+ "repository": "https://github.com/futuresearch/everyrow-sdk",
9
+ "mcpServers": {
10
+ "futuresearch": {
11
+ "command": "uvx",
12
+ "args": ["futuresearch-mcp"],
13
+ "env": {
14
+ "FUTURESEARCH_API_KEY": "${FUTURESEARCH_API_KEY}"
15
+ }
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ # Deny everything by default, allowlist what the Dockerfile needs
2
+ *
3
+
4
+ # Root workspace files
5
+ !pyproject.toml
6
+ !uv.lock
7
+ !README.md
8
+
9
+ # SDK package
10
+ !src/
11
+ !src/**
12
+
13
+ # MCP server package
14
+ !everyrow-mcp/pyproject.toml
15
+ !everyrow-mcp/README.md
16
+ !everyrow-mcp/src/
17
+ !everyrow-mcp/src/**
@@ -0,0 +1,12 @@
1
+ # FutureSearch API Configuration
2
+ # Required: Your API key for authenticating with the FutureSearch API
3
+ FUTURESEARCH_API_KEY=
4
+
5
+ # Optional: API base URL (defaults to https://futuresearch.ai/api/v0/)
6
+ # FUTURESEARCH_API_URL=https://futuresearch.ai/api/v0/
7
+ # Optional: App base URL (defaults to https://futuresearch.ai/)
8
+ # FUTURESEARCH_APP_URL=https://futuresearch.ai/
9
+
10
+ # Legacy env vars (still supported for backwards compatibility):
11
+ # EVERYROW_API_KEY=
12
+ # EVERYROW_API_URL=
@@ -0,0 +1,10 @@
1
+ *.pdf filter=lfs diff=lfs merge=lfs -text
2
+ *.png filter=lfs diff=lfs merge=lfs -text
3
+ *.jpg filter=lfs diff=lfs merge=lfs -text
4
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
5
+ *.svg filter=lfs diff=lfs merge=lfs -text
6
+ *.webp filter=lfs diff=lfs merge=lfs -text
7
+ *.mp4 filter=lfs diff=lfs merge=lfs -text
8
+ *.csv filter=lfs diff=lfs merge=lfs -text
9
+ *.tar filter=lfs diff=lfs merge=lfs -text
10
+ *.zip filter=lfs diff=lfs merge=lfs -text
@@ -0,0 +1,91 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ paths:
7
+ - "src/futuresearch/**"
8
+ - "tests/**"
9
+ - "examples/**"
10
+ - "pyproject.toml"
11
+ - "uv.lock"
12
+ - ".github/workflows/ci.yaml"
13
+ - "futuresearch-mcp/**"
14
+
15
+ pull_request:
16
+ paths:
17
+ - "src/futuresearch/**"
18
+ - "tests/**"
19
+ - "examples/**"
20
+ - "pyproject.toml"
21
+ - "uv.lock"
22
+ - "futuresearch-mcp/**"
23
+
24
+ concurrency:
25
+ group: ${{ github.workflow }}-${{ github.ref }}
26
+ cancel-in-progress: true
27
+
28
+ jobs:
29
+ checks:
30
+ name: python
31
+ runs-on: ubuntu-latest
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+
35
+ - name: Install uv
36
+ uses: astral-sh/setup-uv@v5
37
+ with:
38
+ enable-cache: true
39
+ cache-dependency-glob: "uv.lock"
40
+
41
+ - name: "Set up Python"
42
+ uses: actions/setup-python@v5
43
+ with:
44
+ python-version: "3.12"
45
+
46
+ - name: Install dependencies
47
+ run: uv sync
48
+
49
+ - name: Check formatting
50
+ run: uv run ruff format --check
51
+
52
+ - name: Run ruff
53
+ run: uv run ruff check
54
+
55
+ - name: Run tests
56
+ run: uv run pytest tests
57
+
58
+ - name: Run basedpyright
59
+ run: uv run basedpyright
60
+
61
+ mcp-checks:
62
+ name: futuresearch-mcp
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+
67
+ - name: Install redis-server
68
+ run: sudo apt-get update && sudo apt-get install -y redis-server
69
+
70
+ - name: Install uv
71
+ uses: astral-sh/setup-uv@v5
72
+ with:
73
+ enable-cache: true
74
+ cache-dependency-glob: "uv.lock"
75
+
76
+ - name: "Set up Python"
77
+ uses: actions/setup-python@v5
78
+ with:
79
+ python-version: "3.12"
80
+
81
+ - name: Install dependencies
82
+ run: uv sync --directory futuresearch-mcp
83
+
84
+ - name: Check formatting
85
+ run: uv run --directory futuresearch-mcp ruff format --check
86
+
87
+ - name: Run ruff
88
+ run: uv run --directory futuresearch-mcp ruff check
89
+
90
+ - name: Run tests
91
+ run: uv run --directory futuresearch-mcp pytest tests
@@ -0,0 +1,72 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ # Interactive @claude mentions
5
+ issue_comment:
6
+ types: [created]
7
+ pull_request_review_comment:
8
+ types: [created]
9
+ pull_request_review:
10
+ types: [submitted]
11
+ issues:
12
+ types: [opened, assigned]
13
+
14
+ concurrency:
15
+ group: claude-review-${{ github.event.pull_request.number || github.event.issue.number || github.run_id }}
16
+ cancel-in-progress: true
17
+
18
+ jobs:
19
+ # Interactive @claude responses
20
+ interactive:
21
+ if: |
22
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
23
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
24
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
25
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
26
+ runs-on: ubuntu-latest
27
+ permissions:
28
+ contents: write
29
+ pull-requests: write
30
+ issues: write
31
+ id-token: write
32
+ actions: read
33
+ steps:
34
+ - name: Checkout repository
35
+ uses: actions/checkout@v4
36
+ with:
37
+ fetch-depth: 0 # Full history needed for PR checkout
38
+
39
+ # When commenting on a PR, checkout the PR branch instead of default branch
40
+ - name: Checkout PR branch (for PR comments)
41
+ if: github.event_name == 'issue_comment' && github.event.issue.pull_request
42
+ run: gh pr checkout ${{ github.event.issue.number }}
43
+ env:
44
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45
+
46
+ - name: Run Claude Code
47
+ uses: anthropics/claude-code-action@v1
48
+ with:
49
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
50
+ github_token: ${{ secrets.GITHUB_TOKEN }}
51
+ track_progress: true
52
+ prompt: |
53
+ REPO: ${{ github.repository }}
54
+ PR NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
55
+
56
+ IMPORTANT CONTEXT:
57
+ - You are running in GitHub Actions, not a local dev environment
58
+ - Focus on static code analysis, not runtime verification
59
+
60
+ REVIEW APPROACH:
61
+ - Use inline comments with code suggestions that authors can accept directly
62
+ - Focus on actionable feedback, not nitpicks
63
+ - Check for security issues, correctness, and adherence to existing patterns
64
+
65
+ STYLE:
66
+ - Please try to discard outdated comments from previous runs and keep the discussions in threads
67
+ - Update the comment message with the summary continuously, instead of adding more and more of these
68
+ per each review
69
+
70
+ claude_args: |
71
+ --model claude-opus-4-6
72
+ --allowedTools "Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh issue view:*),Bash(gh pr checks:*),Read,Glob,Grep,Task,WebSearch,WebFetch"