futuresearch-mcp 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 (66) hide show
  1. futuresearch_mcp-0.6.0/.gitignore +232 -0
  2. futuresearch_mcp-0.6.0/.mcpbignore +13 -0
  3. futuresearch_mcp-0.6.0/PKG-INFO +200 -0
  4. futuresearch_mcp-0.6.0/README.md +181 -0
  5. futuresearch_mcp-0.6.0/deploy/.dockerignore +15 -0
  6. futuresearch_mcp-0.6.0/deploy/.env.example +8 -0
  7. futuresearch_mcp-0.6.0/deploy/Dockerfile +36 -0
  8. futuresearch_mcp-0.6.0/deploy/chart/.gitignore +4 -0
  9. futuresearch_mcp-0.6.0/deploy/chart/.sops.yaml +2 -0
  10. futuresearch_mcp-0.6.0/deploy/chart/Chart.yaml +6 -0
  11. futuresearch_mcp-0.6.0/deploy/chart/secrets.enc.yaml +15 -0
  12. futuresearch_mcp-0.6.0/deploy/chart/secrets.staging.enc.yaml +14 -0
  13. futuresearch_mcp-0.6.0/deploy/chart/templates/deployment.yaml +96 -0
  14. futuresearch_mcp-0.6.0/deploy/chart/templates/gcpbackendpolicy.yaml +15 -0
  15. futuresearch_mcp-0.6.0/deploy/chart/templates/httproute.yaml +19 -0
  16. futuresearch_mcp-0.6.0/deploy/chart/templates/networkpolicy.yaml +90 -0
  17. futuresearch_mcp-0.6.0/deploy/chart/templates/secrets.yaml +13 -0
  18. futuresearch_mcp-0.6.0/deploy/chart/templates/service.yaml +17 -0
  19. futuresearch_mcp-0.6.0/deploy/chart/templates/serviceaccount.yaml +5 -0
  20. futuresearch_mcp-0.6.0/deploy/chart/values.staging.yaml +16 -0
  21. futuresearch_mcp-0.6.0/deploy/chart/values.yaml +91 -0
  22. futuresearch_mcp-0.6.0/deploy/docker-compose.local.yaml +12 -0
  23. futuresearch_mcp-0.6.0/deploy/docker-compose.multi.yaml +22 -0
  24. futuresearch_mcp-0.6.0/deploy/docker-compose.yaml +62 -0
  25. futuresearch_mcp-0.6.0/deploy/nginx.conf +13 -0
  26. futuresearch_mcp-0.6.0/images/future-search-logo-128.png +3 -0
  27. futuresearch_mcp-0.6.0/manifest.json +115 -0
  28. futuresearch_mcp-0.6.0/pyproject.toml +69 -0
  29. futuresearch_mcp-0.6.0/server.json +33 -0
  30. futuresearch_mcp-0.6.0/src/futuresearch_mcp/__init__.py +1 -0
  31. futuresearch_mcp-0.6.0/src/futuresearch_mcp/app.py +183 -0
  32. futuresearch_mcp-0.6.0/src/futuresearch_mcp/auth.py +712 -0
  33. futuresearch_mcp-0.6.0/src/futuresearch_mcp/config.py +193 -0
  34. futuresearch_mcp-0.6.0/src/futuresearch_mcp/http_config.py +264 -0
  35. futuresearch_mcp-0.6.0/src/futuresearch_mcp/middleware.py +189 -0
  36. futuresearch_mcp-0.6.0/src/futuresearch_mcp/models.py +792 -0
  37. futuresearch_mcp-0.6.0/src/futuresearch_mcp/redis_store.py +322 -0
  38. futuresearch_mcp-0.6.0/src/futuresearch_mcp/result_store.py +425 -0
  39. futuresearch_mcp-0.6.0/src/futuresearch_mcp/routes.py +326 -0
  40. futuresearch_mcp-0.6.0/src/futuresearch_mcp/server.py +160 -0
  41. futuresearch_mcp-0.6.0/src/futuresearch_mcp/templates.py +898 -0
  42. futuresearch_mcp-0.6.0/src/futuresearch_mcp/tool_helpers.py +570 -0
  43. futuresearch_mcp-0.6.0/src/futuresearch_mcp/tools.py +1433 -0
  44. futuresearch_mcp-0.6.0/src/futuresearch_mcp/uploads.py +274 -0
  45. futuresearch_mcp-0.6.0/src/futuresearch_mcp/utils.py +457 -0
  46. futuresearch_mcp-0.6.0/tests/__init__.py +1 -0
  47. futuresearch_mcp-0.6.0/tests/conftest.py +284 -0
  48. futuresearch_mcp-0.6.0/tests/test_auth.py +904 -0
  49. futuresearch_mcp-0.6.0/tests/test_http_integration.py +599 -0
  50. futuresearch_mcp-0.6.0/tests/test_http_real.py +255 -0
  51. futuresearch_mcp-0.6.0/tests/test_http_transport.py +353 -0
  52. futuresearch_mcp-0.6.0/tests/test_integration.py +559 -0
  53. futuresearch_mcp-0.6.0/tests/test_manifest_sync.py +66 -0
  54. futuresearch_mcp-0.6.0/tests/test_mcp_e2e.py +469 -0
  55. futuresearch_mcp-0.6.0/tests/test_middleware.py +239 -0
  56. futuresearch_mcp-0.6.0/tests/test_redis_utils.py +77 -0
  57. futuresearch_mcp-0.6.0/tests/test_result_store.py +1112 -0
  58. futuresearch_mcp-0.6.0/tests/test_routes.py +498 -0
  59. futuresearch_mcp-0.6.0/tests/test_security_hardening.py +100 -0
  60. futuresearch_mcp-0.6.0/tests/test_server.py +2152 -0
  61. futuresearch_mcp-0.6.0/tests/test_state_redis.py +126 -0
  62. futuresearch_mcp-0.6.0/tests/test_stdio_content.py +829 -0
  63. futuresearch_mcp-0.6.0/tests/test_tool_helpers.py +162 -0
  64. futuresearch_mcp-0.6.0/tests/test_ua_detection.py +72 -0
  65. futuresearch_mcp-0.6.0/tests/test_uploads.py +404 -0
  66. futuresearch_mcp-0.6.0/tests/test_utils.py +504 -0
