mcp-server-worldquantbrain 0.1.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 (52) hide show
  1. mcp_server_worldquantbrain-0.1.0/LICENSE +21 -0
  2. mcp_server_worldquantbrain-0.1.0/PKG-INFO +285 -0
  3. mcp_server_worldquantbrain-0.1.0/README.md +250 -0
  4. mcp_server_worldquantbrain-0.1.0/pyproject.toml +96 -0
  5. mcp_server_worldquantbrain-0.1.0/pyproject.toml.orig +76 -0
  6. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/__init__.py +11 -0
  7. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/__main__.py +3 -0
  8. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/cli.py +127 -0
  9. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/__init__.py +3 -0
  10. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/alphas.py +259 -0
  11. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/base.py +607 -0
  12. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/cache.py +48 -0
  13. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/data.py +103 -0
  14. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/filters.py +60 -0
  15. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/ledger.py +132 -0
  16. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/paging.py +22 -0
  17. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/retry.py +37 -0
  18. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/session.py +107 -0
  19. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/simulations.py +103 -0
  20. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/client/users.py +77 -0
  21. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/config.py +185 -0
  22. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/errors.py +79 -0
  23. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/http_app.py +50 -0
  24. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/integrations/__init__.py +0 -0
  25. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/integrations/langgraph.py +137 -0
  26. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/knowledge/__init__.py +20 -0
  27. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/knowledge/fastexpr-cheatsheet.md +36 -0
  28. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/knowledge/settings-guide.md +20 -0
  29. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/knowledge/submission-criteria.md +24 -0
  30. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/logging_setup.py +18 -0
  31. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/__init__.py +0 -0
  32. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/alpha.py +190 -0
  33. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/auth.py +12 -0
  34. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/base.py +23 -0
  35. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/data.py +132 -0
  36. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/simulation.py +117 -0
  37. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/models/user.py +38 -0
  38. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/__init__.py +9 -0
  39. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/alphas.py +200 -0
  40. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/auth.py +34 -0
  41. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/data.py +132 -0
  42. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/registry.py +151 -0
  43. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/simulations.py +147 -0
  44. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/submit.py +156 -0
  45. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/ops/users.py +38 -0
  46. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/prompts.py +38 -0
  47. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/py.typed +0 -0
  48. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/redaction.py +70 -0
  49. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/resources.py +51 -0
  50. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/server.py +52 -0
  51. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/sim_manager.py +467 -0
  52. mcp_server_worldquantbrain-0.1.0/src/mcp_server_worldquantbrain/tools.py +121 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcell Tukora
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,285 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-server-worldquantbrain
3
+ Version: 0.1.0
4
+ Summary: MCP server and LangGraph tools for the WorldQuant BRAIN platform: simulate alphas, inspect results, browse data fields and operators.
5
+ Keywords: worldquant,brain,mcp,langgraph,quant,alpha
6
+ Author: Marcell Tukora
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Financial and Insurance Industry
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Office/Business :: Financial :: Investment
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: httpx2>=2.10
20
+ Requires-Dist: mcp>=2.3,<3
21
+ Requires-Dist: pydantic>=2.12
22
+ Requires-Dist: pydantic-settings>=2.10
23
+ Requires-Dist: starlette>=0.48
24
+ Requires-Dist: uvicorn>=0.31.1
25
+ Requires-Dist: langchain>=1.4.6 ; extra == 'langgraph'
26
+ Requires-Dist: langchain-core>=1.0 ; extra == 'langgraph'
27
+ Requires-Dist: langgraph>=1.2 ; extra == 'langgraph'
28
+ Requires-Python: >=3.11
29
+ Project-URL: Homepage, https://github.com/tukorama/mcp-server-worldquantbrain
30
+ Project-URL: Repository, https://github.com/tukorama/mcp-server-worldquantbrain
31
+ Project-URL: Issues, https://github.com/tukorama/mcp-server-worldquantbrain/issues
32
+ Project-URL: Changelog, https://github.com/tukorama/mcp-server-worldquantbrain/blob/main/CHANGELOG.md
33
+ Provides-Extra: langgraph
34
+ Description-Content-Type: text/markdown
35
+
36
+ <!-- mcp-name: io.github.tukorama/mcp-server-worldquantbrain -->
37
+
38
+ # mcp-server-worldquantbrain
39
+
40
+ [![PyPI](https://img.shields.io/pypi/v/mcp-server-worldquantbrain)](https://pypi.org/project/mcp-server-worldquantbrain/)
41
+ [![CI](https://github.com/tukorama/mcp-server-worldquantbrain/actions/workflows/ci.yml/badge.svg)](https://github.com/tukorama/mcp-server-worldquantbrain/actions/workflows/ci.yml)
42
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
43
+
44
+ An MCP server and LangGraph toolkit for [WorldQuant BRAIN](https://platform.worldquantbrain.com).
45
+ It lets an agent look up data fields, backtest FASTEXPR alphas and read the results. Unofficial, and
46
+ not affiliated with WorldQuant.
47
+
48
+ ## Why this exists
49
+
50
+ Driving BRAIN from an agent goes wrong in a few predictable ways, and each one shaped this package.
51
+
52
+ - **A simulation takes minutes and clients give up sooner.** A wait that runs out returns `PENDING`
53
+ with an id, and `get_simulation_status` picks it up again. Nothing is resubmitted.
54
+ - **Agents repeat themselves, and simulations are metered.** A local ledger remembers every
55
+ expression and settings pair, so a repeat returns the earlier alpha instead of spending quota.
56
+ - **BRAIN responses are huge.** Tools return trimmed, typed results: a PnL series becomes yearly
57
+ figures, lists are paged and capped, and messages lose their embedded images.
58
+ - **Logging in is awkward.** The session is saved to disk, so restarts and short-lived stdio
59
+ processes reuse it. If BRAIN asks for a biometric check you get a URL to open, not a headless
60
+ browser you cannot see.
61
+ - **Submission is permanent.** `submit_alpha` does not exist unless you turn it on, and when it is
62
+ on it runs BRAIN's checks and the self-correlation test first and refuses on any failure.
63
+
64
+ ## Quick start
65
+
66
+ Store your login once. Credentials go to `~/.config/mcp-server-worldquantbrain/credentials.json`, readable
67
+ only by you.
68
+
69
+ ```bash
70
+ uvx mcp-server-worldquantbrain auth
71
+ ```
72
+
73
+ Then add the server to your client.
74
+
75
+ **Claude Code**
76
+
77
+ ```bash
78
+ claude mcp add brain -- uvx mcp-server-worldquantbrain
79
+ ```
80
+
81
+ **Claude Desktop, Cursor, VS Code and others**
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "brain": { "command": "uvx", "args": ["mcp-server-worldquantbrain"] }
87
+ }
88
+ }
89
+ ```
90
+
91
+ Now ask for something like "Find a value signal in the fundamental datasets for USA TOP3000 and
92
+ backtest it."
93
+
94
+ Prefer to pass credentials directly? Add `"env": {"WQB_EMAIL": "...", "WQB_PASSWORD": "..."}`.
95
+
96
+ ## LangGraph
97
+
98
+ The `langgraph` extra gives you plain LangChain tools in the same process, with no MCP server to
99
+ run. It also has a prebuilt agent.
100
+
101
+ ```bash
102
+ uv add "mcp-server-worldquantbrain[langgraph]"
103
+ ```
104
+
105
+ ```python
106
+ from mcp_server_worldquantbrain.integrations.langgraph import create_brain_agent, get_brain_tools
107
+
108
+ agent = create_brain_agent("anthropic:claude-sonnet-5")
109
+ result = await agent.ainvoke({"messages": [("user", "Backtest rank(-returns) and summarize it")]})
110
+
111
+ # Or take the tools and build your own graph:
112
+ tools = get_brain_tools()
113
+ ```
114
+
115
+ The tools work from sync and async graphs. With `WQB_ALLOW_SUBMIT=true` the agent stops for human
116
+ approval before `submit_alpha`. Invoke it with a `thread_id` in the config, and resume with
117
+ `Command(resume=...)`. `get_brain_tools()` leaves `submit_alpha` out, because a custom graph has no
118
+ approval step; pass `include_submit=True` once yours does.
119
+
120
+ To keep BRAIN in a separate process, connect over MCP instead. This route needs `langchain[mcp]`,
121
+ which LangChain still marks as beta.
122
+
123
+ ```python
124
+ from langchain.agents import create_agent
125
+ from langchain.mcp import MCPAdapter
126
+
127
+ config = {
128
+ "mcpServers": {
129
+ "brain": {
130
+ "command": "uvx",
131
+ "args": ["mcp-server-worldquantbrain"],
132
+ "timeout": 1_200_000, # milliseconds; simulations block
133
+ }
134
+ }
135
+ }
136
+
137
+ async with MCPAdapter(config) as adapter:
138
+ agent = create_agent("anthropic:claude-sonnet-5", await adapter.list_tools())
139
+ ```
140
+
141
+ The subprocess inherits only `HOME`, `PATH` and a few others, so anything else, including `WQB_*`
142
+ variables, has to go in `env`. Over this route a submission confirmation arrives as a LangGraph
143
+ interrupt, so give the agent a checkpointer if you enable submission. A deployable example is in
144
+ [examples/langgraph_app](examples/langgraph_app).
145
+
146
+ ## Tools
147
+
148
+ | Group | Tool | Notes |
149
+ |---|---|---|
150
+ | Login | `authenticate`, `complete_authentication`, `auth_status` | Other tools log in by themselves |
151
+ | Simulate | `simulate_alpha` | Blocks up to 15 minutes by default; `wait=False` returns at once |
152
+ | | `simulate_alphas_batch` | Up to 30 expressions, in groups of 10; needs multi-simulation access |
153
+ | | `get_simulation_status` | Check or resume a simulation |
154
+ | | `get_simulation_options` | Regions, universes and delays your account can use |
155
+ | Alphas | `get_alpha`, `list_alphas` | Filter by Sharpe, fitness, turnover, date, tag and more |
156
+ | | `get_alpha_pnl`, `list_alpha_recordsets`, `get_alpha_recordset` | PnL by year; other recordsets as rows |
157
+ | | `update_alpha` | Name, description, tags, color, category |
158
+ | | `check_alpha_submission` | BRAIN's pre-submission checks |
159
+ | | `get_alpha_self_correlation`, `get_alpha_prod_correlation` | Production correlation depends on account tier |
160
+ | | `submit_alpha` | Off unless `WQB_ALLOW_SUBMIT=true` |
161
+ | Data | `list_datasets`, `get_dataset`, `list_datafields`, `get_datafield` | |
162
+ | | `list_data_categories`, `list_operators` | |
163
+ | Account | `get_user_profile`, `get_user_activity`, `list_messages` | Personal fields are withheld by default |
164
+
165
+ Resources: `brain://operators`, `brain://simulation-options`, `brain://alphas/{alpha_id}`, and
166
+ reference pages under `brain://docs/` (`fastexpr-cheatsheet`, `settings-guide`,
167
+ `submission-criteria`).
168
+
169
+ Prompts: `design_alpha` runs a short research loop. `review_alpha` assesses an existing alpha.
170
+
171
+ ## Configuration
172
+
173
+ All settings are environment variables. A `.env` file in the working directory also works, except
174
+ for settings that decide where credentials go or that enable submission (`WQB_BASE_URL`, the file
175
+ and directory paths, the `WQB_SUBMIT_*` and `WQB_ALLOW_SUBMIT` settings, and the bearer token).
176
+ These have to be set in the real environment.
177
+
178
+ | Variable | Default | Purpose |
179
+ |---|---|---|
180
+ | `WQB_EMAIL`, `WQB_PASSWORD` | | Login. These win over the credentials file |
181
+ | `WQB_CREDENTIALS_FILE` | `~/.config/mcp-server-worldquantbrain/credentials.json` | JSON: `["email", "password"]` |
182
+ | `WQB_SESSION_FILE` | `~/.config/mcp-server-worldquantbrain/session.json` | Saved session. Delete it to log out |
183
+ | `WQB_CACHE_DIR` | `~/.cache/mcp-server-worldquantbrain` | Catalogue cache and simulation ledger |
184
+ | `WQB_CACHE_TTL` | per catalogue | Seconds; `0` disables the cache |
185
+ | `WQB_LEDGER` | `true` | Reuse results of identical simulations |
186
+ | `WQB_ALLOW_SUBMIT` | `false` | Expose `submit_alpha` |
187
+ | `WQB_SUBMIT_CONFIRM` | `elicit` | Ask the user first where the client supports it; `none` skips asking |
188
+ | `WQB_SUBMIT_CORRELATION_GATE` | `0.7` | Refuse at or above this self-correlation; `0` disables |
189
+ | `WQB_MAX_CONCURRENT_SIMULATIONS` | `2` | Blocking simulation calls this process runs at once |
190
+ | `WQB_SIMULATION_TIMEOUT` | `900` | Seconds a blocking simulation waits |
191
+ | `WQB_HTTP_TIMEOUT` | `30` | Seconds per HTTP request |
192
+ | `WQB_POLL_MAX_INTERVAL` | `30` | Longest pause between status polls |
193
+ | `WQB_HTTP_BEARER_TOKEN` | | Required by the HTTP transport on a non-local address |
194
+ | `WQB_LOG_LEVEL` | `INFO` | Logs go to stderr |
195
+ | `WQB_DEFAULT_REGION`, `WQB_DEFAULT_UNIVERSE`, `_DELAY`, `_DECAY`, `_NEUTRALIZATION`, `_TRUNCATION`, `_PASTEURIZATION`, `_UNIT_HANDLING`, `_NAN_HANDLING`, `_TEST_PERIOD`, `_MAX_TRADE`, `_INSTRUMENT_TYPE` | USA, TOP3000, 1, 0, INDUSTRY, 0.08, ON, VERIFY, OFF, none, OFF, EQUITY | Used when a call leaves a setting out. A call for another region must name its universe |
196
+
197
+ On Windows the two directories are `%APPDATA%\mcp-server-worldquantbrain` and
198
+ `%LOCALAPPDATA%\mcp-server-worldquantbrain`, and files are protected by your user profile rather than POSIX
199
+ permissions.
200
+
201
+ To serve over HTTP:
202
+
203
+ ```bash
204
+ WQB_HTTP_BEARER_TOKEN=change-me mcp-server-worldquantbrain serve --transport streamable-http --host 0.0.0.0
205
+ ```
206
+
207
+ The server refuses a non-local address without a token. `/health` stays open for probes.
208
+
209
+ ## How it behaves
210
+
211
+ **Long calls.** Claude Desktop has been reported to cancel stdio tool calls after about a minute, so
212
+ for that client each call is limited to 45 seconds of waiting and the agent resumes with
213
+ `get_simulation_status`. Claude Code and LangGraph wait as long as you let them. Set
214
+ `WQB_SIMULATION_TIMEOUT` to match whatever your client allows.
215
+
216
+ **Concurrency.** BRAIN limits simultaneous simulations per account and does not publish the number.
217
+ The default of 2 is deliberately cautious. Raise it if your account allows more. The setting only
218
+ counts blocking calls while they wait, and one batch group of up to 10 uses one slot. `wait=False`
219
+ calls, simulations still running after a timeout, and other processes on the same account are not
220
+ counted, and can hit BRAIN's own limit, which comes back as a rate-limit error with a suggested
221
+ wait.
222
+
223
+ **The ledger.** Whitespace in an expression does not matter; every setting does. Pass `force=True`
224
+ to run an identical simulation again. Failed simulations can be run again.
225
+
226
+ **Writes are not retried.** A POST that may have reached BRAIN is never repeated automatically, so a
227
+ network failure cannot spend quota twice or submit twice. Reads retry with backoff and honour
228
+ `Retry-After`.
229
+
230
+ **Biometric login.** `authenticate` returns a URL, the user finishes the check in a browser, and
231
+ `complete_authentication` ends the login. The pending check is saved for 30 minutes, so it survives
232
+ a restart. On a terminal, `mcp-server-worldquantbrain auth` does the same with a prompt.
233
+
234
+ **What is cached.** Operators and simulation options for a week, categories and dataset pages for a
235
+ day. Alphas, simulations, checks, correlations and data fields are always fetched fresh.
236
+
237
+ **What is never logged.** Passwords, cookies, authorization headers and session tokens are masked,
238
+ and email addresses are shortened, in logs and error messages.
239
+
240
+ ## Limitations
241
+
242
+ - BRAIN's API documentation sits behind a login, and BRAIN can change the API without notice. Run
243
+ `WQB_LIVE=1 uv run pytest -m live` to check it against your account.
244
+ - Login, saved sessions, data catalogues, single simulations, alpha search, PnL, recordsets,
245
+ submission checks and self-correlation have been run against a live account. Biometric
246
+ completion, multi-simulation, `update_alpha`, `submit_alpha` and production correlation results
247
+ have only been tested against responses documented by other BRAIN clients, so treat them as less
248
+ proven. If a biometric completion fails, log in once on the BRAIN website and call `authenticate`
249
+ with `force=true`.
250
+ - The self-correlation gate fails closed: if BRAIN will not report the figure, `submit_alpha`
251
+ refuses. Set `WQB_SUBMIT_CORRELATION_GATE=0` on accounts where that endpoint is unavailable.
252
+ - Simulations are REGULAR FASTEXPR alphas. SUPER and region-agnostic alphas, Python alphas, forum
253
+ access, payments, competitions and pyramids are not covered.
254
+ - There is no cancel tool, because no cancel endpoint is known.
255
+ - `credentials.json` is plaintext protected by file permissions. Use `WQB_EMAIL` and `WQB_PASSWORD`
256
+ from your own secret store if that is not enough.
257
+ - Check that your use of automation complies with the BRAIN terms that apply to you.
258
+
259
+ ## Alternatives
260
+
261
+ - [cnhkmcp](https://pypi.org/project/cnhkmcp/) is on PyPI and covers far more of the platform,
262
+ including the forum. It is a large install that bundles Selenium.
263
+ - [lavender1203/world-quant-brain-mcp](https://github.com/lavender1203/world-quant-brain-mcp) has the
264
+ deepest local analytics, such as correlation pools and an alpha history database. It runs with
265
+ Docker and Redis over HTTP, and has no license.
266
+ - [QuantGPT](https://github.com/Miasyster/QuantGPT) is a full research agent with its own knowledge
267
+ base, for when you want the loop rather than the tools.
268
+ - [worldquant-harness](https://github.com/gyx09212214-prog/worldquant-harness) adds local backtests
269
+ and a strict human submission boundary.
270
+ - [brainapi-go-sdk](https://github.com/wh0amibjm/brainapi-go-sdk) is a Go SDK and CLI with static
271
+ binaries and tests built on captured API responses.
272
+ - [rocky-d/wqb](https://github.com/rocky-d/wqb) is a plain Python client, if you do not need an
273
+ agent interface.
274
+
275
+ No code in this repository was copied from those projects.
276
+
277
+ ## Development
278
+
279
+ To point a client at a checkout, use `uvx --from /path/to/mcp-server-worldquantbrain mcp-server-worldquantbrain`,
280
+ or `uv add --editable ../mcp-server-worldquantbrain` from your LangGraph project. See
281
+ [CONTRIBUTING.md](CONTRIBUTING.md) and [RELEASING.md](RELEASING.md).
282
+
283
+ ## License
284
+
285
+ [MIT](LICENSE)
@@ -0,0 +1,250 @@
1
+ <!-- mcp-name: io.github.tukorama/mcp-server-worldquantbrain -->
2
+
3
+ # mcp-server-worldquantbrain
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/mcp-server-worldquantbrain)](https://pypi.org/project/mcp-server-worldquantbrain/)
6
+ [![CI](https://github.com/tukorama/mcp-server-worldquantbrain/actions/workflows/ci.yml/badge.svg)](https://github.com/tukorama/mcp-server-worldquantbrain/actions/workflows/ci.yml)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
8
+
9
+ An MCP server and LangGraph toolkit for [WorldQuant BRAIN](https://platform.worldquantbrain.com).
10
+ It lets an agent look up data fields, backtest FASTEXPR alphas and read the results. Unofficial, and
11
+ not affiliated with WorldQuant.
12
+
13
+ ## Why this exists
14
+
15
+ Driving BRAIN from an agent goes wrong in a few predictable ways, and each one shaped this package.
16
+
17
+ - **A simulation takes minutes and clients give up sooner.** A wait that runs out returns `PENDING`
18
+ with an id, and `get_simulation_status` picks it up again. Nothing is resubmitted.
19
+ - **Agents repeat themselves, and simulations are metered.** A local ledger remembers every
20
+ expression and settings pair, so a repeat returns the earlier alpha instead of spending quota.
21
+ - **BRAIN responses are huge.** Tools return trimmed, typed results: a PnL series becomes yearly
22
+ figures, lists are paged and capped, and messages lose their embedded images.
23
+ - **Logging in is awkward.** The session is saved to disk, so restarts and short-lived stdio
24
+ processes reuse it. If BRAIN asks for a biometric check you get a URL to open, not a headless
25
+ browser you cannot see.
26
+ - **Submission is permanent.** `submit_alpha` does not exist unless you turn it on, and when it is
27
+ on it runs BRAIN's checks and the self-correlation test first and refuses on any failure.
28
+
29
+ ## Quick start
30
+
31
+ Store your login once. Credentials go to `~/.config/mcp-server-worldquantbrain/credentials.json`, readable
32
+ only by you.
33
+
34
+ ```bash
35
+ uvx mcp-server-worldquantbrain auth
36
+ ```
37
+
38
+ Then add the server to your client.
39
+
40
+ **Claude Code**
41
+
42
+ ```bash
43
+ claude mcp add brain -- uvx mcp-server-worldquantbrain
44
+ ```
45
+
46
+ **Claude Desktop, Cursor, VS Code and others**
47
+
48
+ ```json
49
+ {
50
+ "mcpServers": {
51
+ "brain": { "command": "uvx", "args": ["mcp-server-worldquantbrain"] }
52
+ }
53
+ }
54
+ ```
55
+
56
+ Now ask for something like "Find a value signal in the fundamental datasets for USA TOP3000 and
57
+ backtest it."
58
+
59
+ Prefer to pass credentials directly? Add `"env": {"WQB_EMAIL": "...", "WQB_PASSWORD": "..."}`.
60
+
61
+ ## LangGraph
62
+
63
+ The `langgraph` extra gives you plain LangChain tools in the same process, with no MCP server to
64
+ run. It also has a prebuilt agent.
65
+
66
+ ```bash
67
+ uv add "mcp-server-worldquantbrain[langgraph]"
68
+ ```
69
+
70
+ ```python
71
+ from mcp_server_worldquantbrain.integrations.langgraph import create_brain_agent, get_brain_tools
72
+
73
+ agent = create_brain_agent("anthropic:claude-sonnet-5")
74
+ result = await agent.ainvoke({"messages": [("user", "Backtest rank(-returns) and summarize it")]})
75
+
76
+ # Or take the tools and build your own graph:
77
+ tools = get_brain_tools()
78
+ ```
79
+
80
+ The tools work from sync and async graphs. With `WQB_ALLOW_SUBMIT=true` the agent stops for human
81
+ approval before `submit_alpha`. Invoke it with a `thread_id` in the config, and resume with
82
+ `Command(resume=...)`. `get_brain_tools()` leaves `submit_alpha` out, because a custom graph has no
83
+ approval step; pass `include_submit=True` once yours does.
84
+
85
+ To keep BRAIN in a separate process, connect over MCP instead. This route needs `langchain[mcp]`,
86
+ which LangChain still marks as beta.
87
+
88
+ ```python
89
+ from langchain.agents import create_agent
90
+ from langchain.mcp import MCPAdapter
91
+
92
+ config = {
93
+ "mcpServers": {
94
+ "brain": {
95
+ "command": "uvx",
96
+ "args": ["mcp-server-worldquantbrain"],
97
+ "timeout": 1_200_000, # milliseconds; simulations block
98
+ }
99
+ }
100
+ }
101
+
102
+ async with MCPAdapter(config) as adapter:
103
+ agent = create_agent("anthropic:claude-sonnet-5", await adapter.list_tools())
104
+ ```
105
+
106
+ The subprocess inherits only `HOME`, `PATH` and a few others, so anything else, including `WQB_*`
107
+ variables, has to go in `env`. Over this route a submission confirmation arrives as a LangGraph
108
+ interrupt, so give the agent a checkpointer if you enable submission. A deployable example is in
109
+ [examples/langgraph_app](examples/langgraph_app).
110
+
111
+ ## Tools
112
+
113
+ | Group | Tool | Notes |
114
+ |---|---|---|
115
+ | Login | `authenticate`, `complete_authentication`, `auth_status` | Other tools log in by themselves |
116
+ | Simulate | `simulate_alpha` | Blocks up to 15 minutes by default; `wait=False` returns at once |
117
+ | | `simulate_alphas_batch` | Up to 30 expressions, in groups of 10; needs multi-simulation access |
118
+ | | `get_simulation_status` | Check or resume a simulation |
119
+ | | `get_simulation_options` | Regions, universes and delays your account can use |
120
+ | Alphas | `get_alpha`, `list_alphas` | Filter by Sharpe, fitness, turnover, date, tag and more |
121
+ | | `get_alpha_pnl`, `list_alpha_recordsets`, `get_alpha_recordset` | PnL by year; other recordsets as rows |
122
+ | | `update_alpha` | Name, description, tags, color, category |
123
+ | | `check_alpha_submission` | BRAIN's pre-submission checks |
124
+ | | `get_alpha_self_correlation`, `get_alpha_prod_correlation` | Production correlation depends on account tier |
125
+ | | `submit_alpha` | Off unless `WQB_ALLOW_SUBMIT=true` |
126
+ | Data | `list_datasets`, `get_dataset`, `list_datafields`, `get_datafield` | |
127
+ | | `list_data_categories`, `list_operators` | |
128
+ | Account | `get_user_profile`, `get_user_activity`, `list_messages` | Personal fields are withheld by default |
129
+
130
+ Resources: `brain://operators`, `brain://simulation-options`, `brain://alphas/{alpha_id}`, and
131
+ reference pages under `brain://docs/` (`fastexpr-cheatsheet`, `settings-guide`,
132
+ `submission-criteria`).
133
+
134
+ Prompts: `design_alpha` runs a short research loop. `review_alpha` assesses an existing alpha.
135
+
136
+ ## Configuration
137
+
138
+ All settings are environment variables. A `.env` file in the working directory also works, except
139
+ for settings that decide where credentials go or that enable submission (`WQB_BASE_URL`, the file
140
+ and directory paths, the `WQB_SUBMIT_*` and `WQB_ALLOW_SUBMIT` settings, and the bearer token).
141
+ These have to be set in the real environment.
142
+
143
+ | Variable | Default | Purpose |
144
+ |---|---|---|
145
+ | `WQB_EMAIL`, `WQB_PASSWORD` | | Login. These win over the credentials file |
146
+ | `WQB_CREDENTIALS_FILE` | `~/.config/mcp-server-worldquantbrain/credentials.json` | JSON: `["email", "password"]` |
147
+ | `WQB_SESSION_FILE` | `~/.config/mcp-server-worldquantbrain/session.json` | Saved session. Delete it to log out |
148
+ | `WQB_CACHE_DIR` | `~/.cache/mcp-server-worldquantbrain` | Catalogue cache and simulation ledger |
149
+ | `WQB_CACHE_TTL` | per catalogue | Seconds; `0` disables the cache |
150
+ | `WQB_LEDGER` | `true` | Reuse results of identical simulations |
151
+ | `WQB_ALLOW_SUBMIT` | `false` | Expose `submit_alpha` |
152
+ | `WQB_SUBMIT_CONFIRM` | `elicit` | Ask the user first where the client supports it; `none` skips asking |
153
+ | `WQB_SUBMIT_CORRELATION_GATE` | `0.7` | Refuse at or above this self-correlation; `0` disables |
154
+ | `WQB_MAX_CONCURRENT_SIMULATIONS` | `2` | Blocking simulation calls this process runs at once |
155
+ | `WQB_SIMULATION_TIMEOUT` | `900` | Seconds a blocking simulation waits |
156
+ | `WQB_HTTP_TIMEOUT` | `30` | Seconds per HTTP request |
157
+ | `WQB_POLL_MAX_INTERVAL` | `30` | Longest pause between status polls |
158
+ | `WQB_HTTP_BEARER_TOKEN` | | Required by the HTTP transport on a non-local address |
159
+ | `WQB_LOG_LEVEL` | `INFO` | Logs go to stderr |
160
+ | `WQB_DEFAULT_REGION`, `WQB_DEFAULT_UNIVERSE`, `_DELAY`, `_DECAY`, `_NEUTRALIZATION`, `_TRUNCATION`, `_PASTEURIZATION`, `_UNIT_HANDLING`, `_NAN_HANDLING`, `_TEST_PERIOD`, `_MAX_TRADE`, `_INSTRUMENT_TYPE` | USA, TOP3000, 1, 0, INDUSTRY, 0.08, ON, VERIFY, OFF, none, OFF, EQUITY | Used when a call leaves a setting out. A call for another region must name its universe |
161
+
162
+ On Windows the two directories are `%APPDATA%\mcp-server-worldquantbrain` and
163
+ `%LOCALAPPDATA%\mcp-server-worldquantbrain`, and files are protected by your user profile rather than POSIX
164
+ permissions.
165
+
166
+ To serve over HTTP:
167
+
168
+ ```bash
169
+ WQB_HTTP_BEARER_TOKEN=change-me mcp-server-worldquantbrain serve --transport streamable-http --host 0.0.0.0
170
+ ```
171
+
172
+ The server refuses a non-local address without a token. `/health` stays open for probes.
173
+
174
+ ## How it behaves
175
+
176
+ **Long calls.** Claude Desktop has been reported to cancel stdio tool calls after about a minute, so
177
+ for that client each call is limited to 45 seconds of waiting and the agent resumes with
178
+ `get_simulation_status`. Claude Code and LangGraph wait as long as you let them. Set
179
+ `WQB_SIMULATION_TIMEOUT` to match whatever your client allows.
180
+
181
+ **Concurrency.** BRAIN limits simultaneous simulations per account and does not publish the number.
182
+ The default of 2 is deliberately cautious. Raise it if your account allows more. The setting only
183
+ counts blocking calls while they wait, and one batch group of up to 10 uses one slot. `wait=False`
184
+ calls, simulations still running after a timeout, and other processes on the same account are not
185
+ counted, and can hit BRAIN's own limit, which comes back as a rate-limit error with a suggested
186
+ wait.
187
+
188
+ **The ledger.** Whitespace in an expression does not matter; every setting does. Pass `force=True`
189
+ to run an identical simulation again. Failed simulations can be run again.
190
+
191
+ **Writes are not retried.** A POST that may have reached BRAIN is never repeated automatically, so a
192
+ network failure cannot spend quota twice or submit twice. Reads retry with backoff and honour
193
+ `Retry-After`.
194
+
195
+ **Biometric login.** `authenticate` returns a URL, the user finishes the check in a browser, and
196
+ `complete_authentication` ends the login. The pending check is saved for 30 minutes, so it survives
197
+ a restart. On a terminal, `mcp-server-worldquantbrain auth` does the same with a prompt.
198
+
199
+ **What is cached.** Operators and simulation options for a week, categories and dataset pages for a
200
+ day. Alphas, simulations, checks, correlations and data fields are always fetched fresh.
201
+
202
+ **What is never logged.** Passwords, cookies, authorization headers and session tokens are masked,
203
+ and email addresses are shortened, in logs and error messages.
204
+
205
+ ## Limitations
206
+
207
+ - BRAIN's API documentation sits behind a login, and BRAIN can change the API without notice. Run
208
+ `WQB_LIVE=1 uv run pytest -m live` to check it against your account.
209
+ - Login, saved sessions, data catalogues, single simulations, alpha search, PnL, recordsets,
210
+ submission checks and self-correlation have been run against a live account. Biometric
211
+ completion, multi-simulation, `update_alpha`, `submit_alpha` and production correlation results
212
+ have only been tested against responses documented by other BRAIN clients, so treat them as less
213
+ proven. If a biometric completion fails, log in once on the BRAIN website and call `authenticate`
214
+ with `force=true`.
215
+ - The self-correlation gate fails closed: if BRAIN will not report the figure, `submit_alpha`
216
+ refuses. Set `WQB_SUBMIT_CORRELATION_GATE=0` on accounts where that endpoint is unavailable.
217
+ - Simulations are REGULAR FASTEXPR alphas. SUPER and region-agnostic alphas, Python alphas, forum
218
+ access, payments, competitions and pyramids are not covered.
219
+ - There is no cancel tool, because no cancel endpoint is known.
220
+ - `credentials.json` is plaintext protected by file permissions. Use `WQB_EMAIL` and `WQB_PASSWORD`
221
+ from your own secret store if that is not enough.
222
+ - Check that your use of automation complies with the BRAIN terms that apply to you.
223
+
224
+ ## Alternatives
225
+
226
+ - [cnhkmcp](https://pypi.org/project/cnhkmcp/) is on PyPI and covers far more of the platform,
227
+ including the forum. It is a large install that bundles Selenium.
228
+ - [lavender1203/world-quant-brain-mcp](https://github.com/lavender1203/world-quant-brain-mcp) has the
229
+ deepest local analytics, such as correlation pools and an alpha history database. It runs with
230
+ Docker and Redis over HTTP, and has no license.
231
+ - [QuantGPT](https://github.com/Miasyster/QuantGPT) is a full research agent with its own knowledge
232
+ base, for when you want the loop rather than the tools.
233
+ - [worldquant-harness](https://github.com/gyx09212214-prog/worldquant-harness) adds local backtests
234
+ and a strict human submission boundary.
235
+ - [brainapi-go-sdk](https://github.com/wh0amibjm/brainapi-go-sdk) is a Go SDK and CLI with static
236
+ binaries and tests built on captured API responses.
237
+ - [rocky-d/wqb](https://github.com/rocky-d/wqb) is a plain Python client, if you do not need an
238
+ agent interface.
239
+
240
+ No code in this repository was copied from those projects.
241
+
242
+ ## Development
243
+
244
+ To point a client at a checkout, use `uvx --from /path/to/mcp-server-worldquantbrain mcp-server-worldquantbrain`,
245
+ or `uv add --editable ../mcp-server-worldquantbrain` from your LangGraph project. See
246
+ [CONTRIBUTING.md](CONTRIBUTING.md) and [RELEASING.md](RELEASING.md).
247
+
248
+ ## License
249
+
250
+ [MIT](LICENSE)
@@ -0,0 +1,96 @@
1
+ [project]
2
+ name = "mcp-server-worldquantbrain"
3
+ version = "0.1.0"
4
+ description = "MCP server and LangGraph tools for the WorldQuant BRAIN platform: simulate alphas, inspect results, browse data fields and operators."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.11"
9
+ keywords = [
10
+ "worldquant",
11
+ "brain",
12
+ "mcp",
13
+ "langgraph",
14
+ "quant",
15
+ "alpha",
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Intended Audience :: Developers",
20
+ "Intended Audience :: Financial and Insurance Industry",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Office/Business :: Financial :: Investment",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = [
30
+ "httpx2>=2.10",
31
+ "mcp>=2.3,<3",
32
+ "pydantic>=2.12",
33
+ "pydantic-settings>=2.10",
34
+ "starlette>=0.48",
35
+ "uvicorn>=0.31.1",
36
+ ]
37
+
38
+ [[project.authors]]
39
+ name = "Marcell Tukora"
40
+
41
+ [project.optional-dependencies]
42
+ langgraph = [
43
+ "langchain>=1.4.6",
44
+ "langchain-core>=1.0",
45
+ "langgraph>=1.2",
46
+ ]
47
+
48
+ [project.scripts]
49
+ mcp-server-worldquantbrain = "mcp_server_worldquantbrain.cli:main"
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/tukorama/mcp-server-worldquantbrain"
53
+ Repository = "https://github.com/tukorama/mcp-server-worldquantbrain"
54
+ Issues = "https://github.com/tukorama/mcp-server-worldquantbrain/issues"
55
+ Changelog = "https://github.com/tukorama/mcp-server-worldquantbrain/blob/main/CHANGELOG.md"
56
+
57
+ [dependency-groups]
58
+ dev = [
59
+ "anyio>=4.9",
60
+ "mcp[cli]>=2.3,<3",
61
+ "pip-audit>=2.10",
62
+ "pyright>=1.1.400",
63
+ "pytest>=8.4",
64
+ "ruff>=0.12",
65
+ ]
66
+
67
+ [build-system]
68
+ requires = ["uv_build>=0.13.7,<0.14"]
69
+ build-backend = "uv_build"
70
+
71
+ [[tool.uv.index]]
72
+ name = "testpypi"
73
+ url = "https://test.pypi.org/simple/"
74
+ publish-url = "https://test.pypi.org/legacy/"
75
+ explicit = true
76
+
77
+ [tool.ruff]
78
+ line-length = 100
79
+
80
+ [tool.ruff.lint]
81
+ select = [
82
+ "E",
83
+ "F",
84
+ "I",
85
+ "UP",
86
+ "B",
87
+ "SIM",
88
+ ]
89
+
90
+ [tool.pyright]
91
+ include = ["src"]
92
+ pythonVersion = "3.11"
93
+
94
+ [tool.pytest.ini_options]
95
+ testpaths = ["tests"]
96
+ markers = ["live: talks to the real BRAIN API (needs WQB_LIVE=1)"]