Skip to main content
Glama
Koniverse

senti-mcp-server

by Koniverse

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

list_accounts

none

Lists the MT5 accounts linked to the configured API key: id, login, broker, last known balance and equity, sync state, running strategies.

list_brokers

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.

list_strategies

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.

list_account_strategies

accountId (the id from list_accounts, not login)

Lists the strategies currently deployed on one MT5 account, with each deployment's symbol, timeframe and status.

list_positions

accountId (the id from list_accounts, not login)

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 409 means the account's terminal is offline — not that the account holds no positions.

list_pending_orders

accountId (the id from list_accounts, not login)

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 list_positions. A 409 means the account's terminal is offline — not that the account has no pending orders.

list_deals

accountId, plus optional limit (1–500, default 50), cursor, entry (in or out), from and to (ISO-8601)

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 cursor you must pass back to read the next page. For totals over a period use get_account_performance rather than adding these rows up.

get_account_performance

accountId, plus optional from, to (YYYY-MM-DD, UTC) and reporting (an ISO-4217 currency code, default USD)

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 from/to for the last 30 days. Unlike list_positions and list_pending_orders there is no 409 — an unreachable terminal arrives as a null live block inside a success, and is reported as unreachable rather than as zeroes.

get_performance_breakdowns

accountId, plus the same optional from, to and reporting as get_account_performance

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 notes and repeated in the text; notes is empty when nothing was cut. For a single whole-account figure use get_account_performance — it is smaller and it is the default for a performance question.

get_equity_timeseries

accountId, plus the same optional from, to and reporting as get_account_performance

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 notes, which is empty when the series was short enough to return whole; narrow from/to for finer resolution. caveats and portfolioCaveats — the API's own statements about figures it could not fully reconstruct — are always returned in full, never shortened.

get_authoring_conventions

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; forbiddenConstructs[].pattern values are regular expressions reported verbatim, never evaluated.

get_draft

draftId (the id field from list_drafts)

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 list_draft_attachments returns their code — notes points there only when an attachment actually carried source to lose.

list_drafts

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 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 — it reads the API's draft summaries, so no source code, compiler log or diagnostics cross the wire. A non-null compileLogBytes means the last compile left a log to read, even when diagnosticsCount is 0. Measured live on 2026-09-15: 1,616 B for 4 drafts, against 22,459 B for the same drafts in full. Call get_draft for one draft's source, compiler log and diagnostics, and list_draft_attachments for its indicator sources. notes is kept for compatibility and is always empty.

list_draft_attachments

draftId (the id field from list_drafts), plus optional filename

Reads the indicator source files a draft's EA embeds via #resource — the source get_draft deliberately leaves out. Pass filename to read at most one attachment whole, by exact name; that is also how to read one a default call had to leave out — if more than one attachment shares that filename, only the first is returned and notes says how many were skipped. A filtered read says so in its text and names the draft's real attachment count, so content alone is never read as the whole set. This response is budgeted, not truncated. With filename omitted, attachments are returned whole while the running total stays within a 64 KiB budget — the first attachment is always returned whole regardless of size, and once one is cut every later one is cut too, and notes says exactly that rather than claiming each cut file exceeded the budget; a cut attachment keeps its metadata and reports sourceCode: null, never a partial source. notes says whether a cut happened. Worst case, counting both response channels, is roughly 33,000 tokens.

create_draft

name (1–120 chars, unique per user), sourceCode (the complete EA)

Write tool — registered only when SENTI_ENABLE_AUTHORING_WRITE is set (see Enabling the write path). Creates a new MQL5 draft from source you have written, and returns its id. Call get_authoring_conventions first: code that breaks the platform rules is rejected by a static scan before it reaches the compiler, and this tool does not check them for you. The response does not echo your source back — you just sent it — so it returns the new id, the byte count written and the compile state, and notes points at get_draft for a read-back. Nothing is compiled until you call compile_draft. A 409 means the name is taken; a 403 means either the key lacks authoring:write or your draft cap is full, and the message says both because the API does not distinguish them.

update_draft

draftId, name, sourceCode

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 get_draft first if you do not have the current source. Annotated destructiveHint for exactly that reason, despite the name. Reports the bytes written, not a before/after delta — the PUT response carries only the new draft, and this server does not make a hidden second request to invent the missing figure. Compiles nothing; if a previous compile no longer matches, the text says so and points at compile_draft.

delete_draft

draftId

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 create_draft reports the draft cap is full. Needs a host that supports MCP elicitation; on one that does not, this tool cannot be used, and that is deliberate rather than degraded to a silent delete.

add_draft_attachment