@@ -0,0 +1,232 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ # Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ # poetry.lock
109
+ # poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ # pdm.lock
116
+ # pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ # pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # Redis
135
+ *.rdb
136
+ *.aof
137
+ *.pid
138
+
139
+ # RabbitMQ
140
+ mnesia/
141
+ rabbitmq/
142
+ rabbitmq-data/
143
+
144
+ # ActiveMQ
145
+ activemq-data/
146
+
147
+ # SageMath parsed files
148
+ *.sage.py
149
+
150
+ # Environments
151
+ .env
152
+ .envrc
153
+ .venv
154
+ env/
155
+ venv/
156
+ ENV/
157
+ env.bak/
158
+ venv.bak/
159
+
160
+ # Spyder project settings
161
+ .spyderproject
162
+ .spyproject
163
+
164
+ # Rope project settings
165
+ .ropeproject
166
+
167
+ # mkdocs documentation
168
+ /site
169
+
170
+ # mypy
171
+ .mypy_cache/
172
+ .dmypy.json
173
+ dmypy.json
174
+
175
+ # Pyre type checker
176
+ .pyre/
177
+
178
+ # pytype static type analyzer
179
+ .pytype/
180
+
181
+ # Cython debug symbols
182
+ cython_debug/
183
+
184
+ # PyCharm
185
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
186
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
187
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
188
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
189
+ .idea/
190
+
191
+ # Abstra
192
+ # Abstra is an AI-powered process automation framework.
193
+ # Ignore directories containing user credentials, local state, and settings.
194
+ # Learn more at https://abstra.io/docs
195
+ .abstra/
196
+
197
+ # Visual Studio Code
198
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
199
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
200
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
201
+ # you could uncomment the following to ignore the entire vscode folder
202
+ .vscode/
203
+
204
+ # MacOS
205
+ .DS_Store
206
+
207
+ # Ruff stuff:
208
+ .ruff_cache/
209
+
210
+ # PyPI configuration file
211
+ .pypirc
212
+
213
+ # Marimo
214
+ marimo/_static/
215
+ marimo/_lsp/
216
+ __marimo__/
217
+
218
+ # Streamlit
219
+ .streamlit/secrets.toml
220
+
221
+ .history/
222
+ .python-version
223
+
224
+ # MCPB bundles
225
+ *.mcpb
226
+
227
+ # MCP registry tokens
228
+ .mcpregistry_*
229
+
230
+ # Claude Code local instructions
231
+ CLAUDE.local.md
232
+ worktrees/
@@ -0,0 +1,13 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ *.egg-info/
7
+ server/lib/
8
+ server/venv/
9
+ .mcpregistry_github_token
10
+ .mcpregistry_registry_token
11
+ tests/
12
+ dist/
13
+ .ruff_cache/
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: futuresearch-mcp
3
+ Version: 0.6.0
4
+ Summary: MCP server for futuresearch: a researcher for every row
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: futuresearch>=0.6.0
7
+ Requires-Dist: httpx>=0.27.0
8
+ Requires-Dist: jsonschema>=4.0.0
9
+ Requires-Dist: litellm>=1.50.0
10
+ Requires-Dist: mcp[cli]>=1.0.0
11
+ Requires-Dist: pandas>=2.0.0
12
+ Requires-Dist: pydantic-settings>=2.0.0
13
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
14
+ Requires-Dist: pyjwt[crypto]>=2.8.0
15
+ Requires-Dist: redis[hiredis]>=5.0.0
16
+ Requires-Dist: sentry-sdk[starlette]>=2.0.0
17
+ Requires-Dist: tabulate>=0.9.0
18
+ Description-Content-Type: text/markdown
19
+
20
+ # FutureSearch MCP Server
21
+
22
+ > Most users don't need to run the MCP server locally. Use the hosted remote server at `https://mcp.futuresearch.ai/mcp` — it authenticates via OAuth, no API key needed. See the [setup guide](https://futuresearch.ai/docs). The instructions below are for self-hosted or advanced use cases where an API key is required.
23
+
24
+ MCP (Model Context Protocol) server for [FutureSearch](https://futuresearch.ai): agent ops at spreadsheet scale.
25
+
26
+ This server exposes FutureSearch's core operations as MCP tools, allowing LLM applications to classify, rank, dedupe, merge, forecast, and run agents on CSV files.
27
+
28
+ **All tools operate on local CSV files.** Provide absolute file paths as input, and transformed results are written to new CSV files at your specified output path.
29
+
30
+ ## Installation
31
+
32
+ The server requires a FutureSearch API key. Get one at [futuresearch.ai/api-key](https://futuresearch.ai/api-key) ($20 free credit).
33
+
34
+ ### Claude Desktop
35
+
36
+ Download the latest `.mcpb` bundle from the [GitHub Releases](https://github.com/futuresearch/futuresearch-python/releases) page and double-click to install in Claude Desktop. You'll be prompted to enter your FutureSearch API key during setup. After installing the bundle, you can use FutureSearch from Chat, Cowork and Code within Claude Desktop.
37
+
38
+ ### Cursor
39
+ Set the environment variable in your terminal shell before opening cursor. You may need to re-open cursor from your shell after this. Alternatively, hardcode the api key within cursor settings instead of the hard-coded `${env:FUTURESEARCH_API_KEY}`
40
+ ```bash
41
+ export FUTURESEARCH_API_KEY=your_key_here
42
+ ```
43
+
44
+ ### Manual Config
45
+
46
+ Either set the API key in your shell environment as mentioned above, or hardcode it directly in the config below. Environment variable interpolation may differ between MCP clients.
47
+
48
+ ```bash
49
+ export FUTURESEARCH_API_KEY=your_key_here
50
+ ```
51
+
52
+ Add this to your MCP config. If you have [uv](https://docs.astral.sh/uv/) installed:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "futuresearch": {
58
+ "command": "uvx",
59
+ "args": ["futuresearch-mcp"],
60
+ "env": {
61
+ "FUTURESEARCH_API_KEY": "${FUTURESEARCH_API_KEY}"
62
+ }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ Alternatively, install with pip (ideally in a venv) and use `"command": "futuresearch-mcp"` instead of uvx.
69
+
70
+ ## Workflow
71
+
72
+ All operations follow an async pattern:
73
+
74
+ 1. **Start** - Call an operation tool (e.g., `futuresearch_agent`) to start a task. Returns immediately with a task ID and session URL.
75
+ 2. **Monitor** - Call `futuresearch_progress(task_id)` repeatedly to check status. The tool blocks ~12s to limit the polling rate.
76
+ 3. **Retrieve** - Once complete, call `futuresearch_results(task_id, output_path)` to save results to CSV.
77
+
78
+ ## Available Tools
79
+
80
+ ### futuresearch_rank
81
+
82
+ Score and sort CSV rows based on qualitative criteria.
83
+
84
+ ```
85
+ Parameters:
86
+ - task: Natural language instructions for scoring a single row
87
+ - input_csv: Absolute path to input CSV
88
+ - field_name: Name of the score field to add
89
+ - field_type: Type of the score field (float, int, str, bool)
90
+ - ascending_order: Sort direction (default: true)
91
+ - response_schema: (optional) JSON schema for custom response fields
92
+ ```
93
+
94
+ Example: Rank leads by "likelihood to need data integration solutions"
95
+
96
+ ### futuresearch_dedupe
97
+
98
+ Remove duplicate rows using semantic equivalence.
99
+
100
+ ```
101
+ Parameters:
102
+ - equivalence_relation: Natural language description of what makes rows duplicates
103
+ - input_csv: Absolute path to input CSV
104
+ ```
105
+
106
+ Example: Dedupe contacts where "same person even with name abbreviations or career changes"
107
+
108
+ ### futuresearch_merge
109
+
110
+ Join two CSV files using intelligent entity matching (LEFT JOIN semantics).
111
+
112
+ ```
113
+ Parameters:
114
+ - task: Natural language description of how to match rows
115
+ - left_csv: The table being enriched — all its rows are kept in the output
116
+ - right_csv: The lookup/reference table — its columns are appended to matches; unmatched left rows get nulls
117
+ - merge_on_left: (optional) Only set if you expect exact string matches on this column or want to draw agent attention to it. Fine to omit.
118
+ - merge_on_right: (optional) Only set if you expect exact string matches on this column or want to draw agent attention to it. Fine to omit.
119
+ - use_web_search: (optional) "auto" (default), "yes", or "no"
120
+ - relationship_type: (optional) "many_to_one" (default) if multiple left rows can match one right row, "one_to_one" matches must be unique, "one_to_many" one left row can match multiple right rows, "many_to_many" multiple left rows can match multiple right rows. For one_to_many and many_to_many, multiple matches are joined with " | " in each added column.
121
+ ```
122
+
123
+ Example: Match software products (left, enriched) to parent companies (right, lookup): Photoshop -> Adobe
124
+
125
+ ### futuresearch_classify
126
+
127
+ Classify each row into one of the provided categories.
128
+
129
+ ```
130
+ Parameters:
131
+ - task: Natural language classification instructions
132
+ - categories: Allowed categories (minimum 2)
133
+ - classification_field: (optional) Output column name (default: "classification")
134
+ - include_reasoning: (optional) Include reasoning column (default: false)
135
+ ```
136
+
137
+ Example: Classify companies by GICS sector with categories ["Energy", "Financials", "Information Technology", ...]
138
+
139
+ ### futuresearch_forecast
140
+
141
+ Forecast the probability of binary questions.
142
+
143
+ ```
144
+ Parameters:
145
+ - context: (optional) Batch-level context for all questions
146
+ ```
147
+
148
+ Example: "Will the US Federal Reserve cut rates before July 2027?"
149
+
150
+ ### futuresearch_agent
151
+
152
+ Run web research agents on each row of a CSV.
153
+
154
+ ```
155
+ Parameters:
156
+ - task: Natural language description of research task
157
+ - input_csv: Absolute path to input CSV
158
+ - response_schema: (optional) JSON schema for custom response fields
159
+ ```
160
+
161
+ Example: "Find this company's latest funding round and lead investors"
162
+
163
+ ### futuresearch_progress
164
+
165
+ Check progress of a running task.
166
+
167
+ ```
168
+ Parameters:
169
+ - task_id: The task ID returned by an operation tool
170
+ ```
171
+
172
+ Blocks ~12s before returning status. Call repeatedly until task completes.
173
+
174
+ ### futuresearch_results
175
+
176
+ Retrieve and save results from a completed task.
177
+
178
+ ```
179
+ Parameters:
180
+ - task_id: The task ID of the completed task
181
+ - output_path: Full absolute path to output CSV file (must end in .csv)
182
+ ```
183
+
184
+ Only call after `futuresearch_progress` reports status "completed".
185
+
186
+ ## Development
187
+
188
+ ```bash
189
+ cd futuresearch-mcp
190
+ uv sync
191
+ uv run pytest
192
+ ```
193
+ For MCP [registry publishing](https://modelcontextprotocol.info/tools/registry/publishing/#package-deployment):
194
+
195
+ mcp-name: io.github.futuresearch/futuresearch-mcp
196
+
197
+
198
+ ## License
199
+
200
+ MIT - See [LICENSE.txt](../LICENSE.txt)
@@ -0,0 +1,181 @@
1
+ # FutureSearch MCP Server
2
+
3
+ > Most users don't need to run the MCP server locally. Use the hosted remote server at `https://mcp.futuresearch.ai/mcp` — it authenticates via OAuth, no API key needed. See the [setup guide](https://futuresearch.ai/docs). The instructions below are for self-hosted or advanced use cases where an API key is required.
4
+
5
+ MCP (Model Context Protocol) server for [FutureSearch](https://futuresearch.ai): agent ops at spreadsheet scale.
6
+
7
+ This server exposes FutureSearch's core operations as MCP tools, allowing LLM applications to classify, rank, dedupe, merge, forecast, and run agents on CSV files.
8
+
9
+ **All tools operate on local CSV files.** Provide absolute file paths as input, and transformed results are written to new CSV files at your specified output path.
10
+
11
+ ## Installation
12
+
13
+ The server requires a FutureSearch API key. Get one at [futuresearch.ai/api-key](https://futuresearch.ai/api-key) ($20 free credit).
14
+
15
+ ### Claude Desktop
16
+
17
+ Download the latest `.mcpb` bundle from the [GitHub Releases](https://github.com/futuresearch/futuresearch-python/releases) page and double-click to install in Claude Desktop. You'll be prompted to enter your FutureSearch API key during setup. After installing the bundle, you can use FutureSearch from Chat, Cowork and Code within Claude Desktop.
18
+
19
+ ### Cursor
20
+ Set the environment variable in your terminal shell before opening cursor. You may need to re-open cursor from your shell after this. Alternatively, hardcode the api key within cursor settings instead of the hard-coded `${env:FUTURESEARCH_API_KEY}`
21
+ ```bash
22
+ export FUTURESEARCH_API_KEY=your_key_here
23
+ ```
24
+
25
+ ### Manual Config
26
+
27
+ Either set the API key in your shell environment as mentioned above, or hardcode it directly in the config below. Environment variable interpolation may differ between MCP clients.
28
+
29
+ ```bash
30
+ export FUTURESEARCH_API_KEY=your_key_here
31
+ ```
32
+
33
+ Add this to your MCP config. If you have [uv](https://docs.astral.sh/uv/) installed:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "futuresearch": {
39
+ "command": "uvx",
40
+ "args": ["futuresearch-mcp"],
41
+ "env": {
42
+ "FUTURESEARCH_API_KEY": "${FUTURESEARCH_API_KEY}"
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ Alternatively, install with pip (ideally in a venv) and use `"command": "futuresearch-mcp"` instead of uvx.
50
+
51
+ ## Workflow
52
+
53
+ All operations follow an async pattern:
54
+
55
+ 1. **Start** - Call an operation tool (e.g., `futuresearch_agent`) to start a task. Returns immediately with a task ID and session URL.
56
+ 2. **Monitor** - Call `futuresearch_progress(task_id)` repeatedly to check status. The tool blocks ~12s to limit the polling rate.
57
+ 3. **Retrieve** - Once complete, call `futuresearch_results(task_id, output_path)` to save results to CSV.
58
+
59
+ ## Available Tools
60
+
61
+ ### futuresearch_rank
62
+
63
+ Score and sort CSV rows based on qualitative criteria.
64
+
65
+ ```
66
+ Parameters:
67
+ - task: Natural language instructions for scoring a single row
68
+ - input_csv: Absolute path to input CSV
69
+ - field_name: Name of the score field to add
70
+ - field_type: Type of the score field (float, int, str, bool)
71
+ - ascending_order: Sort direction (default: true)
72
+ - response_schema: (optional) JSON schema for custom response fields
73
+ ```
74
+
75
+ Example: Rank leads by "likelihood to need data integration solutions"
76
+
77
+ ### futuresearch_dedupe
78
+
79
+ Remove duplicate rows using semantic equivalence.
80
+
81
+ ```
82
+ Parameters:
83
+ - equivalence_relation: Natural language description of what makes rows duplicates
84
+ - input_csv: Absolute path to input CSV
85
+ ```
86
+
87
+ Example: Dedupe contacts where "same person even with name abbreviations or career changes"
88
+
89
+ ### futuresearch_merge
90
+
91
+ Join two CSV files using intelligent entity matching (LEFT JOIN semantics).
92
+
93
+ ```
94
+ Parameters:
95
+ - task: Natural language description of how to match rows
96
+ - left_csv: The table being enriched — all its rows are kept in the output
97
+ - right_csv: The lookup/reference table — its columns are appended to matches; unmatched left rows get nulls
98
+ - merge_on_left: (optional) Only set if you expect exact string matches on this column or want to draw agent attention to it. Fine to omit.
99
+ - merge_on_right: (optional) Only set if you expect exact string matches on this column or want to draw agent attention to it. Fine to omit.
100
+ - use_web_search: (optional) "auto" (default), "yes", or "no"
101
+ - relationship_type: (optional) "many_to_one" (default) if multiple left rows can match one right row, "one_to_one" matches must be unique, "one_to_many" one left row can match multiple right rows, "many_to_many" multiple left rows can match multiple right rows. For one_to_many and many_to_many, multiple matches are joined with " | " in each added column.
102
+ ```
103
+
104
+ Example: Match software products (left, enriched) to parent companies (right, lookup): Photoshop -> Adobe
105
+
106
+ ### futuresearch_classify
107
+
108
+ Classify each row into one of the provided categories.
109
+
110
+ ```
111
+ Parameters:
112
+ - task: Natural language classification instructions
113
+ - categories: Allowed categories (minimum 2)
114
+ - classification_field: (optional) Output column name (default: "classification")
115
+ - include_reasoning: (optional) Include reasoning column (default: false)
116
+ ```
117
+
118
+ Example: Classify companies by GICS sector with categories ["Energy", "Financials", "Information Technology", ...]
119
+
120
+ ### futuresearch_forecast
121
+
122
+ Forecast the probability of binary questions.
123
+
124
+ ```
125
+ Parameters:
126
+ - context: (optional) Batch-level context for all questions
127
+ ```
128
+
129
+ Example: "Will the US Federal Reserve cut rates before July 2027?"
130
+
131
+ ### futuresearch_agent
132
+
133
+ Run web research agents on each row of a CSV.
134
+
135
+ ```
136
+ Parameters:
137
+ - task: Natural language description of research task
138
+ - input_csv: Absolute path to input CSV
139
+ - response_schema: (optional) JSON schema for custom response fields
140
+ ```
141
+
142
+ Example: "Find this company's latest funding round and lead investors"
143
+
144
+ ### futuresearch_progress
145
+
146
+ Check progress of a running task.
147
+
148
+ ```
149
+ Parameters:
150
+ - task_id: The task ID returned by an operation tool
151
+ ```
152
+
153
+ Blocks ~12s before returning status. Call repeatedly until task completes.
154
+
155
+ ### futuresearch_results
156
+
157
+ Retrieve and save results from a completed task.
158
+
159
+ ```
160
+ Parameters:
161
+ - task_id: The task ID of the completed task
162
+ - output_path: Full absolute path to output CSV file (must end in .csv)
163
+ ```
164
+
165
+ Only call after `futuresearch_progress` reports status "completed".
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ cd futuresearch-mcp
171
+ uv sync
172
+ uv run pytest
173
+ ```
174
+ For MCP [registry publishing](https://modelcontextprotocol.info/tools/registry/publishing/#package-deployment):
175
+
176
+ mcp-name: io.github.futuresearch/futuresearch-mcp
177
+
178
+
179
+ ## License
180
+
181
+ MIT - See [LICENSE.txt](../LICENSE.txt)
@@ -0,0 +1,15 @@
1
+ .git
2
+ .github
3
+ .venv
4
+ __pycache__
5
+ *.pyc
6
+ .env
7
+ *.env
8
+ !.env.example
9
+ .claude/
10
+ .vscode/
11
+ *.egg-info
12
+ dist/
13
+ build/
14
+ node_modules/
15
+ docs-site/
@@ -0,0 +1,8 @@
1
+ FUTURESEARCH_API_KEY=sk-cho-your-api-key-here
2
+ SUPABASE_URL=https://your-project.supabase.co
3
+ SUPABASE_ANON_KEY=sb_publishable_your-anon-key-here
4
+ MCP_SERVER_URL=https://your-tunnel-url.example.com
5
+ REDIS_PASSWORD=change-me-to-a-strong-random-password
6
+
7
+ # Legacy env vars (still supported for backwards compatibility):
8
+ # EVERYROW_API_KEY=sk-cho-your-api-key-here
@@ -0,0 +1,36 @@
1
+ # Stage 1: Build Python environment with uv
2
+ FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS build
3
+ ENV PYTHONDONTWRITEBYTECODE=1
4
+ ENV PYTHONUNBUFFERED=1
5
+ WORKDIR /app
6
+
7
+ # Copy workspace root pyproject + lock + README, then each package
8
+ COPY --link pyproject.toml uv.lock README.md ./
9
+ COPY --link src/ ./src/
10
+ COPY --link everyrow-mcp/pyproject.toml everyrow-mcp/README.md ./everyrow-mcp/
11
+ COPY --link everyrow-mcp/src/ ./everyrow-mcp/src/
12
+
13
+ # Install everyrow-mcp and its dependencies (includes workspace everyrow package)
14
+ RUN uv sync --package everyrow-mcp --no-dev --no-sources --no-editable
15
+
16
+ # Stage 2: Slim runtime
17
+ FROM python:3.13-slim
18
+
19
+ ENV PYTHONDONTWRITEBYTECODE=1
20
+ ENV PYTHONUNBUFFERED=1
21
+
22
+ RUN groupadd -r -g 10000 mcp && useradd -r -u 10000 -g mcp -d /app -s /sbin/nologin mcp
23
+
24
+ ENV PATH="/app/.venv/bin:$PATH"
25
+ EXPOSE 8000
26
+
27
+ WORKDIR /app
28
+ COPY --link --from=build /app/.venv .venv
29
+ RUN chown -R mcp:mcp /app
30
+
31
+ USER mcp
32
+
33
+ HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
34
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
35
+
36
+ CMD ["everyrow-mcp", "--http", "--port", "8000", "--host", "0.0.0.0"]
@@ -0,0 +1,4 @@
1
+ /secrets.yaml
2
+ /values.secrets.yaml
3
+ /values.secrets.staging.yaml
4
+ /secrets.staging.yaml
@@ -0,0 +1,2 @@
1
+ creation_rules:
2
+ - gcp_kms: projects/varuna-400921/locations/global/keyRings/sops/cryptoKeys/sops-key