Skip to main content
Glama
emile-fortier

paper-trader-mcp

Paper Trader MCP

A local, durable, simulation-only MCP server for recording US-equity order intents and later estimating outcomes from historical Alpaca SIP NBBO quotes. It never places live orders or Alpaca paper-broker orders. There is no order endpoint, broker SDK, generic fetch tool, trades endpoint, GTC, extended-hours, fractional-share, or partial-fill support.

Install and run

Requirements: Python 3.14, uv, and Alpaca data credentials with historical SIP access.

./setup.sh
export APCA_API_KEY_ID='...'
export APCA_API_SECRET_KEY='...'
./run.sh

The scripts are executable and run.sh uses only this project's .venv. Credentials are read from the environment (the server does not load .env). Recording, listing, and closing intents work without credentials; evaluation requires them because it reads Alpaca's quote and calendar APIs. The database defaults to ~/.local/share/paper-trader/paper-trader.sqlite3; set PAPER_TRADER_DB to override it. See .env.example for bounded quote-policy and commission options.

Defaults you may want to configure

Setting

Default

Meaning

Commission per order

$0

Applied to every simulated fill

Commission per share

$0

Applied to every simulated fill

Order latency

250 ms

Override per order with latency_ms

Quote lookback

120 s

Search window for prevailing top-of-book quote

Maximum quote age

30 s

Older quotes are unusable

Additional slippage beyond spread

$0

Buys still cross to ask; sells cross to bid

Current sell-side SEC Section 31 and FINRA TAF fees are automatic and itemized. Set the commission variables only when modeling a broker that is not commission-free. Short borrow costs, margin interest, dividends, venue fees, rebates, and taxes are not configurable or modeled.

Related MCP server: quant-research-mcp

MCP configuration

Claude Code (~/.claude.json, within the desired project entry) or Desktop / Cowork (claude_desktop_config.json) can use the same stdio configuration:

{
  "mcpServers": {
    "paper-trader": {
      "command": "/absolute/path/to/paper-trader-mcp/run.sh",
      "env": {
        "APCA_API_KEY_ID": "YOUR_DATA_KEY",
        "APCA_API_SECRET_KEY": "YOUR_DATA_SECRET"
      }
    }
  }
}

Prefer launching the client from a shell containing credentials rather than writing secrets into configuration. The five tools are paper_trade_record, paper_trade_get, paper_trade_list, paper_trade_evaluate, and paper_trade_close. Mutation calls require a caller-generated unique request_id; exact retries replay while changed input conflicts. submitted_at is accepted only with backtest=true. Evaluation without as_of explicitly selects now - 16 minutes.

Model and safety caveats

This is an intentionally conservative estimate, not an execution simulator. It crosses one complete top-of-book quote (ask to buy, bid to sell), requires the displayed size to cover the entire order, assumes zero additional slippage, and declares resting limits or insufficient depth indeterminate. There is no L2/depth. Quotes must be regular-session, fresh, complete, non-crossed, SIP-feed records on or after 2025-11-03 (Alpaca changed quote-size units then). Equal timestamps retain API ordering and raw nanosecond timestamps. Temporary SIP embargoes use pending_data; model limitations that prevent a defensible fill use the distinct terminal state indeterminate.

DAY eligibility uses Alpaca's New York calendar, including holidays and early closes. Data newer than the 15-minute entitlement plus a one-minute guard is never queried or clamped. Weekend, pre-open, and after-close marks use the most recent session. Multi-session results do not model splits, dividends, ticker changes, short borrow/availability and fees, dividends owed by shorts, halts/LULD, auctions, or quote corrections.

Accounting uses decimal text and cash-flow logic. Configured commissions apply per fill. Sell fees include FINRA's published 2025-2029 equity TAF schedule and the SEC Section 31 rate (zero through 2026-04-03; 0.00002060 thereafter in the verified 2026 period); dates outside explicit SEC ranges produce warnings. TAF is calculated at the published per-share rate without an invented penny minimum or per-fill rounding, capped per trade, and exempted when execution price is below the applicable per-share rate. Results expose commissions, SEC fees, and FINRA fees separately. Snapshots are immutable. SQLite uses WAL, foreign keys, busy timeout, explicit short transactions, and one connection per operation; network requests occur before write transactions.