draftId, filename (a bare .mq5 basename), sourceCode

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-insensitivelyMyInd.mq5 collides with myind.mq5, because the compile host writes them into one flat Windows directory. Attaching does not wire it up: the text names the exact #resource "<stem>.ex5" and iCustom(…) lines the EA still needs, which means an update_draft afterwards, or the file is compiled and never used. The response does not echo your source back.

update_draft_attachment

draftId, attachmentId, sourceCode

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 404 here may also mean the attachment belongs to a different draft.

delete_draft_attachment

draftId, attachmentId

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 #resource and iCustom lines with update_draft, or the next compile_draft fails on a file that is no longer there — the text says so. Also how to free a slot when the attachment cap is full, and the only way to rename a file. Needs a host that supports MCP elicitation.

compile_draft

draftId

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 ok: false with diagnostics, so read the result rather than retrying. The compile slot is one per account and the compile server is globally serial, so a second concurrent call is a 409 and contention is a 503 with a wait — this server reports both and retries neither. If the 15s client timeout fires, the compile keeps running on the server: the message says so and sends you to get_draft for lastCompileStatus.

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, and npm run test:smoke uses node --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 a 403 naming 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) and authoring: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.0 SENTI_ENABLE_AUTHORING_WRITE registers 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

SENTI_API_KEY

First-party key. The server exits at startup without it.

SENTI_API_BASE_URL

https://api.sentitrade.xyz

Override only to reach another deployment of the API, such as a local one.

SENTI_ENABLE_AUTHORING_WRITE

unset (off)

1 or true registers the authoring write tools. See below.

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 401 against any other, however valid it is. So when a correct-looking key is rejected, check SENTI_API_BASE_URL before regenerating the key — a 401 is 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). Leave SENTI_API_BASE_URL unset 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-server

Then 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 dev

npm 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 tools
get_account_performanceGet an account performance summaryA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoWindow end, inclusive (UTC, YYYY-MM-DD).
fromNoWindow start (UTC, YYYY-MM-DD).
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).
reportingNoISO-4217 currency the money figures are normalized to. Defaults to USD.

Output Schema

