# StockSharp Odysseus (nuget · StockSharp.Odysseus.Mcp)

Generate, compile, validate and backtest StockSharp trading strategies through local MCP.

- Trust score: 76/100 (medium)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- nuget · `StockSharp.Odysseus.Mcp`: 76/100 (this document), [markdown](https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp.md), [page](https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp)

## Channel facts

- Registry: `nuget`
- Package: `StockSharp.Odysseus.Mcp`
- Version: `1.0.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - No production dependencies, so there is no dependency health to assess.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Build provenance not yet verified.
  - Licence could not be checked: the licence is shipped as a file inside the package, not declared as a standard (SPDX) licence identifier, so we cannot tell whether it is OSI-approved.
  - Actively maintained (last published 26 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 71/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6939 tokens (~144/item across 48 items; 48 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 73/100
  - Stability observed for 22 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 0 of 2 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "remove_product" implies "remove" and declares no destructiveHint at all, which the MCP spec reads as destructive by default.
  - An AI judge read all 48 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the StockSharp Odysseus MCP server?

StockSharp Odysseus runs locally as a NuGet package, launched with dnx StockSharp.Odysseus.Mcp@1.0.2 --yes. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add stocksharp-odysseus -- dnx StockSharp.Odysseus.Mcp@1.0.2 --yes
```

### Cursor

```json
{
  "mcpServers": {
    "stocksharp-odysseus": {
      "command": "dnx",
      "args": [
        "StockSharp.Odysseus.Mcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "stocksharp-odysseus": {
      "command": "dnx",
      "args": [
        "StockSharp.Odysseus.Mcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add stocksharp-odysseus -- dnx StockSharp.Odysseus.Mcp@1.0.2 --yes
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "stocksharp-odysseus": {
      "type": "local",
      "command": [
        "dnx",
        "StockSharp.Odysseus.Mcp@1.0.2",
        "--yes"
      ],
      "enabled": true
    }
  }
}
```

### Hermes

```yaml
mcp_servers:
  stocksharp-odysseus:
    command: "dnx"
    args: ["StockSharp.Odysseus.Mcp@1.0.2", "--yes"]
```

### Netclaw