The only HTTP destinations implemented are redirect-disabled GET requests to:

  • https://data.alpaca.markets/v2/stocks/quotes (always feed=sip, one symbol)

  • https://paper-api.alpaca.markets/v2/calendar

Authoritative references: Alpaca historical stock quotes, historical stock data, and calendar API.

Tests

Core tests use only the standard library and fake providers, so MCP need not be installed:

PYTHONPATH=src python3 -m unittest discover -s tests -v

No test uses credentials or network access.

License

Copyright 2026 Emile Fortier.

Licensed under the Apache License 2.0.

Available Tools

5 tools
paper_trade_closeA

Durably record a simulation-only market DAY exit intent for an open trade; never sends a live or broker-paper order and does not close immediately. Evaluate later, after the 16-minute SIP safety window, to estimate fill.

ParametersJSON Schema
NameRequiredDescriptionDefault
backtestNo
trade_idYesTrade UUID returned by paper_trade_record.
latency_msNoAssumed order-to-market latency in milliseconds; defaults to 250 ms. Combined with submitted_at (or the session open for pre-open orders) to determine execution eligibility and the stored fill time.
request_idYesCaller-generated idempotency key. Reuse only to retry the exact same call; use a new value otherwise.
submitted_atNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description properly discloses critical behavioral traits: it is simulation-only, never sends real orders, and does not close immediately. It also mentions the 16-minute SIP safety window, adding context beyond the schema. However, it does not detail behaviors for invalid parameters or duplicate requests, which are somewhat covered by schema descriptions.

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, front-loaded with the main purpose and key caveats. Every sentence adds essential information without waste, maintaining high readability and brevity.

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?

Given the existence of an output schema and sibling tools, the description covers the essential behavior and workflow. It explains the delay and estimation step but could be more explicit about how to use it in conjunction with other tools. Overall, it provides sufficient context for an agent to understand the tool's role, though not exhaustive.

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?

The schema already provides descriptions for 4 out of 5 parameters, and the tool description does not add parameter-level details. The backtest parameter lacks a schema description and is also not explained in the tool description, leaving a gap. While the description's 'simulation-only' hints at backtest usage, it does not fully compensate for the missing parameter context.

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 specific verb 'record' and resource 'simulation-only market DAY exit intent', distinguishing it from opening trades (paper_trade_record) and evaluation (paper_trade_evaluate). It also clarifies it does not send live orders or close immediately, leaving no ambiguity about the tool's function.

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 implies a clear workflow: use this to record an exit intent, then evaluate later after a 16-minute safety window. It does not explicitly name alternative tools or state when not to use it, but the context and sibling listings make the intended usage evident.

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

paper_trade_evaluateA

Evaluate a pending simulated entry/exit or mark an open position using delayed historical consolidated SIP top-of-book quotes; no order is sent. Buys use ask, sells use bid, latency and displayed size are enforced, and fees are itemized. A fill's execution time is its submitted_at plus latency (or session open); quote_as_of identifies the latest qualifying quote used at or before that instant. For entries, a separate position mark uses as_of. If as_of is omitted, it means now minus 16 minutes—not latest/live data. Read outcome_reason, state_after, next_action, and warnings; never infer a fill from an indeterminate outcome.

ParametersJSON Schema
NameRequiredDescriptionDefault
as_ofNo
trade_idYesTrade UUID returned by paper_trade_record.
request_idYesCaller-generated idempotency key. Reuse only to retry the exact same call; use a new value otherwise.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries full responsibility for behavioral disclosure. It richly details execution semantics: buys use ask, sells use bid, latency and size enforced, fees itemized, fill time calculation (submitted_at + latency or session open), quote_as_of significance, and the 16-minute historical delay when as_of is omitted. It also warns against assuming a fill from indeterminate outcomes, adding exceptional transparency.

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 five sentences, but each sentence carries critical, non-redundant information. The first sentence is front-loaded with the core purpose and scope, followed by execution details and usage cautions. There is no fluff or repetition; it is appropriately sized for the tool's complexity.

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?