ParametersJSON Schema
NameRequiredDescription
liveYes
notesYes
metricsYes
lifetimeIrrYes
portfolioReturnYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, it discloses meaningful behavior: the summary is fixed-size and does not grow with the window, and a null live block means the terminal was unreachable rather than the account being empty. These are exactly the kind of non-obvious behavioral details an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: the first defines the tool's output, the second establishes its default role, and the remaining sentences clarify parameter gotchas and null semantics. The most important usage guidance is front-loaded, with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists, the description does not need to spell out return fields, yet it still covers defaults, parameter identity traps, and the live-block null meaning. For a read-only summary tool with one required parameter, this is fully sufficient for an agent to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description adds essential disambiguation: accountId is the id from list_accounts and not the MT5 login, reporting is a currency code rather than a reporting period, and omitting from/to defaults to the last 30 days. This goes well beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb (summarize), a specific resource (one MT5 account over a date window), and enumerates the exact metrics returned (net P&L, win rate, profit factor, gross profit/loss, deal counts, etc.). It also explicitly positions itself as the default tool for performance questions, which distinguishes it from breakdown and timeseries siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly says this is the default tool for any performance question and explains that the response stays fixed-size regardless of window length, which guides selection. It also gives concrete invocation guidance like omitting from/to for the last 30 days, but it does not name specific sibling alternatives to use instead for specialized performance breakdowns.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_authoring_conventionsRead the MQL5 authoring rulesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
limitsYes
forbiddenConstructsYes
hardSafetyConstraintsYes
tradingSafetyRequirementsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint annotation, the description adds behavioral specifics: the response is small (~2 KB) and static per deploy, and forbiddenConstructs[].pattern values are regular expressions reported verbatim without evaluation. These details give an agent accurate expectations about call cost, response stability, and the tool's pass-through behavior, all of which are not visible in annotations or the empty input schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place. The first sentence defines the resource, the second gives a direct action, the third provides the cost rationale, and the final two disclose response size and regex handling. The content is front-loaded with the most important information and uses imperative language for the critical instruction.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a read-only, zero-parameter tool. An output schema exists, so return-value detail is not the description's responsibility, but it still tells the agent the response is small, static, and that regexes are verbatim. The sibling-tool context shows no overlap, so no alternative-routing information is needed. An agent knows exactly when to call it and what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the baseline is 4. The description does not need to explain parameter meanings; instead it clarifies what the returned data represents, which is the closest equivalent. It names the four content categories and the pattern semantics, adding meaning beyond the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read the Senti Quant MQL5 authoring contract as data'. It enumerates four concrete components of that contract and the platform limits on draft count and source size. This clearly differentiates it from all sibling tools, which deal with drafts, accounts, brokers, strategies, positions, and performance—not authoring rules.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit, imperative trigger: 'CALL THIS BEFORE GENERATING ANY MQL5 SOURCE.' It also explains the cost of ignoring that guidance: rule-breaking code is rejected by a static scan before the compiler, and compile slots are globally serial, making compile-time discovery expensive. This is unambiguous when-to-use guidance with a clear rationale.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_draftRead one MQL5 draftA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
draftIdYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
notesYes
createdAtYes
updatedAtYes
sourceCodeYes
attachmentsYes
logTruncatedYes
eaDefinitionIdYes
lastCompileLogYes
compiledUpToDateYes
lastCompileStatusYes
lastCompileDiagnosticsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=true, and the description complements them by disclosing the potentially huge response size (up to ~105,000 tokens), the duplication of content, and the exclusion of attachment source. These are significant behavioral details beyond the annotations, and there is no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than average but every sentence earns its place: the core purpose is front-loaded, the size warning is critical and placed early, and the sibling alternatives are at the end. The structure is logical and scannable; a slight trim could improve conciseness but it remains efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists (though not shown) and the annotations cover safety, the description fully equips the agent: it covers the payload contents, response size, what is not included, and when to use alternatives. No critical information is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It explains that draftId is the id field from list_drafts, which gives the agent a concrete way to obtain a valid value. It doesn't describe format constraints, but for a single string parameter that's sufficient; it adds meaningful context beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Read one MQL5 draft') and the resource, enumerating the exact payload fields (source code, compiler log, diagnostics, compile-match status). It explicitly differentiates from siblings by naming list_drafts and list_draft_attachments and explaining what each offers, so an agent can unambiguously pick this tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit use cases ('why did this fail to compile', 'show me the code'), states the parameter source (draftId from list_drafts), and gives clear alternatives with conditions: list_drafts for a cheap overview, list_draft_attachments for attachment code. This is comprehensive routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_equity_timeseriesTrack an account's equity curve and drawdown over timeA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoWindow end, inclusive (UTC, YYYY-MM-DD).
fromNoWindow start (UTC, YYYY-MM-DD).
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).
reportingNoISO-4217 currency the money figures are normalized to. Defaults to USD.

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
caveatsYes
portfolioYes
portfolioCaveatsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint, openWorldHint), the description discloses key behavioral traits: the series is downsampled to at most 200 points, but first/last/deepest-drawdown points are always retained. It explains the `notes` field records downsampling and warns that short moves may not be visible. It also tells users to read `caveats` and `portfolioCaveats` before quoting numbers, which is critical for data quality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured: purpose first, then alternatives, then downsampling behavior, then parameter clarifications. Every sentence adds value, though the length is substantial. The all-caps 'THIS RESPONSE IS SHAPED' is attention-grabbing but slightly jarring; however, it emphasizes an important limitation. Overall it's appropriately sized for a tool with these nuances.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations are present, the description covers all necessary operational context: how the response is shaped, downsampling rules, the meaning of `notes` and `caveats`, and parameter gotchas. It leaves no major ambiguity about selecting, invoking, or interpreting the tool's results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes parameters, but the description adds crucial disambiguation: `accountId` is the `id` field from list_accounts (NOT `login`), and `reporting` is an ISO-4217 currency code, not a reporting period. It also notes omitting from/to gives the last 30 days. These clarifications prevent common misuse and go well beyond the schema's stated descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a specific verb and resource: 'Return the reconstructed equity curve and floating drawdown for one MT5 account over a date window, as a series of points.' It clearly distinguishes from siblings by naming get_account_performance for whole-account figures and get_performance_breakdowns for day/symbol/hour breakdowns, so the tool's role is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance says when to use it ('how has my equity moved' or 'what was my worst drawdown') and when not to (for net P&L, win rate, ROI use get_account_performance; for breakdowns use get_performance_breakdowns). It also adds practical tips like omitting from/to for the last 30 days and narrowing the window for finer resolution.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_performance_breakdownsBreak an account down by day, symbol and hourA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoWindow end, inclusive (UTC, YYYY-MM-DD).
fromNoWindow start (UTC, YYYY-MM-DD).
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).
reportingNoISO-4217 currency the money figures are normalized to. Defaults to USD.

Output Schema