```json
{
  "McpServers": {
    "stocksharp-odysseus": {
      "Transport": "stdio",
      "Command": "dnx",
      "Arguments": [
        "StockSharp.Odysseus.Mcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

### Other

```json
{
  "mcpServers": {
    "stocksharp-odysseus": {
      "command": "dnx",
      "args": [
        "StockSharp.Odysseus.Mcp@1.0.2",
        "--yes"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 76, +1)

No change was recorded against any check on this day. Stability & Change Management went from 70 to 73. That category is still filling its 30-day observation window: 21 days of observed history at the previous scan, 22 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 75, +1)

No change was recorded against any check on this day. Stability & Change Management went from 60 to 63. That category is still filling its 30-day observation window: 18 days of observed history at the previous scan, 19 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-31 (score 74, +1)

No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-29 (score 73, +1)

No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-27 (score 72, +1)

No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-25 (score 71, +1)

No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-23 (score 70, +1)

No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-21 (score 69, +3)

- [functional improvement] Stability: unverified → 0.23

## MCP tools (48)

### `build_candidate` (~146 tokens)

Turn a recorded specification into a real StockSharp strategy and compile it. This is where a project starts spending its allowance, so it is worth reading analyze_market first: a hypothesis the data already contradicts costs a candidate to disprove. A specification reworded without changing what it does builds to the same code and costs nothing — the same candidate is returned. Nothing is run here; use run_backtest for that.

Input parameters:

- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.
- `specId` (string, required): Identifier of the specification to build, as returned by propose_spec.

### `get_installer_state` (~127 tokens)

Report whether this server can install StockSharp products at all: whether the installer console is where it expects it, whether this machine has a StockSharp account signed in, which product ids the operator allowed, and where products would be installed. Call this before the other product tools - installing is off by default and most machines do not have the installer on them, so being refused mid-plan is a worse way to find that out. This touches no network and installs nothing; it does briefly run the installer to read this machine's hardware id, which is the one thing it can answer offline.

### `get_candidate_source` (~102 tokens)

Read the C# a candidate was compiled from. It is an ordinary StockSharp strategy: the parameters it declares are the ones an optimiser may vary, and every rule carries the identifier it has in the specification, so the two can be read side by side. This is also the file to hand to anyone who asks what the strategy actually does.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `projectId` (string, required): Identifier of the project.

### `explain_run` (~159 tokens)

Cut a run's result apart: month by month, by the part of the session a position was opened in, by how long positions were held, and by direction. A run reports one number for a whole stretch of history, and one number cannot tell an edge that held throughout from a single fortnight that paid for everything around it - which is the common case. Read netWithoutBestMonth first: a candidate that turns negative there made its money in one stretch of the market rather than out of something repeatable. Nothing is re-run and nothing is charged, so ask freely; these are the trades the run already recorded, grouped.

Input parameters:

- `projectId` (string, required): Identifier of the project.
- `runId` (string, required): Identifier of the run.

### `get_deployment` (~209 tokens)

What a deployment has done against the broker, next to what the closed-data run said it would do. Rates are per trading day on both sides, so a deployment up for a few days can be read against a run measured over months. Watch two things above all: whether it trades at the rate it was supposed to, and whether one trade comes to what one trade came to in the backtest. A strategy that trades far less than expected is not being filled; one whose average trade is far worse is paying costs the backtest did not charge. Read 'runner' before any of the numbers: 'attached' means the figures are current, 'gone' means the process ended and left whatever it held as it stood, and 'unresponsive' means the process is alive and not answering - which is the one that may still be trading and still be holding a position.

Input parameters:

- `deploymentId` (string, required): Identifier of the deployment.
- `projectId` (string, required): Identifier of the project.

### `get_trades` (~103 tokens)

Read the individual trades of a run, in the order they closed: when each opened and closed, at what price, and what it made after costs. Use this when a metric is surprising — a high win rate with a poor result, or a profit that arrived in one week — because the trade list says which it is and a summary cannot.

Input parameters:

- `projectId` (string, required): Identifier of the project.
- `runId` (string, required): Identifier of the run.

### `get_account_state` (~174 tokens)

Read an account itself: whether it may trade, what it can buy with, everything it is holding and every order it has live. This is the broker talking, not this server - every other number about a deployment is what was recorded while something was watching, and a deployment nobody has spoken to since has been recording nothing. Pass a deploymentId to read the account that deployment's own process is trading on, which is the one holding its position; pass an empty deploymentId to read the account this server bound, which is a paper one and need not be the same. Read this after anything ends unexpectedly. It only reads; closing a position is not something this server does on your behalf.

Input parameters:

- `deploymentId` (string, required): Identifier of a deployment to read through its own runner, or empty for this server's account.

### `run_optimization` (~246 tokens)

Search the numbers this candidate declared and measure the setting that came out best. The ranges come from the specification, not from this call: each number was declared with its bounds and its step, and the search stays inside them. It runs on the development slice only — searching on validation would tune the candidate to the data meant to judge it. Every setting evaluated costs a backtest, so the whole search is charged up front and refused if the project cannot afford it. The search ranks; it does not decide: what it picks is then run and judged like anything else. Look at the spread of the results, not only at the winner — a lone peak surrounded by poor neighbours is a number that fitted this history, not an edge.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.
- `seed` (integer, required): Seed for the search, so the same search can be repeated. Any whole number.
- `symbol` (string, required): Symbol to trade. Leave empty to trade the first symbol of the dataset.

### `select_connector` (~261 tokens)

Download a connector, put it into demo mode, apply the credentials this server was started with and the settings you pass, and bind it: from then on import_history, lookup_symbols, lookup_option_contracts, deploy_candidate and get_account_state work. Two settings are reserved by this server rather than passed on - 'board' and 'optionBoard' name the markets a symbol is quoted on. Credentials are never passed here; they are read from a file the server was started with. A connector that cannot be told it is on a paper account is refused. Selecting again loads a second connector and leaves the first one loaded, so choose once per server if you can. A hosted instance refuses this, as it refuses the other two: its connector is chosen when the process starts.

Input parameters:

- `adapter` (string): Full type name of the adapter. Leave empty when the package holds exactly one.
- `packageId` (string, required): Package holding the connector, for example 'StockSharp.Binance'.
- `settings` (string): Settings as a JSON object of name and value, for example {"StockFeed":"sip"}. Leave empty for the connector's own defaults.
- `version` (string): Exact package version. Leave empty for the newest release the sources offer.

### `get_evaluation` (~66 tokens)

Read the numbers already recorded for a candidate: every run, every figure, and how many times it has been measured. Nothing is re-run and nothing is spent.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `projectId` (string, required): Identifier of the project.

### `stop_deployment` (~205 tokens)

Stop a deployment. Say what to do with any position it is holding: closing one places a trade on your behalf, and leaving one open keeps money at risk with nothing watching it. There is no safe default, which is why this asks. A stop is a decision about the position; a process that died is not, and nothing here turns one into the other - a deployment whose runner is gone is recorded as interrupted with whatever it last wrote down, and its position is left exactly as it stood. A runner whose process is alive and not answering is refused: nothing is recorded, because recording it as stopped would say something untrue about an open position. This cannot kill a process; that is a person's job at a terminal.

Input parameters:

- `closePosition` (boolean, required): True to close what it is holding, false to leave the position open at the broker.
- `deploymentId` (string, required): Identifier of the deployment.
- `projectId` (string, required): Identifier of the project.

### `evaluate_candidate` (~259 tokens)

Run a candidate six times — development, validation, validation with costs half again as high, and three consecutive walk-forward windows — and report what each one came to. Which runs those are is fixed, so the evidence cannot be chosen to suit the answer. All six fill on the bar the signal fired on; whether the result survives an entry a bar later is a separate question, asked with run_backtest under the 'entryOneBarLater' scenario. The result is statistics: profit, drawdown, trade counts, win rate, exposure, costs, concentration, and the spread between windows. It contains no verdict and no score, because deciding whether these numbers are worth trading is yours to do, not the server's. The closed part of the history is not touched here.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `parameters` (string, required): Parameter values, as 'Name=Value' separated by commas. Leave empty to use what the strategy declares.
- `projectId` (string, required): Identifier of the project.
- `symbol` (string, required): Symbol to trade. Leave empty to trade the first symbol of the dataset.

### `describe_connector` (~163 tokens)

Download a connector package and report what it is without binding it: the adapter inside it, what it is for, which credentials it takes, whether it can be proven to be on a paper account, and every setting it accepts with the values each one allows. Reading it downloads the package and builds the adapter, so a hosted instance refuses this as it refuses select_connector. Read this before select_connector: the settings it reports are exactly the ones selecting will accept.

Input parameters:

- `adapter` (string): Full type name of the adapter. Leave empty when the package holds exactly one.
- `packageId` (string, required): Package holding the connector, for example 'StockSharp.Binance'.
- `version` (string): Exact package version. Leave empty for the newest release the sources offer.

### `describe_server` (~84 tokens)

Report the server version, the mode it runs in, and whether a broker connector is bound. Call this first: half of what this server can do depends on whether a connector was chosen, and being refused mid-plan is a worse way to find that out. It also says where the deployments this server starts keep their records, which is what a later session reads them back from.

### `list_products` (~117 tokens)

List the StockSharp products the store offers, with the numeric id each one is installed by. Needs the network and a StockSharp account on this machine even though it sounds local: the installer reloads its whole product catalogue from the web on every call. The program behind this has no machine-readable output, so an entry it printed in a shape this server does not recognise comes back in 'unparsed' as raw text rather than being dropped.

Input parameters:

- `search` (string): Phrase a product name must contain. Leave empty for all of them.

### `install_product` (~157 tokens)

Download and install one StockSharp product on this machine. Takes the numeric product id list_products reports and nothing else: where it lands is derived from this server's own projects root and is not something a caller chooses. Only the product ids the operator allowed can be installed, and the refusal names the ones that can. Set reinstall true to remove an already installed copy first and put it back - the two behaviours differ enough to be asked about rather than defaulted. This downloads packages and can take many minutes; it does not start the product afterwards.

Input parameters:

- `productId` (integer, required): Numeric product id, as list_products reports it.
- `reinstall` (boolean, required): True to remove an already installed copy first, false to install alongside what is there.

### `list_deployments` (~146 tokens)

Every deployment this project has had, newest first, and every runner on this machine that no row here accounts for. Two things are reported about each: what was recorded, and what was found when the process trading it was looked for. Start here in a new session - a deployment an earlier conversation started is still running, and this is how it is found again. A row recorded as running whose runner is 'gone' belonged to a process that ended: nothing was stopped in an orderly fashion, so read the account for anything it left open and call stop_deployment to end it properly. Reading this list changes nothing.

Input parameters:

- `projectId` (string, required): Identifier of the project.

### `list_projects` (~96 tokens)

List the research projects on this server, most recently changed first, a page at a time.

Input parameters:

- `limit` (integer): How many to return at once. Zero asks for the default of 50; the most that can be asked for is 500.
- `offset` (integer): How many to skip, for reading a long list a page at a time. Zero starts at the beginning; the answer says what to pass next.

### `list_specs` (~127 tokens)

List the specifications recorded for a project, oldest first, so the history of what was tried can be read back. Answers a page at a time and says how to ask for the next.

Input parameters:

- `limit` (integer): How many to return at once. Zero asks for the default of 50; the most that can be asked for is 500.
- `offset` (integer): How many to skip, for reading a long list a page at a time. Zero starts at the beginning; the answer says what to pass next.
- `projectId` (string, required): Identifier of the project.

### `get_metrics` (~102 tokens)

Read what a run measured: the result before and after costs, the drawdown, the trade population, and how much of the result rests on a single trade. Read the net side, which is the one an account would have seen, and read the concentration beside it, because a result carried by one trade is one observation rather than an edge.

Input parameters:

- `projectId` (string, required): Identifier of the project.
- `runId` (string, required): Identifier of the run.

### `propose_spec` (~115 tokens)

Record a specification as this project's next revision. It is checked first and refused if it would not survive translation, so an invalid one never becomes part of the history. Specifications are never edited: a change is a new revision, and every candidate points at the exact words it was built from.

Input parameters:

- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.
- `spec` (string, required): The strategy specification, as a JSON document.

### `list_connectors` (~90 tokens)

Report which broker connectors this server has already downloaded, which one is bound now, where it may download from and which package names it will accept. Touches no network, but it does build one of every connector in the cache to read it, which is why a hosted instance refuses it. A connector is what turns import_history, the instrument lookups and paper trading on; everything else works without one.

### `import_history` (~195 tokens)

Download real market history for one or more symbols into the market-data storage every project shares, and make that range this project's dataset. The bars come from the bound broker, or from the StockSharp storage server the operator named when there is one. Ask for enough days that the development slice - the first three fifths - holds at least a few thousand bars, or the measurements below it rest on too little.

Input parameters:

- `days` (integer, required): How many calendar days back to download.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.
- `symbols` (string, required): Symbols to download, separated by commas, for example 'NVDA' or 'NVDA,AMD'.
- `timeFrame` (string, required): Candle length: 1m, 5m, 15m, 1h or 1d.

### `lookup_option_contracts` (~202 tokens)

List the option contracts the broker offers on an instrument, optionally within a window of expiries. An option is traded here by its full contract code, which carries the underlying, the expiry, the right and the strike in nineteen characters that have to be exactly right - so this is where one comes from. Everything else in this product treats such a code like any other symbol: the same specification, the same runs, the same measurements, with the hundred shares a contract carries taken into account when the result is worked out.

Input parameters:

- `expiringFrom` (string): Earliest expiry to include, as yyyy-MM-dd. Leave empty for no lower bound.
- `expiringTo` (string): Latest expiry to include, as yyyy-MM-dd. Leave empty for no upper bound.
- `limit` (integer): Most to return. Zero asks for fifty.
- `underlying` (string, required): Code of the instrument the contracts are written on, for example 'NVDA'.

### `list_installed_products` (~98 tokens)

List the StockSharp products already installed on this machine, with the directory each one is in. Reads the installer's own registry of installations, which covers products this server never installed. Needs the network and a StockSharp account for the same reason list_products does, and reports the same 'unparsed' lines for anything it could not read.

Input parameters:

- `search` (string): Phrase a product name must contain. Leave empty for all of them.

### `get_project_state` (~65 tokens)

Read one project: its name, status, dataset if any, and how much of its research budget is left. The budget is a server-side ceiling, so check it before planning a long search.

Input parameters:

- `projectId` (string, required): Identifier returned by create_project or list_projects.

### `list_runs` (~174 tokens)

List what this project has already run, oldest first. Read it before running anything: the allowance is finite, and a slice already measured under the same scenario will answer with the same numbers. A project may hold hundreds of runs, so this answers a page at a time and says how to ask for the next.

Input parameters:

- `candidateId` (string, required): Identifier of a candidate. Leave empty to list every run of the project.
- `limit` (integer): How many to return at once. Zero asks for the default of 50; the most that can be asked for is 500.
- `offset` (integer): How many to skip, for reading a long list a page at a time. Zero starts at the beginning; the answer says what to pass next.
- `projectId` (string, required): Identifier of the project.

### `list_completed_strategies` (~57 tokens)

List the strategies this project has been finished with, oldest first, with what each was measured on and why it was kept. Nothing is re-run and nothing is spent.

Input parameters:

- `projectId` (string, required): Identifier of the project.

### `check_determinism` (~198 tokens)

Check whether this candidate is a function of its data: the same history in, the same trades out. Two checks. Its source is read for anything that differs between runs - the machine clock, numbers nobody seeded, a string's per-process hash, the file system, the network, timing - however it is reached. And it is run twice over the development slice and the two runs compared trade by trade, which catches what the source does not show. Costs two backtests. A candidate that fails either check produces numbers that cannot be arrived at twice, so nothing measured of it means what it says.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.
- `symbol` (string, required): Symbol to run. Leave empty to run the first symbol of the dataset.

### `list_candidates` (~69 tokens)

List the candidates a project has built, oldest first, with where each has reached in its lifecycle. Read this before building another: the project's allowance is finite, and a candidate that has already been measured is a hypothesis that has already been answered.

Input parameters:

- `projectId` (string, required): Identifier of the project.

### `rename_project` (~48 tokens)

Rename a project. The previous name is kept in the audit trail.

Input parameters:

- `name` (string, required): New name for the project.
- `projectId` (string, required): Identifier of the project to rename.

### `analyze_market` (~135 tokens)

Measure what this instrument's history actually contains, before proposing anything for it: how much it moves, whether moves continue or come back, what followed the events a strategy would trade, and how the day is shaped. Read this first. A breakout hypothesis on an instrument whose breakouts led nowhere costs a generation of candidates to disprove, and the numbers here say so beforehand. Measured on the development slice only, so nothing here comes from data held back for judging.

Input parameters:

- `projectId` (string, required): Identifier of the project.
- `symbol` (string, required): Symbol to measure. Leave empty to measure the first symbol of the dataset.

### `get_dataset_report` (~83 tokens)

Report the dataset this project researches: symbols, timeframe, range, how many bars each symbol kept, and what was rejected — malformed bars, repeated moments, missing bars. Bad bars are dropped rather than repaired, so a gap here is a gap in what any result can be based on.

Input parameters:

- `projectId` (string, required): Identifier of the project whose dataset to describe.

### `remove_product` (~127 tokens)

Remove one installed StockSharp product from this machine. removeData decides what happens to that product's own application data - the settings, schemas and logs it wrote, which live outside its install directory and are not recoverable once removed. There is no safe default for that, which is why the tool asks rather than choosing. Only the product ids the operator allowed can be removed.

Input parameters:

- `productId` (integer, required): Numeric product id, as list_installed_products reports it.
- `removeData` (boolean, required): True to delete the settings, schemas and logs the product wrote. This cannot be undone.

### `create_project` (~96 tokens)

Create a research project. Pass an operationKey you generate once per intent: repeating a call with the same key returns the project the first call created instead of making a second one, which is what makes a retry after a dropped connection safe.

Input parameters:

- `name` (string, required): Name for the project, as a person would write it.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.

### `describe_split` (~113 tokens)

Describe how the history is divided in time: development (the first three fifths), validation (the next fifth) and the closed slice (the last fifth). Form hypotheses and search on development, measure on validation through run_backtest. No tool hands out the closed slice's bars; it is measured once, for the finalist only, and once spent it is spent for every project on this machine that imports the same stretch of the same instrument.

Input parameters:

- `projectId` (string, required): Identifier of the project whose split to describe.

### `get_indicator_catalog` (~57 tokens)

List every indicator a specification may refer to, with what it reads and the window lengths it accepts. This is the only vocabulary that exists: a specification naming anything else is refused before any code is generated, so read this before writing rules.

### `get_closed_data_state` (~54 tokens)

Say whether this project has spent its one measurement against the closed part of the history, and on which candidates. Where the closed part lies is in describe_split.

Input parameters:

- `projectId` (string, required): Identifier of the project.

### `run_backtest` (~352 tokens)

Run a candidate over one part of the project's history and measure what it did. Start on 'development'; 'validation' is where a candidate is checked against data it was not tuned on, so running it repeatedly while still adjusting the rules is how a validation result stops meaning anything. Costs are charged from the first run — a candidate that only works without them is not a candidate. A run that has already been done with the same candidate, data, slice and scenario is returned rather than repeated, and does not spend the allowance again.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate, as returned by build_candidate.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `parameters` (string, required): Parameter values, as 'Name=Value' separated by commas. Leave empty to use what the strategy declares.
- `projectId` (string, required): Identifier of the project.
- `scenario` (string, required): What the run is measured under. 'baseline' charges the ordinary costs and fills on the bar after the one the rule fired on. 'costsX15' charges costs half again as high, which asks whether the result…
- `slice` (string, required): Part of the history: 'development' or 'validation'.
- `symbol` (string, required): Symbol to trade. Leave empty to trade the first symbol of the dataset.

### `import_demo_dataset` (~98 tokens)

Import the bundled dataset for this project, so the whole pipeline can run without a broker account. These bars are generated, not observed: use them to prove the machinery works, never to judge whether a strategy is any good. Every report over them says so.

Input parameters:

- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project to import into.

### `get_audit_log` (~165 tokens)

Read the permanent record of a project: what happened, who caused it — user, agent or the server itself — and when. Entries are append-only and their sequence has no gaps, so a missing step is visible. The record grows with everything the project does, so this answers a page at a time and says how to ask for the next.

Input parameters:

- `limit` (integer): How many to return at once. Zero asks for the default of 50; the most that can be asked for is 500.
- `offset` (integer): How many to skip, for reading a long list a page at a time. Zero starts at the beginning; the answer says what to pass next.
- `projectId` (string, required): Identifier of the project whose record to read.

### `update_product` (~120 tokens)

Update one installed StockSharp product to the newest version the store offers. Note the side effect before calling it: the installer closes a running copy of the product first, so updating something a person has open in front of them will shut it. Set backupSettings true to copy that product's settings aside before the update. Only the product ids the operator allowed can be updated.

Input parameters:

- `backupSettings` (boolean, required): True to copy the product's settings aside before updating it.
- `productId` (integer, required): Numeric product id, as list_installed_products reports it.

### `validate_spec` (~76 tokens)

Check a specification and report everything wrong with it at once, each with the place in the document, what is wrong and what would fix it. Nothing is recorded, so use this freely while drafting. Every problem it reports would otherwise become a refusal from propose_spec.

Input parameters:

- `spec` (string, required): The strategy specification, as a JSON document.

### `run_walk_forward` (~283 tokens)

Walk this candidate's declared numbers forward over the development slice. The slice is cut into windows that step forward by the tested length: each window searches every setting the specification allows on its first stretch, takes the best, and runs it on the stretch right after, which the choice never saw. So every tested result comes from numbers chosen without it, which is the question run_optimization alone cannot answer. Every window costs a backtest per setting plus one for the test, charged up front and refused if the project cannot afford it. Read the tested results side by side: numbers that hold up window after window are a property of the instrument, numbers that change every window and only win where they were chosen are a fit to the history.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `inSampleDays` (integer, required): Days each window searches the numbers on. A whole number, at least 1.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `outOfSampleDays` (integer, required): Days each window tests the chosen numbers on, and how far each window steps forward. A whole number, at least 1.
- `projectId` (string, required): Identifier of the project.
- `symbol` (string, required): Symbol to trade. Leave empty to trade the first symbol of the dataset.

### `measure_on_closed_data` (~271 tokens)

Measure a candidate ONCE against the part of the history that has been closed all along, and report what it did there beside what it did on the data it was allowed to see. Use it on the candidate you would actually trade and on nothing else: a candidate cannot be measured here twice, and once a second candidate of the same project has been, neither result is independent of the slice any more — whoever chose the second one knew how the first went. Everything the earlier numbers are worth rests on this slice not having been touched, so spend it last. What gets measured is not yours to choose here: the instrument and the parameters come from the run validation was taken on, because measuring some other setting spends the only slice that could have said anything about the one you validated. It also asks the closed data the walk-forward question, in consecutive stretches, so that answer too comes from data nobody could have tuned to. That costs five backtests. The result is statistics and nothing else: what the gap between the open and closed numbers means is yours to read.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate to measure.
- `operationKey` (string, required): Caller-generated key identifying this request, reused on retries of the same intent.
- `projectId` (string, required): Identifier of the project.

### `deploy_candidate` (~213 tokens)

Run a candidate the closed data has already measured against the live paper account, with the numbers it was measured with and a position sized by the same rule the backtests used. This is the first thing that can contradict a backtest: a fill that never comes, a spread wider than the one that was charged, a bar that arrives late. None of it shows up in history. IMPORTANT: the deployment runs in a process of its own and keeps trading when you disconnect, when this server exits, and after the machine's session ends - until something stops it. Nothing stops it on your behalf, so whatever you start here is yours to stop with stop_deployment, and a later session can find it again with list_deployments. Every deployment this server starts trades on a paper account. One deployment per project: two strategies on one account trade against each other's positions and neither result means anything afterwards.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `projectId` (string, required): Identifier of the project.

### `lookup_symbols` (~101 tokens)

Find instruments the broker offers, by part of a code or a name. Use it before import_history rather than guessing a symbol: a code the account cannot hold is discovered here in one call, or at the end of a download that returns nothing. It reads the broker and imports nothing.

Input parameters:

- `limit` (integer): Most to return. Zero asks for fifty.
- `query` (string, required): Part of a code or a name, for example 'NVDA'.

### `complete_strategy` (~235 tokens)

Declare a strategy finished and keep it. This is the one place a conclusion is recorded, and the conclusion is yours: the server runs strategies and reports numbers, and whether these numbers are worth trading is a judgement it never makes. Call it once you have read the runs and decided. What gets written into the project folder is the generated C#, the specification it was translated from, and one metadata file holding everything the server knows — the instrument, the timeframe, the parameters it was run with, the dataset and where its bars came from, how the data was divided, every completed run with its full metrics, both measurements, and the reason you give here. Say that reason properly: it is the only part of your decision the server can keep, and in six months it is the only thing that explains why this strategy and not another. A candidate the closed data has never seen is refused.

Input parameters:

- `candidateId` (string, required): Identifier of the candidate.
- `notes` (string, required): Why you consider this strategy finished: what convinced you, and what you would still watch.
- `projectId` (string, required): Identifier of the project.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp#diagnostics

## Score history

- 2026-11-05: 76
- 2026-11-04: 75
- 2026-11-03: 75
- 2026-11-02: 75
- 2026-11-01: 74
- 2026-10-31: 74
- 2026-10-30: 73
- 2026-10-29: 73
- 2026-10-28: 72
- 2026-10-27: 72
- 2026-10-26: 71
- 2026-10-25: 71
- 2026-10-24: 70
- 2026-10-23: 70
- 2026-10-22: 69
- 2026-10-21: 69
- 2026-10-20: 66
- 2026-10-19: 66
- 2026-10-18: 66
- 2026-10-17: 66
- 2026-10-16: 66
- 2026-10-15: 66
- 2026-10-14: 66
- 2026-10-13: 36
- 2026-10-12: 36

## Common questions

### What is the StockSharp Odysseus MCP server?

StockSharp Odysseus is an MCP server listed in the public MCP registry as io.github.StockSharp/odysseus. Generate, compile, validate and backtest StockSharp trading strategies through local MCP. This page covers its NuGet package (StockSharp.Odysseus.Mcp).

### Is the StockSharp Odysseus MCP server safe to use?

StockSharp Odysseus scores 76 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. It declares no install or post-install scripts. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the StockSharp Odysseus MCP server expose?

StockSharp Odysseus exposes 48 tools: build_candidate, get_installer_state, get_candidate_source, explain_run, get_deployment, and 43 more. Their descriptions and schemas cost roughly 6,939 tokens of context every time the server is loaded.

### Is the StockSharp Odysseus MCP server still maintained?

StockSharp Odysseus is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What did VerifyMCP test on the StockSharp Odysseus MCP server?

VerifyMCP ran 14 checks on StockSharp Odysseus, covering Malware scan, Known CVEs, Install scripts, Dependency health and 10 more. 2 items could not be completed, a gap on our side rather than a finding about StockSharp Odysseus: Provenance and License. Endpoint Security and Transport & Reachability do not apply to a NuGet package, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.

## Links

- NuGet package: https://www.nuget.org/packages/StockSharp.Odysseus.Mcp
- Socket report: https://socket.dev/nuget/package/StockSharp.Odysseus.Mcp
- Repository: https://github.com/StockSharp/Odysseus
- Changelog RSS feed: https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp/changelog.json
- Trust report (JSON): https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp.json
- HTML version of this page: https://verifymcp.io/servers/stocksharp-odysseus/stocksharp-odysseus-mcp