Despite having an output schema (not shown), the description still guides the agent on what to inspect (outcome_reason, state_after, next_action, warnings) and how to interpret results. It covers default time behavior, fill timing, and safety caveats. For a tool with this complexity, the description is remarkably complete and leaves few unanswered questions.

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 description coverage is 67% (top-level), with as_of's description nested in anyOf. The description adds value by explaining how as_of affects fill evaluation and position marking, and reiterates the default behavior (now minus 16 minutes) clearly. It also ties trade_id to paper_trade_record and request_id to idempotency, though those are also in the schema. The added context on quote_as_of and execution time goes beyond the schema, so a 4 is warranted.

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+resource: 'Evaluate a pending simulated entry/exit or mark an open position using delayed historical consolidated SIP top-of-book quotes; no order is sent.' This clearly distinguishes it from siblings (record, get, list, close) by focusing on evaluation of hypothetical fills and position marks, and explicitly notes no real order is placed.

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 indicates when to use it (evaluate pending order or mark open position) and provides a caution about reading outcome fields and not inferring fills from indeterminate results. However, it does not explicitly name alternatives or state 'when not to use,' only implying the context. This is clear context without explicit exclusions, so a 4 is appropriate.

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

paper_trade_getA

Read one durable simulated trade with native structured intents, fills, itemized fees, raw selected quotes, and immutable evaluation snapshots. No market-data or broker call is made.

ParametersJSON Schema
NameRequiredDescriptionDefault
trade_idYesTrade UUID returned by paper_trade_record.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description takes on the burden of behavioral disclosure. It explicitly states that no market-data or broker call is made, indicating a read-only, non-side-effect operation. It also describes the return content in rich detail, helping agents understand what to expect, though it does not cover error cases or authentication requirements.

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 a single, well-structured sentence that front-loads the primary action and resource, then elaborates with meaningful content details. No words are wasted; every clause adds value, including the explicit 'No market-data or broker call is made' behavioral note. It is exemplary in its economy and clarity.

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?

For a simple read operation with one parameter and an output schema, the description is quite complete. It discloses the scope ('one'), the nature ('simulated', 'durable'), the contents, and a key behavioral guarantee (no external calls). However, it does not mention what happens if the trade_id is invalid or not found, which is a minor gap that could be inferred from the output schema. Overall, it is sufficient for an agent to invoke correctly.

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?

The input schema covers 100% of parameters and already provides a clear description for trade_id: 'Trade UUID returned by paper_trade_record.' The tool description adds no additional parameter-level semantics beyond this. Since schema coverage is high, the baseline of 3 applies, and the description does not enhance or clarify the parameter further.

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'), the resource ('one durable simulated trade'), and the specific content included (intents, fills, fees, quotes, snapshots). It also distinguishes from siblings by emphasizing 'one' trade and explicitly noting that no market-data or broker call is made, which differentiates it from potential alternatives like paper_trade_list or paper_trade_record near the same domain.

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 for when to use the tool: when a single trade's full details are needed, and explicitly notes that no external data calls are made, implying it is safe for quick lookups. However, it does not explicitly mention alternatives or exclusions (e.g., 'use paper_trade_list for multiple trades'), relying on the 'one' keyword and sibling names to convey scope distinction.

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

paper_trade_listA

List durable simulated trades, optionally filtered by state. No market-data or broker call is made.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum rows to return.
stateNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden. It explicitly states 'No market-data or broker call is made' which is a valuable behavioral disclosure about side effects and external dependencies. It does not specify pagination behavior or state-value meanings, but these are partially covered by the output schema and enum values. Overall, it provides useful transparency beyond the bare function.

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 a single 16-word sentence, front-loaded with the action and resource, with no filler words. It earns every word.

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 that can document return values, and its simple parameters (limit/state) are captured in the schema. The description adds 'durable' and 'no market-data or broker call' which gives important context about scope and side effects. It is sufficiently complete for a list operation with a small parameter set.

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?

The schema describes limit but not state. The description adds 'optionally filtered by state', clarifying the state parameter's role. However, it does not explain the meaning of each state enum value, and the schema itself lacks descriptions for those values, leaving a known gap. With 50% schema coverage, the description partially compensates but not fully.

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 uses a specific verb ('List') and identifies the resource ('durable simulated trades') and optional filter ('by state'), clearly distinguishing it from sibling tools like paper_trade_get or paper_trade_record.

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 about what the tool does (lists trade records) and notes that no market-data or broker call is made, implying it is safe and fast. However, it does not explicitly mention when to prefer this over siblings or provide exclusions, so it falls short of a 5.

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

paper_trade_recordA