ParametersJSON Schema
NameRequiredDescription
dailyYes
notesYes
hourlyYes
perSymbolYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses response shaping that annotations don't cover: per-account rows and running totals are dropped, at most ten symbols are kept, the hourly grid is totalled, and cuts are reported in `notes`. It also warns to read `notes` before concluding a symbol was untraded and notes that narrowing the window reveals cut symbols. This adds substantial behavioral context beyond readOnlyHint=true and openWorldHint=true, and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded: purpose first, then usage guidance, then behavioral caveats, then parameter disambiguation. A few phrases like 'THIS RESPONSE IS SHAPED.' are slightly opaque and the accountId warning repeats the schema, but no sentence is pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and readOnly/openWorld annotations, the description covers all operational essentials: what data is returned, how it may be truncated, how to detect cuts, default time window, and the accountId-vs-login trap. An agent has everything needed to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds non-redundant meaning: omitting `from`/`to` defaults to the last 30 days, `reporting` is disambiguated from a reporting period, and accountId is re-emphasized as list_accounts.id, not login. Some duplication exists with schema descriptions, but the default-window behavior is genuinely new.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise action: breaking one MT5 account into three series (day-by-day P&L/volume/notional, per-symbol P&L/deal-count, and P&L by hour) over a date window. It also names the sibling get_account_performance and explicitly says what this tool is not (a single whole-account figure), making it easy to distinguish without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete example questions ('which symbol is losing me money', 'what hour do I trade worst') for when to use it, and directs the agent to get_account_performance for single whole-account figures, calling it 'the default for a performance question.' This is explicit when/when-not guidance with a named alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsList linked MT5 accountsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
accountsYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=trueabc and openWorldHint=true, so the read-only safety profile is covered. The description adds meaningful behavioral context by stating exactly what each returned account entry contains and that `id` is the accountId used by other endpoints, which goes beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the first states the action and scope, the second lists the output fields and adds the critical id/login distinction. Every sentence provides necessary information and the most important usage detail is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool with an output schema, the description is complete. It identifies the resource, the output fields, and the cross-tool meaning of `id`. No additional pagination or ordering details are necessary for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Parameter count is 0 and schema coverage is 100%, so the baseline is 4. The description goes further by explaining the meaning and downstream use of the returned `id` field, which is effectively the most important semantic information an agent needs for parameterizing future calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and a specific resource ('MT5 trading accounts linked to the configured Senti Quant API key'), then enumerates the returned fields. It clearly differentiates from siblings like list_brokers and list_account_strategies by identifying exactly which account-level data is returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the tool's role obvious: it is the way to discover linked MT5 accounts and obtain the canonical accountId. It gives downstream guidance ('pass id, not login') that helps an agent choose and use the result correctly. It does not explicitly name sibling alternatives or exclusions, but the context is otherwise clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_account_strategiesList strategies deployed on an accountA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).

Output Schema

