senti-mcp-server
This server connects an AI assistant to the Senti Quant trading platform, letting it read account, strategy, position, order, deal, performance, and equity data, plus author and manage MQL5 expert advisor drafts.
Read trading data: List linked MT5 accounts (
list_accounts), open positions (list_positions), pending orders (list_pending_orders), and closed deal history (list_deals— paginated with cursor).Query performance: Get account summaries (
get_account_performance), breakdowns by day/symbol/hour (get_performance_breakdowns), and equity/drawdown curves (get_equity_timeseries).Explore platform catalogs: List supported brokers (
list_brokers) and deployable strategies (list_strategies).List per-account deployments: See which strategies are running on a specific account (
list_account_strategies).Author MQL5 drafts (write tools only when
SENTI_ENABLE_AUTHORING_WRITE=1and API key hasauthoring:writescope): Create, read, list, update, delete drafts and their indicator attachments, and compile drafts (create_draft,get_draft,list_drafts,update_draft,delete_draft,add_draft_attachment,update_draft_attachment,delete_draft_attachment,compile_draft).Read authoring rules: Get the MQL5 authoring contract, forbidden constructs, and platform limits (
get_authoring_conventions) before generating code.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@senti-mcp-serverlist my MT5 accounts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
senti-mcp-server
A Model Context Protocol server that lets an AI assistant (Claude Code, Claude Desktop, Cursor, …) read trading data from the Senti Quant Public API.
Tools
Tool | Input | What it does |
| none | Lists the MT5 accounts linked to the configured API key: id, login, broker, last known balance and equity, sync state, running strategies. |
| none | Lists the platform-wide catalog of brokers Senti Quant supports — not the accounts this API key already has — with each broker's MT5 server names and account types. |
| none | Lists the platform-wide catalog of strategies (expert advisors) available to deploy — not the strategies currently running on any account — with each strategy's supported symbols, timeframes, rating and presets. |
|
| Lists the strategies currently deployed on one MT5 account, with each deployment's symbol, timeframe and status. |
|
| Lists the positions currently open on one MT5 account, read live from the terminal: symbol, direction, volume, open/current price, stop loss, take profit, swap and floating profit. A |
|
| Lists the pending limit and stop orders resting on one MT5 account, read live from the terminal: symbol, order type, volume, trigger price, stop loss, take profit and stop-limit price. These are orders that have NOT been filled — for open positions, use |
|
| Lists one page of an MT5 account's closed deal history — the fills that already happened: symbol, direction, entry kind, volume, price, realized profit, costs, the linked position and order. Paginated, and it never pages on its own: one call is exactly one request, and when more deals exist the answer reports a |
|
| Summarizes how one MT5 account performed over a date window: net P&L, win rate, profit factor, gross profit and loss, deal counts, costs, cash flow, period ROI and IRR, lifetime IRR, and the live terminal state. Omit |
|
| Breaks one MT5 account down three ways over a date window: a day-by-day P&L, volume and notional series; a per-symbol P&L and deal-count series; and P&L by hour of the day. Answers "which symbol is losing me money" and "what hour do I trade worst". This response is shaped. The endpoint is the largest the API serves — 87 KB for a 63-day window on a single-symbol account — so per-account rows and running totals are dropped, at most 10 symbols are kept (those with the largest absolute net P&L), and the hourly grid is totalled across the window. Whatever that costs is listed in |
|
| Returns the reconstructed equity curve and floating drawdown for one MT5 account over a date window, as a series of points — answers "how has my equity moved" and "what was my worst drawdown". This response is shaped. A wide window returns a point per interval and grows without bound, so the series is downsampled to at most 200 points — but the first point, the last point and the point of deepest drawdown are always retained, so the start, the end and the worst of the curve are exact rather than sampled near. Measured live on 2026-08-12: 499 points over 63 days → 200. Every downsample is recorded in |
| none | Reads the Senti Quant MQL5 authoring contract as data: hard-safety constraints, trading-safety requirements, the static analyzer's forbidden-construct list, and the platform limits on draft count and source size. Call this before generating any MQL5 source — code that breaks these rules is rejected by a static scan before it reaches the compiler, and compile slots are globally serial, so discovering a rule by failing a compile is expensive and still fails. Limits are reported exactly — a ceiling that is not a whole multiple of 1024 stays in bytes rather than being rounded into a KiB figure the API does not honour. The response is small (~2 KB) and static per deploy; |
|
| Reads one MQL5 draft the API key owns: its full source code, its compiler log, its diagnostics, and whether the last compile still matches the current source. Answers "why did this fail to compile" or "show me the code". The response can be large — a draft may hold up to 192 KiB of source plus 16 KiB of compiler log, and this server returns that content twice, once as text and once as structured data — roughly 105,000 tokens worst case. Attachment source is NOT included; attachments are listed with their size, and |
| none | Lists the MQL5 drafts this API key owns, most recently updated first, with each draft's compile status, source size and SHA-256, compile-log size, attachment sizes and registered-EA id. Use it to find a |
|
| Reads the indicator source files a draft's EA embeds via |
|
| Write tool — registered only when |
|
| Write tool, behind the opt-in. Replaces an existing draft. THIS IS A FULL REPLACE, NOT A PATCH — both fields are always written, so send the complete draft every time; sending only what you changed deletes the rest of the file, because the API has no partial-update verb. Call |
|
| Write tool, behind the opt-in — and it asks first. Deletes one draft and every indicator attached to it. Cannot be undone, and no tool here restores one, so it pauses for an explicit human confirmation before anything is sent; declining returns a success saying nothing was deleted, not an error. An EA already registered from the draft is unaffected — a separate resource. Use it to free a slot when |
|
| Write tool, behind the opt-in. Attaches one MQL5 indicator source to a draft so the EA can embed it. Filenames are unique within a draft case-insensitively — |
|
| Write tool, behind the opt-in. Replaces one indicator's source. The filename cannot be changed and this tool takes no filename — an EA embeds an indicator by name, so a rename would orphan every reference; to rename, delete, re-add and update the EA source. A full replace of that file's contents, so send the complete indicator. A |
|
| Write tool, behind the opt-in — and it asks first. Removes one indicator from a draft. Cannot be undone. Afterwards the EA still references it: remove its |
|
| Write tool, behind the opt-in. Runs the static-safety scan and the MQL5 compiler over a draft and every indicator attached to it, and returns the verdict, the diagnostics and the compiler log. A check only — it registers and deploys nothing. A failed build is not an error: the tool succeeds and reports |
The id a tool returns is the accountId other Senti endpoints take. login is
the MT5 account number, not a key.
Related MCP server: ctrader-mcp-server
Requirements
Node.js ≥ 22.11.0 — the first LTS release of the Node 22 "Jod" line, supported until 2027-04-30. The floor is a support-lifetime choice, not an API one: the newest runtime feature this server actually uses is
AbortSignal.any()(Node 20.3.0), on the path of every tool call, andnpm run test:smokeusesnode --env-file(20.6.0). Raised from the old 20.6.0 floor in v2.0.0 because Node 20 reached end of life on 2026-04-30 (CONTEXT D27)A Senti Quant API key (
sq_live_…). As of v2.1.0 the tool surface needs six read scopes:accounts:read,brokers:read,strategies:read,performance:read,trading:read,authoring:read— create one with all six at the API Keys dashboard. There is no key-introspection endpoint, so a missing scope isn't caught at startup: it surfaces as a403naming the scope the first time the affected tool is called, and every other tool keeps working. All six are exercised by a shipped tool:accounts:read(list_accounts),brokers:read(list_brokers),strategies:read(list_strategies,list_account_strategies),trading:read(list_positions,list_pending_orders,list_deals),performance:read(get_account_performance,get_performance_breakdowns,get_equity_timeseries) andauthoring:read(get_authoring_conventions,get_draft,list_drafts,list_draft_attachments).A seventh scope,
authoring:write, only if you turn the write tools on. As of v2.5.0SENTI_ENABLE_AUTHORING_WRITEregisters tools that create and change MQL5 drafts, and those need it. A key without it runs the entire read surface unaffected, and a key with it changes nothing while the flag is unset — no write tool is registered, so none can be called.
Configuration
Variable | Required | Default | Purpose |
| ✅ | — | First-party key. The server exits at startup without it. |
|
| Override only to reach another deployment of the API, such as a local one. | |
| unset (off) |
|
Enabling the write path
Every tool is read-only unless you opt in. Set SENTI_ENABLE_AUTHORING_WRITE=1
in the server's env block and the authoring write tools are registered; leave it
unset — or set it to 0, false, no or off — and they are not. A host that
never sets it never sees one in tools/list, so there is nothing for a model to
call by accident.
Turning it on gives an agent the ability to create, replace and delete MQL5
drafts and their indicator files, and to compile them — the whole
write → build → read the errors → write again loop, without leaving the editor.
The key must also hold authoring:write.
The two delete tools pause for a human. delete_draft and
delete_draft_attachment ask for an explicit confirmation through MCP elicitation
before anything is sent, because they are the only operations here that no other
tool can undo. The other five do not ask: update_draft fires on every save in an
edit loop, and a prompt seen fifty times a session gets rubber-stamped, which is
worse than no prompt. On a host that does not support elicitation the two delete
tools cannot be used — deliberately, rather than degraded to a silent delete.
It does not enable any trading write. Closing a position, cancelling an order
and deploying a strategy to an account are a different surface, gated by a
different scope (strategies:write, trading:write) and by a flag that does not
exist yet — see EPIC-3. No setting of
SENTI_ENABLE_AUTHORING_WRITE reaches them. Registering an authored EA as a
private strategy is also not available: that is POST …/register, deliberately
left out of EPIC-8 because no operation in the
authoring surface can delete what it creates.
The key and the base URL must belong to the same environment. Keys are environment-bound: a key is issued by whichever backend the dashboard you used talks to, and it returns
401against any other, however valid it is. So when a correct-looking key is rejected, checkSENTI_API_BASE_URLbefore regenerating the key — a401is far more often a mismatched environment than a bad key.Verified pairing: a key from the API Keys dashboard against the default,
https://api.sentitrade.xyz— checked on 2026-09-15 with an authenticated read (CONTEXT D48). LeaveSENTI_API_BASE_URLunset unless you run another deployment of the API.
See docs/SETUP.md for a full local setup walkthrough.
Use with an MCP client
No install step — npx fetches the published package on first run:
{
"mcpServers": {
"senti": {
"command": "npx",
"args": ["-y", "senti-mcp-server"],
"env": {
"SENTI_API_KEY": "sq_live_..."
}
}
}
}Restart the client; all fourteen tools should appear — every GET operation the Senti
Quant Public API exposes now has one, the last four added over the Authoring tag
EPIC-7 shipped.
npx -y senti-mcp-server resolves to whatever npm's latest tag points at — 2.9.0 as
of this release.
It carries 2.4.0's fourteen read tools plus seven write tools — create_draft,
update_draft, delete_draft, add_draft_attachment, update_draft_attachment,
delete_draft_attachment and compile_draft — which are registered only when
SENTI_ENABLE_AUTHORING_WRITE is set, so an installation that does not set it sees the same
fourteen tools 2.4.0 did.
2.4.0 carries the ten tools of 1.4.0 plus get_authoring_conventions, get_draft,
list_drafts and list_draft_attachments, fourteen in total, and no write tool at any
setting. 2.3.0 carries those same
ten tools plus get_authoring_conventions, get_draft and list_drafts, thirteen in
total. 2.2.0 carries those same ten tools plus get_authoring_conventions and
get_draft, twelve in total. 2.1.0 carries those same ten tools plus
get_authoring_conventions only, eleven in total. 2.0.1 and 2.0.0
carry the same ten tools as 1.4.0 and differ from it only in
requiring Node ≥ 22.11.0; the 2.0.1 patch on top of 2.0.0 carries only
build-toolchain and documentation changes.
1.4.0 is the last version declaring the old 20.6.0 floor and is the one to
pin if you are stuck on Node 20; it carries ten tools. 1.3.0 carries nine,
without get_equity_timeseries; 1.2.0 carries eight, without
get_performance_breakdowns as well; 1.1.0 carries seven, without list_deals
on top of that; 1.0.1 carries six, without get_account_performance too;
and only list_accounts is reachable on 0.1.0, which was published before the
others existed, so check npm view senti-mcp-server dist-tags if a tool you
expect is missing.
Pin the version in args if you want to hold one —
["-y", "senti-mcp-server@2.9.0"]. To put it on your PATH instead:
npm install -g senti-mcp-serverThen the client block becomes "command": "senti-mcp-server" with no args.
From a git checkout
Point the client at your own build — useful while developing:
npm install
npm run build{
"mcpServers": {
"senti": {
"command": "node",
"args": ["/absolute/path/to/senti-mcp-server/dist/index.js"],
"env": {
"SENTI_API_KEY": "sq_live_..."
}
}
}
}Security
The API key is read from the environment and never appears in a tool's input schema. A tool parameter would live in the model's context, and from there in transcripts and logs; an environment variable does not. The test suite asserts the key appears in no error message.
The trading write operations are not exposed. Closing positions, cancelling
orders and stopping strategies have no tool, deliberately, and adding one needs
its own design. The authoring writes that SENTI_ENABLE_AUTHORING_WRITE turns
on (v2.5.0) are the only writes this server can make: they create, replace,
delete and compile MQL5 drafts, and touch no account, position or order. They
ship with the three things this section has always demanded of a write — an
opt-in switch, Idempotency-Key support, and user confirmation before either
delete. Left unset, the server registers read-only tools only.
Development
npm test # unit tests (stubbed fetch)
npm run test:watch
npm run test:smoke # one live call against the dev API; needs .env.local
npm run typecheck
npm run dev # run from source, e.g. SENTI_API_KEY=… npm run devnpm run test:smoke reads SENTI_SMOKE_KEY from .env.local, which is
gitignored. If .env.local exists but doesn't set SENTI_SMOKE_KEY, the smoke
test skips cleanly. If .env.local doesn't exist at all, node --env-file fails
to start (node: .env.local: not found, exit 9) rather than skipping — create
the file, even empty, to get the skip instead of the failure.
License
MIT
Available Tools
14 toolsget_account_performanceGet an account performance summaryARead-only
Summarize how one MT5 account has performed over a date window: net P&L, win rate, profit factor, gross profit and loss, deal counts, costs, cash flow, period ROI and IRR, lifetime IRR, and the live terminal state. This is the default tool for any performance question — the response is a fixed-size summary that does not grow with the window. accountId is the id field from list_accounts — NOT login. Omit from/to for the last 30 days. reporting is an ISO-4217 currency code (default USD), not a reporting period. A null live block means the terminal was unreachable, not that the account is empty.
Inputs: accountId (required), to, from, reporting. Returns: live, notes, metrics, lifetimeIrr, +1 more
get_authoring_conventionsRead the MQL5 authoring rulesARead-only
Read the Senti Quant MQL5 authoring contract as data: the hard-safety constraints, the trading-safety requirements, the static analyzer's forbidden-construct list, and the platform limits on draft count and source size. CALL THIS BEFORE GENERATING ANY MQL5 SOURCE. Code that breaks these rules is rejected by a static scan before it reaches the compiler, and compile slots are globally serial, so discovering a rule by failing a compile is expensive and still fails. The response is small (~2 KB) and static per deploy. forbiddenConstructs[].pattern values are regular expressions reported verbatim — this tool does not evaluate them.
Inputs: no named parameters. Returns: limits, forbiddenConstructs, hardSafetyConstraints, tradingSafetyRequirements
get_draftRead one MQL5 draftARead-only
Read one MQL5 draft the API key owns: its full source code, its compiler log, its diagnostics, and whether the last compile still matches the current source. Use it to answer "why did this fail to compile" or "show me the code". draftId is the id field from list_drafts. THE RESPONSE CAN BE LARGE — a draft may hold up to 192 KiB of source plus 16 KiB of compiler log, and this server returns that content twice (once as text, once as structured data) — roughly 105,000 tokens worst case. Attachment source is NOT included; the attachments are listed with their size, and list_draft_attachments returns their code. For a cheap overview of every draft, call list_drafts instead.
Inputs: draftId (required). Returns: id, name, notes, createdAt, +9 more
get_equity_timeseriesTrack an account's equity curve and drawdown over timeARead-only
Return the reconstructed equity curve and floating drawdown for one MT5 account over a date window, as a series of points. Use it for "how has my equity moved" or "what was my worst drawdown". For a single whole-account figure — net P&L, win rate, ROI — use get_account_performance; for a breakdown by day, symbol or hour use get_performance_breakdowns. THIS RESPONSE IS SHAPED. A wide window holds more points than an answer can carry, so the series is downsampled to at most 200 points — but the first point, the last point and the point of deepest drawdown are always retained, so the start, the end and the worst of the curve are exact rather than approximate. Every downsample is recorded in notes, which is empty when the series was short enough to return whole. A short move between two kept points may not be visible; narrow from/to for finer resolution. caveats and portfolioCaveats are the API's own statements about figures it could not fully reconstruct — read them before quoting a number. accountId is the id field from list_accounts — NOT login. Omit from/to for the last 30 days. reporting is an ISO-4217 currency code (default USD), not a reporting period.
Inputs: accountId (required), to, from, reporting. Returns: notes, caveats, portfolio, portfolioCaveats
get_performance_breakdownsBreak an account down by day, symbol and hourARead-only
Break one MT5 account down three ways over a date window: a day-by-day P&L, volume and notional series; a per-symbol P&L and deal-count series; and P&L by hour of the day. Use it for "which symbol is losing me money" or "what hour do I trade worst". For a single whole-account figure — net P&L, win rate, ROI, the live terminal — use get_account_performance instead: it is smaller and it is the default for a performance question. THIS RESPONSE IS SHAPED. The endpoint returns a chart-sized payload, so per-account rows and running totals are dropped, at most ten symbols are kept, and the hourly grid is totalled across the window. Whatever that cost is listed in notes, which is empty when nothing was cut — read it before concluding that a symbol was not traded. accountId is the id field from list_accounts — NOT login. Omit from/to for the last 30 days; a narrower window is also how you see a symbol that was cut. reporting is an ISO-4217 currency code (default USD), not a reporting period.
Inputs: accountId (required), to, from, reporting. Returns: daily, notes, hourly, perSymbol
list_accountsList linked MT5 accountsARead-only
List the MT5 trading accounts linked to the configured Senti Quant API key. Returns each account's id, login, broker, last known balance and equity, sync state, and running strategies. The id field is the accountId every other Senti endpoint takes — pass id, not login, when a tool asks for an account.
Inputs: no named parameters. Returns: accounts
list_account_strategiesList strategies deployed on an accountARead-only
List the strategies (expert advisors) currently deployed on one MT5 account, with each deployment's symbol, timeframe and status. accountId is the id field from list_accounts — NOT login, which is the MT5 account number and is not a valid accountId. For the platform-wide catalog of strategies available to deploy, use list_strategies instead.
Inputs: accountId (required). Returns: strategies
list_brokersList brokers available to linkARead-only
List the brokers Senti Quant supports, with each broker's MT5 server names and account types. This is the platform-wide catalog of what can be linked — it is NOT the set of accounts this API key already has, which is list_accounts. Use accountTypes[].id as brokerAccountTypeId and a servers[] value as server when linking a new account.
Inputs: no named parameters. Returns: brokers
list_dealsList deal history for an accountARead-only
List the closed deal history of one MT5 account — the fills that already happened, newest first: symbol, direction, entry kind, volume, price, realized profit, costs and time. For what is open right now use list_positions, and for orders still resting use list_pending_orders. For totals and ratios over a period use get_account_performance rather than adding these rows up. accountId is the id field from list_accounts — NOT login. This endpoint is paginated: limit defaults to 50 and may not exceed 500, and one call returns exactly one page. If the answer reports that more deals are available, it also reports a cursor — you must call this tool again passing that value as cursor to read the next page. This tool never pages on its own. Narrow instead of paging where you can: entry takes lowercase in (opening) or out (closing), and from/to take ISO-8601 timestamps.
Inputs: accountId (required), to, from, entry, +2 more. Returns: deals, nextCursor, syncedThrough
list_draft_attachmentsRead a draft's indicator sourcesARead-only
Read the indicator source files a draft's EA embeds via #resource. draftId is the id field from list_drafts. Pass filename to read at most one attachment whole, by exact name — that is also how to read one the default call had to leave out. Filenames are not guaranteed unique within a draft: if more than one attachment shares the requested name, only the first is returned and notes says how many were skipped. With filename omitted this returns every attachment's source up to a 64 KiB budget and lists the rest by name and size only; notes says whether that happened. THE RESPONSE CAN BE LARGE — up to 64 KiB of source, returned in both content and structuredContent — roughly 33,000 tokens worst case. Use get_draft for the EA's own source, which this tool never returns.
Inputs: draftId (required), filename. Returns: notes, attachments
list_draftsList MQL5 authoring draftsARead-only
List the MQL5 drafts this API key owns, most recently updated first, with each draft's compile status, source size and SHA-256, compile-log size, attachment sizes and registered-EA id. Use it to find a draftId, to answer "what am I working on" and "which of my drafts are broken", or to tell whether a copy of a draft you hold is current. The list carries sizes and hashes rather than bodies: no source code, compiler log or diagnostics. A non-null compileLogBytes means the last compile left a log to read, even when diagnosticsCount is 0. Call get_draft for one draft's source, compiler log and diagnostics, and list_draft_attachments for its indicator sources.
Inputs: no named parameters. Returns: notes, drafts
list_pending_ordersList pending orders on an accountARead-only
List the pending limit and stop orders resting on one MT5 account, read live from the terminal: symbol, order type, volume, trigger price, stop loss and take profit. These are orders that have NOT been filled — for filled positions currently open, use list_positions. accountId is the id field from list_accounts, NOT login. Each order's ticket is the handle used to cancel it. An sl, tp or priceStopLimit of 0 means that level is not set.
Inputs: accountId (required). Returns: notes, orders
list_positionsList open positions on an accountARead-only
List the positions currently open on one MT5 account, read live from the terminal: symbol, direction, volume, open and current price, stop loss, take profit, swap and floating profit. accountId is the id field from list_accounts — NOT login. Each position's ticket is the handle used to close it. An sl or tp of 0 means no stop loss or take profit is set.
Inputs: accountId (required). Returns: notes, positions
list_strategiesList deployable strategiesARead-only
List every strategy (expert advisor) available to deploy on Senti Quant, with its supported symbols, timeframes, rating and presets. This is the platform-wide catalog of what COULD be deployed — it is NOT what is currently running on an account. For the strategies running on a specific account, use list_account_strategies. Use id as eaDefinitionId when deploying.
Inputs: no named parameters. Returns: strategies
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 14 tools
Each tool targets a distinct resource or view: drafts vs attachments vs accounts vs strategies vs positions/orders/deals vs performance summaries. The closely related performance tools explicitly cross-reference each other, and list_strategies/list_account_strategies plus list_brokers/list_accounts are clearly differentiated.
All tools use lowercase snake_case with a consistent verb_noun pattern: list_* for collections and get_* for single or detailed views. Compound names like list_account_strategies and list_draft_attachments are still predictable.
14 tools is within the ideal range for a platform of this scope, and each tool earns its place. There are no redundant or filler tools.
The read side is comprehensive, but the set is read-only while descriptions repeatedly point to missing lifecycle actions: drafts can be listed/read but not created/updated/compiled, strategies can be listed but not deployed, and position/order tickets are described as handles to close/cancel yet no such tools exist. These are significant dead ends that will cause agent failures.
Maintenance
Related MCP Connectors
Trading MCP server for AI agents, with live market data, account reads and controlled execution.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
MCP server for OpenMM — exposes market data, account, trading, and strategy tools to AI agents
A Model Context Protocol server for Wix AI tools
Related MCP Servers
- FlicenseDqualityDmaintenanceA Model Context Protocol server that enables AI assistants to interact with the Deriv trading API, providing access to active trading symbols and account balance information.2-
- FlicenseNot gradedqualityDmaintenanceA standalone Model Context Protocol (MCP) server that enables AI assistants to interact with the cTrader trading platform.15-
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for the Hyperliquid decentralized exchange, enabling AI assistants to perform trading operations, manage accounts, and retrieve market data.29 PyPI3MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to connect to MetaTrader 5 for trading, market data access, and account management through the Model Context Protocol.118 PyPI239MIT