Durably record a simulation-only whole-share US-equity DAY entry intent; never sends a live or broker-paper order. Without submitted_at, the server timestamps receipt. Historical submitted_at requires backtest=true. Regular hours only: pre-open DAY orders wait for the open; after-close or non-session DAY orders later expire.

ParametersJSON Schema
NameRequiredDescriptionDefault
symbolYesUppercase US equity ticker, for example AAPL or BRK.B.
backtestNo
quantityYesPositive whole-share quantity; fractional shares are unsupported.
latency_msNoAssumed order-to-market latency in milliseconds; defaults to 250 ms. Combined with submitted_at (or the session open for pre-open orders) to determine execution eligibility and the stored fill time.
order_typeYes
request_idYesCaller-generated idempotency key. Reuse only to retry the exact same call; use a new value otherwise.
limit_priceNo
submitted_atNo
position_sideYes
time_in_forceNoday

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly explains safety (no live order), durability, timing behavior (pre-open waits, after-close expires), and the submitted_at/backtest constraint. It does not mention idempotency handling or what happens on successful creation, but the output schema covers return values. The description adds valuable behavioral context beyond the schema, so it merits a high score, though it is not exhaustive, preventing a 5.

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 exceptionally concise, using only three sentences to convey the core purpose and critical behavioral constraints. It is front-loaded with the primary action and immediately distinguishes simulation from live execution. Every sentence adds unique value with no wasted words.

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?

For a tool with 10 parameters, 5 required, an output schema, and multiple conditional behaviors, the description covers the most critical operational aspects: the simulation-only nature, the DAY order semantics, regular-hours restrictions, and submitted_at handling. It does not explain idempotency details or the conditional limit_price requirements, but these are partially covered by schema descriptions. Given the complexity and existing schema support, the description is quite complete but leaves some gaps that prevent a 5.

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?

The schema description coverage is low (40% per context, though actual text has more). The description adds meaning to submitted_at and backtest ('Without submitted_at, the server timestamps receipt. Historical submitted_at requires backtest=true') and clarifies DAY as time_in_force. However, it does not explain key parameters like order_type, limit_price, or position_side, which have sparse schema descriptions. The description partially compensates for the schema gap but leaves several parameters under-explained.

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 purpose with a specific verb ('Durably record') and a precise resource ('simulation-only whole-share US-equity DAY entry intent'). It explicitly distinguishes from live/broker-paper orders and is clearly differentiated from the sibling tools (e.g., paper_trade_close for closing positions) through the term 'entry intent'.

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 for when to use the tool: it is for simulation-only entry recording, and it explicitly states 'never sends a live or broker-paper order', which guides the agent against using it for live trading. It also mentions the backtest requirement for historical submitted_at. However, it does not explicitly mention alternatives such as paper_trade_close for closing positions, so it lacks a full when-not-to-use comparison against siblings.

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

TDQS

A4.5/5.0
Disambiguation5/5

Each tool targets a distinct lifecycle action: recording entry, recording exit, evaluating, reading one, and listing. The purposes are clearly separated by the verb (record, close, evaluate, get, list) and by the descriptive text, so an agent should not confuse them.

Naming Consistency5/5

All tool names follow the same pattern: the resource prefix 'paper_trade' followed by a clear verb (_record, _get, _list, _evaluate, _close). This is a perfectly consistent verb_noun (or resource_verb) convention.

Tool Count5/5

Five tools is well-scoped for a paper trading simulator. It covers the core operations without redundancy or bloat, fitting comfortably in the ideal 3-15 range.

Completeness5/5

The tool set covers a complete lifecycle: record entry intent, evaluate fills/marks, close exits, and query individual or all trades. No obvious gaps exist for simulation-only day trading; even potential missing operations like cancel are handled by day-order expiration.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Review-only MCP server for stock, options, and crypto screening, trade planning, risk checks, backtesting, and journaling, designed to work alongside Robinhood's Trading MCP without placing orders.
    1
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server exposing a registry of paper-backed quantitative trading methods plus a deterministic, no-LLM decision helper for reproducible trading research.
    13
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A Test/Sandbox MCP server that integrates with the SnapTrade API Sandbox environment to provide portfolio oversight, market data, and trading capabilities.
  • A
    license
    C
    quality
    B
    maintenance
    Local paper-trading and market simulation MCP server for multi-account portfolios, advanced orders, options/futures, backtesting, alerts, and automation.
    60
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/emile-fortier/paper-trader-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server