ParametersJSON Schema
NameRequiredDescription
strategiesYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint and openWorldHint, so the description does not need to repeat safety properties. It adds useful behavioral context beyond them by clarifying that this returns only strategies deployed on the account and that accountId must be the id field, not the MT5 login. The description is consistent with the annotations and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the first sentence states what the tool does and what it returns, the second sentence prevents a common input error, and the third sentence routes to the sibling tool. Every sentence earns its place, with no filler or repetition of annotation properties.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single required parameter, an output schema, and annotations that cover the safety profile, the description provides everything an agent needs to call the tool correctly. It explains the output fields, clarifies the critical accountId semantics, and disambiguates against list_strategies. There is no meaningful gap in context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already documents the accountId parameter at 100% coverage, so the baseline is 3. The description goes further by explicitly warning that login is the MT5 account number and is not a valid accountId, and by tying accountId to the output of list_accounts. This adds practical meaning beyond the schema's simple field description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('strategies (expert advisors) currently deployed on one MT5 account'), and even enumerates the output fields (symbol, timeframe, status). It clearly distinguishes this from the sibling list_strategies by saying that list_strategies is the platform-wide catalog.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names the alternative tool for a different use case: 'For the platform-wide catalog of strategies available to deploy, use list_strategies instead.' It also clarifies the correct input source for accountId, telling the agent to take it from list_accounts rather than using the MT5 login, which prevents a common invocation error.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_brokersList brokers available to linkA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
brokersYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only and open-world behavior. The description adds meaningful context by explaining it is a catalog, not user-specific accounts, and shows how to consume the output for account linking. This goes beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: first states the main purpose, then clarifies scope, and finally gives practical usage guidance. Every sentence adds value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters, an output schema, and clear annotations, the description fully addresses the tool's behavior and use. It explains what is returned and how to apply it, making it complete for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, so the baseline per guidelines is 4. The description still implicitly covers the output usage, but since no parameters exist, no additional parameter semantics are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: listing supported brokers with their MT5 server names and account types. It also explicitly differentiates this from `list_accounts`, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear usage context: this is the platform-wide catalog for linking accounts, and explicitly contrasts with `list_accounts`. It also gives actionable guidance on using output fields (`accountTypes[].id` and `servers[]`) when linking a new account.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_dealsList deal history for an accountA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoWindow end (ISO-8601). Omit for no bound on this side.
fromNoWindow start (ISO-8601). Omit for no bound on this side.
entryNoNarrow to opening deals (`in`) or closing deals (`out`). Lowercase — the `entry` field in the response is uppercase and is not valid here. Omit for both.
limitNoDeals per page, 1 to 500. Defaults to 50. One call returns one page; it is never a total.
cursorNoThe `nextCursor` from a previous call to this tool, to retrieve the page after it. Omit for the first page. Opaque — do not construct or edit one.
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dealsYes
nextCursorYes
syncedThroughYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=true, already conveying safety and variability. The description adds valuable behavioral detail: endpoint is paginated, limit defaults to 50/max 500, one call returns one page, tool never pages on its own, cursor semantics, and case sensitivity for entry. It does not go into rate limits or error scenarios, but given annotation coverage, the description adds substantial non-redundant context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is about 150 words, well-structured: purpose first, then sibling routing, then accountId note, then pagination, then narrowing advice. Every sentence adds functional value; there is no fluff. The most critical info (what it does and when to use it) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 params, pagination, output schema exists), the description covers: what it returns, how to navigate pagination, how to narrow results, and how to identify the account correctly. It also directs users to appropriate alternatives. Output schema is present so return structure is not needed in the description. This is a complete and self-sufficient definition for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% — every parameter already has a description. The tool description reinforces and contextualizes: clarifies accountId is the id from list_accounts not login (though schema says the same), adds the 'one call returns exactly one page' nuance for limit, explains cursor as nextCursor from a previous call, and emphasizes lowercase for entry. This goes beyond mere repetition by tying parameters to the pagination behavior, though some of it mirrors schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('closed deal history of one MT5 account'), enumerates the fields returned (symbol, direction, entry kind, volume, price, realized profit, costs, time), and explicitly distinguishes from siblings list_positions, list_pending_orders, and get_account_performance. An agent can immediately grasp what this does and how it differs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names alternatives and when to use them: '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.' Also provides clear guidance on pagination (must call again with cursor) and advises narrowing (via entry and from/to) instead of paging. This is textbook usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_draft_attachmentsRead a draft's indicator sourcesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
draftIdYes
filenameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
attachmentsYes

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, and the description adds substantial behavioral detail: duplicate filenames return only the first with `notes` indicating skipped count, truncated lists are reported via `notes`, and responses can reach roughly 33,000 tokens. It also clarifies what the tool never returns, which is valuable beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: purpose, parameter behavior, budget limits, duplicate handling, response size warning, and the sibling alternative. Key operational constraints are front-loaded before the large-response warning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with two parameters, an output schema, and read-only annotations, the description covers all critical decision factors: how to select an attachment, what happens with duplicates, budget truncation, response size, and the distinction from get_draft. Nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries full parameter documentation. It defines `draftId` as the `id` field from list_drafts and explains that `filename` is an exact name used to read a single attachment or one omitted by the default call, including omitted-parameter behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read the indicator source files a draft's EA embeds via `#resource`.' It clearly differentiates from the sibling get_draft by stating 'this tool never returns' the EA's own source, so an agent can select it correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly explains when to pass `filename` versus omit it, including the exact-name matching behavior and the 64 KiB budget fallback. It also names the alternative for a related need: 'Use get_draft for the EA's own source.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_draftsList MQL5 authoring draftsA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
draftsYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark readOnlyHint, and the description adds meaningful behavior beyond that: the list carries sizes and hashes rather than bodies, and a non-null compileLogBytes is explained even when diagnosticsCount is 0. This gives the agent important interpretation context that annotations alone would not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-organized: the core action and ordering are front-loaded, followed by use cases, payload constraints, and sibling routing. Every sentence adds useful selection or interpretation detail with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with an output schema, the description fully covers purpose, usage context, response content, and alternatives. An agent has everything needed to decide when to call it and how to interpret the results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero properties, so there are no parameter meanings for the description to clarify. The description appropriately focuses on what the response contains, which is the relevant semantic information for a parameterless listing tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('List the MQL5 drafts this API key owns'), specifies ordering ('most recently updated first'), and enumerates the returned fields. It also distinguishes itself from get_draft and list_draft_attachments by explicitly stating what it does not include.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides concrete use cases: find a draftId, answer 'what am I working on' and 'which of my drafts are broken', or check if a held copy is current. It names the alternative tools for deeper content and tells the agent when to call them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_pending_ordersList pending orders on an accountA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
ordersYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=true, covering the safety profile. The description adds substantial context beyond that: the data is 'read live from the terminal' (volatility/freshness), the 'NOT been filled' scope constraint, that each order's `ticket` is the handle used to cancel it, and the crucial semantics that an `sl`, `tp`, or `priceStopLimit` of 0 means the level is unset. This materially enriches what an agent needs to interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a dense multi-sentence block, but every sentence earns its place: scope, returned fields, the exclusion of filled orders, the accountId clarification, ticket usage, and zero-value semantics. It is appropriately sized for the information it carries, though it front-loads the core purpose well in the opening clause. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema (so return values need no elaboration) and annotations covering the safety profile. The description covers what is returned, what is excluded, accountId semantics, ticket-as-cancellation-handle usage, and zero-value field meanings. For a single-parameter list tool, essentially everything an agent needs to call it correctly and interpret results is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — the schema itself already documents accountId as 'The `id` field from list_accounts. Not the `login` (MT5 account number).' The description repeats this same guidance ('accountId is the id field from list_accounts, NOT login') without adding new information. This is useful reinforcement but adds no value beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a precise resource ('pending limit and stop orders resting on one MT5 account'), and the scope ('one MT5 account', 'read live from the terminal'). It enumerates the returned fields (symbol, order type, volume, trigger price, stop loss, take profit) and explicitly distinguishes itself from list_positions by clarifying these are unfilled orders. This fully differentiates it from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names the alternative tool (list_positions) and the condition that selects it ('for filled positions currently open'). It also disambiguates the accountId parameter by warning it is the `id` field from list_accounts, NOT `login`. Both the when-to-use and the common pitfall are addressed explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_positionsList open positions on an accountA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault
accountIdYesThe `id` field from list_accounts. Not the `login` (MT5 account number).

Output Schema

ParametersJSON Schema
NameRequiredDescription
notesYes
positionsYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds valuable behavioral context: it clarifies that sl/tp=0 means no stop loss/take profit is set, and that the ticket field is the handle for closing positions. It also reiterates the accountId caveat. These details go beyond the annotation's safety profile and help the agent interpret the output correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with zero fluff. It front-loads the primary purpose, then delivers critical caveats about accountId, ticket, and sl/tp semantics. Every sentence earns its place, and the structure is highly scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (single parameter), has an output schema, and annotations covering safety. The description explains the return field semantics (sl/tp=0, ticket handle) and the accountId caveat, covering everything an agent needs to call it correctly and interpret results. No missing essential context for a read-only list operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% – the schema already describes accountId as the id field from list_accounts, not the login. The description repeats this caveat, adding no new semantic information. However, the description's explanation of output fields (ticket, sl/tp) indirectly reinforces the parameter's purpose. Baseline 3 is appropriate because the schema fully covers the parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool lists open positions on a single MT5 account, enumerates the returned fields (symbol, direction, volume, prices, SL/TP, swap, floating profit), and distinguishes it from siblings like list_pending_orders and list_deals by specifying 'open positions.' The verb and resource are explicit, and the 'read live from the terminal' phrase adds context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context (positions currently open, live from terminal) and important usage guidance (accountId is the id field, not login; ticket is the close handle). It does not explicitly exclude alternatives like list_pending_orders or list_deals, but the resource distinction is sufficiently clear. The lack of an explicit when-not statement prevents a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_strategiesList deployable strategiesA
Read-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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
strategiesYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true and openWorldHint=true, covering the safety and open-world nature of the call. The description adds useful behavioral context beyond annotations: it returns what COULD be deployed, not what is running, lists the included fields (symbols, timeframes, rating, presets), and explains id semantics. It could mention pagination or rate limits, but with zero parameters and an output schema, the burden is low.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with every clause earning its place: the core action and contents, the scope warning, and the sibling routing plus deployment hint. It is front-loaded with the most important information and contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list operation with an output schema and safety annotations, this description is complete. It explains scope, content, the key sibling distinction, and how the returned id should be used downstream. There are no material gaps for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the baseline is 4. The description still adds a meaningful semantic hint by telling agents to use `id` as `eaDefinitionId` when deploying, which helps connect this catalog to deployment even though the tool itself takes no parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List every strategy (expert advisor) available to deploy on Senti Quant.' It explicitly says this is the platform-wide catalog, distinguishing it from list_account_strategies. An agent can immediately understand exactly what the tool returns and how it differs from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states when to use this tool: to see the platform-wide catalog of deployable EAs, not what is currently running. It names the alternative, list_account_strategies, for account-specific strategies, and gives a concrete deployment hint about using `id` as `eaDefinitionId`. No ambiguity remains.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 11 tool updatesv2.9.0
    • Changedget_account_performance9 fields changed
      • removedOutput schema / properties / lifetimeIrr / properties / earliestMs / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lifetimeIrr / properties / earliestMs / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / lifetimeIrr / properties / irr / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lifetimeIrr / properties / irr / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / properties / live / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "balance": {
        -        "type": "number"
        -      },
        -      "currency": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "equity": {
        -        "type": "number"
        -      },
        -      "leverage": {
        -        "type": "number"
        -      },
        -      "margin": {
        -        "type": "number"
        -      },
        -      "marginFree": {
        -        "type": "number"
        -      },
        -      "marginLevel": {
        -        "type": "number"
        -      },
        -      "name": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "profit": {
        -        "type": "number"
        -      }
        -    },
        -    "required": [
        -      "balance",
        -      "equity",
        -      "profit",
        -      "margin",
        -      "marginFree",
        -      "marginLevel",
        -      "leverage",
        -      "currency",
        -      "name"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "balance": {
        +        "type": "number"
        +      },
        +      "currency": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "equity": {
        +        "type": "number"
        +      },
        +      "leverage": {
        +        "type": "number"
        +      },
        +      "margin": {
        +        "type": "number"
        +      },
        +      "marginFree": {
        +        "type": "number"
        +      },
        +      "marginLevel": {
        +        "type": "number"
        +      },
        +      "name": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "profit": {
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "balance",
        +      "equity",
        +      "profit",
        +      "margin",
        +      "marginFree",
        +      "marginLevel",
        +      "leverage",
        +      "currency",
        +      "name"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / portfolioReturn / properties / irr / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / portfolioReturn / properties / irr / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / portfolioReturn / properties / roi / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / portfolioReturn / properties / roi / type
        Added value: +[
        +  "number",
        +  "null"
        +]
    • Changedget_draft5 fields changed
      • removedOutput schema / properties / eaDefinitionId / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / eaDefinitionId / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / lastCompileLog / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lastCompileLog / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • changedOutput schema / properties / lastCompileStatus / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "PENDING",
        -      "SUCCESS",
        -      "FAILED"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "SUCCESS",
        +      "FAILED"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedget_performance_breakdowns4 fields changed
      • removedOutput schema / properties / perSymbol / properties / dailyDealsRows / items / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  }
        -]
      • addedOutput schema / properties / perSymbol / properties / dailyDealsRows / items / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number"
        +]
      • removedOutput schema / properties / perSymbol / properties / dailyPnlRows / items / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  }
        -]
      • addedOutput schema / properties / perSymbol / properties / dailyPnlRows / items / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number"
        +]
    • Changedlist_account_strategies4 fields changed
      • removedOutput schema / properties / strategies / items / properties / chartId / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / strategies / items / properties / chartId / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / strategies / items / properties / mt5Account / properties / label / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / strategies / items / properties / mt5Account / properties / label / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedlist_accounts13 fields changed
      • removedOutput schema / properties / accounts / items / properties / brokerAccountTypeName / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / brokerAccountTypeName / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / accounts / items / properties / label / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / label / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / accounts / items / properties / lastKnownBalance / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / lastKnownBalance / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / accounts / items / properties / lastKnownEquity / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / lastKnownEquity / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / accounts / items / properties / lastSyncAt / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / lastSyncAt / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / accounts / items / properties / server / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / accounts / items / properties / server / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • changedOutput schema / properties / accounts / items / properties / terminal / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "assignedPort": {
        -        "anyOf": [
        -          {
        -            "type": "number"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "nodeName": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "terminalStatus": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      }
        -    },
        -    "required": [
        -      "assignedPort",
        -      "terminalStatus",
        -      "nodeName"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "assignedPort": {
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "nodeName": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "terminalStatus": {
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "assignedPort",
        +      "terminalStatus",
        +      "nodeName"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
    • Changedlist_deals4 fields changed
      • removedOutput schema / properties / nextCursor / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / nextCursor / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / syncedThrough / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / syncedThrough / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedlist_draft_attachments2 fields changed
      • removedOutput schema / properties / attachments / items / properties / sourceCode / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / attachments / items / properties / sourceCode / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedlist_drafts18 fields changed
      • addedOutput schema / properties / drafts / items / properties / attachments / items / properties / sourceBytes / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / drafts / items / properties / attachments / items / properties / sourceBytes / minimum
        Added value: +-9007199254740991
      • changedOutput schema / properties / drafts / items / properties / attachments / items / properties / sourceBytes / type
        Previous value: -"number"New value: +"integer"
      • addedOutput schema / properties / drafts / items / properties / attachments / items / properties / updatedAt
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / properties / drafts / items / properties / attachments / items / required
        Previous value: -[
        -  "id",
        -  "filename",
        -  "createdAt",
        -  "sourceBytes"
        -]New value: +[
        +  "id",
        +  "filename",
        +  "sourceBytes",
        +  "createdAt",
        +  "updatedAt"
        +]
      • addedOutput schema / properties / drafts / items / properties / compileLogBytes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • addedOutput schema / properties / drafts / items / properties / diagnosticsCount / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / drafts / items / properties / diagnosticsCount / minimum
        Added value: +-9007199254740991
      • changedOutput schema / properties / drafts / items / properties / diagnosticsCount / type
        Previous value: -"number"New value: +"integer"
      • removedOutput schema / properties / drafts / items / properties / eaDefinitionId / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / drafts / items / properties / eaDefinitionId / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • changedOutput schema / properties / drafts / items / properties / lastCompileStatus / anyOf
        Previous value: -[
        -  {
        -    "enum": [
        -      "PENDING",
        -      "SUCCESS",
        -      "FAILED"
        -    ],
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "enum": [
        +      "SUCCESS",
        +      "FAILED"
        +    ],
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedOutput schema / properties / drafts / items / properties / logTruncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / drafts / items / properties / sourceBytes / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / drafts / items / properties / sourceBytes / minimum
        Added value: +-9007199254740991
      • changedOutput schema / properties / drafts / items / properties / sourceBytes / type
        Previous value: -"number"New value: +"integer"
      • addedOutput schema / properties / drafts / items / properties / sourceSha256
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / properties / drafts / items / required
        Previous value: -[
        -  "id",
        -  "name",
        -  "createdAt",
        -  "updatedAt",
        -  "lastCompileStatus",
        -  "compiledUpToDate",
        -  "eaDefinitionId",
        -  "sourceBytes",
        -  "diagnosticsCount",
        -  "attachments"
        -]New value: +[
        +  "id",
        +  "name",
        +  "sourceBytes",
        +  "sourceSha256",
        +  "createdAt",
        +  "updatedAt",
        +  "lastCompileStatus",
        +  "compileLogBytes",
        +  "logTruncated",
        +  "diagnosticsCount",
        +  "compiledUpToDate",
        +  "eaDefinitionId",
        +  "attachments"
        +]
    • Changedlist_pending_orders6 fields changed
      • removedOutput schema / properties / orders / items / properties / priceStopLimit / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / orders / items / properties / priceStopLimit / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / orders / items / properties / sl / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / orders / items / properties / sl / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / orders / items / properties / tp / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / orders / items / properties / tp / type
        Added value: +[
        +  "number",
        +  "null"
        +]
    • Changedlist_positions4 fields changed
      • removedOutput schema / properties / positions / items / properties / sl / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / positions / items / properties / sl / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / positions / items / properties / tp / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / positions / items / properties / tp / type
        Added value: +[
        +  "number",
        +  "null"
        +]
    • Changedlist_strategies4 fields changed
      • removedOutput schema / properties / strategies / items / properties / avgRating / anyOf
        Removed value: -[
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / strategies / items / properties / avgRating / type
        Added value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / properties / strategies / items / properties / description / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / strategies / items / properties / description / type
        Added value: +[
        +  "string",
        +  "null"
        +]
  2. 4 tool updatesv2.8.0
    • Addedget_authoring_conventions
    • Addedget_draft
    • Addedlist_draft_attachments
    • Addedlist_drafts
  3. 1 tool updatev2.0.1
    • Addedget_equity_timeseries
  4. 1 tool updatev1.3.0
    • Addedget_performance_breakdowns
  5. 7 tool updatesv1.2.0
    • Addedget_account_performance
    • Addedlist_account_strategies
    • Addedlist_brokers
    • Addedlist_deals
    • Addedlist_pending_orders
    • Addedlist_positions
    • Addedlist_strategies
  6. 1 tool updatev0.1.0
    • First observedlist_accounts

TDQS

A4.4/5.0

Scored across 14 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness2/5

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

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    A standalone Model Context Protocol (MCP) server that enables AI assistants to interact with the cTrader trading platform.
    14
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol (MCP) server for the Hyperliquid decentralized exchange, enabling AI assistants to perform trading operations, manage accounts, and retrieve market data.
    307 PyPI
    3
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to connect to MetaTrader 5 for trading, market data access, and account management through the Model Context Protocol.
    67 PyPI
    220
    MIT