Skip to main content
Glama
mDemarco12

bull-milker-mcp

by mDemarco12

bull-milker-mcp

A read-only MCP server exposing moomoo market data, the Bull Milker screener, and portfolio risk/exposure tools to Claude Desktop.

What it exposes

Tool

What it does

check_health

Confirms OpenD is reachable

get_account_positions

Current paper/live positions

get_market_snapshot

Live price/volume/change for given codes

run_bull_milker_screener

Screener: turnover, volume, and % change filters, configurable via .env

run_bull_milker_extended_screener

Bull Milker + PE ratio and short-interest enrichment (see caveats below)

get_portfolio_sector_exposure

Deterministic concentration calc across your current positions, grouped by real moomoo industry-plate sectors

get_sector_technical_outlook_tool

RSI/SMA technical signals aggregated per sector, holdings-weighted (see below)

get_quarterly_transaction_summary_tool

Trade counts by quarter (Q126 format), no cost-basis matching

get_quarterly_tax_summary_tool

Realized gain/loss by quarter, FIFO cost basis, LIVE account only (opt-in)

Related MCP server: IB Async MCP Server

Important caveats — read before wiring up the "suggest investments" agent

  • Sector grouping: get_portfolio_sector_exposure and get_sector_technical_outlook_tool group holdings by moomoo's real industry-type plates (via get_owner_plate), not GICS. Concept/thematic plates are excluded. A symbol with no industry-plate match is grouped under an explicitly-labeled "Unknown (no industry plate mapping)" bucket — never silently folded into a real sector.

  • Sector technical signals are a proxy, not an index quote: get_sector_technical_outlook_tool's weighted_rsi_14 and SMA figures are a market-value-weighted average of each holding's own locally computed RSI/SMA, not a real sector-index feed — moomoo doesn't expose one through this API. Daily kline history is cached under data/kline_cache/ because moomoo's historical-kline quota takes 7 days to release per symbol; don't delete that cache casually or you'll burn quota re-fetching it.

  • PE ratio: available directly from moomoo (pe_ttm_ratio on snapshots, or as a FinancialFilter in the screener). Included and working.

  • Short volume / short interest: moomoo's snapshot endpoint exposes short_sell_rate and short_available_volume per symbol. These are fetched as an enrichment step after the screener runs (not filterable inside get_stock_filter itself, since it's not one of the screenable StockField options as far as the public API docs show).

  • Institutional investment %: moomoo's app has an "Institutional Tracker" based on 13F filings, but as of writing this doesn't appear to be exposed through the public OpenAPI — 13F data is also inherently quarterly and reported with up to a 45-day lag, so even where available it's a lagging indicator, not real-time. indicators.py has a stubbed get_institutional_ownership() that raises NotImplementedError with a clear TODO — plug in a third-party data provider there (e.g. a paid fundamentals API) if you want this metric. Don't let the agent silently treat a missing/stubbed value as "0% institutional ownership" — the tool returns None explicitly so that distinction is visible upstream.

Setup

./setup.sh

Creates the venv, installs dependencies, copies .env.example to .env if missing, and prints the exact mcpServers block to paste into Claude Desktop's config. Safe to re-run — skips steps already done. Edit .env afterward to fill in your values (e.g. MOOMOO_SECURITY_FIRM).

Manual equivalent, if you'd rather not run the script:

python -m venv .venv
source .venv/bin/activate      # Windows: .venv\Scripts\activate
pip install -e .
cp .env.example .env           # fill in values

Requires moomoo OpenD running and logged in (see the main Bull Milker project's opend/README.md if you have it, or https://openapi.moomoo.com/moomoo-api-doc/en/intro/). The server now checks OpenD is reachable at startup and exits with a clear message if not, rather than failing opaquely on the first tool call.

Developing in VS Code

  • Open this folder in VS Code.

  • .vscode/launch.json is set up to run src/bull_milker_mcp/server.py directly under the debugger — set breakpoints in any tool function and step through a call.

  • For a protocol-level test without any client, use the MCP Inspector:

    npx @modelcontextprotocol/inspector python -m bull_milker_mcp.server
  • Run python -m bull_milker_mcp.screener for a quick manual smoke test of the screener logic alone, without going through MCP at all.

Wiring into Claude Desktop

Copy the relevant block from claude_desktop_config.example.json into your Claude Desktop MCP config, updating the cwd path. Restart Claude Desktop, then confirm the tools show up (Claude Desktop's MCP tool picker, or just ask "what tools do you have from bull-milker-mcp?").

Shutting down

./stop.sh

Stops the bull_milker_mcp server process and moomoo OpenD, so neither keeps running (or holding a live account connection) between sessions. Quit Claude Desktop first — it respawns the MCP server on demand, so killing it while Claude Desktop is still open just makes tool calls fail until the next call or a Desktop restart.

Suggested build/test order

  1. check_health — confirm the OpenD round trip works at all.

  2. get_market_snapshot — one real symbol, verify data shape.

  3. get_account_positions — paper account.

  4. run_bull_milker_screener — verify against the existing Bull Milker project's results.

  5. get_portfolio_sector_exposure — test with a small known portfolio, check the math by hand.

  6. run_bull_milker_extended_screener — add PE + short interest enrichment.

  7. get_sector_technical_outlook_tool — first call will be slow (fetches ~380 days of daily klines per holding); re-run it and confirm the second call is fast, using the cache instead of re-fetching.

  8. Wire into Claude Desktop, test each tool interactively in chat.

  9. Only then: build the standing prompt and set up a Cowork scheduled task.

Safety

See SAFETY.md for the full threat model and user stories. In short: this server is read-only by design and by enforcement — guardrails.py checks for trade-execution symbols at startup, and tests/test_no_trading_capability.py fails the build if any creep in. Every tool call is logged to data/audit_log.jsonl (see audit.py).

Before adding any new tool, ask: does this need to place, modify, or cancel an order? If yes, stop and read SAFETY.md US-2 first.

Run the safety test any time: pytest tests/test_no_trading_capability.py -v

MCP SDK version note

This project targets mcp v2 (MCPServer, not the older FastMCP class — the official SDK renamed it in its July 2026 v2 release; v1 is now maintenance-only). If you're following older MCP tutorials that show from mcp.server.fastmcp import FastMCP, that's the v1 API — this repo uses from mcp.server import MCPServer instead. If your installed mcp resolves to <2.0, either upgrade (pip install "mcp[cli]>=2.0") or pin your own project to mcp>=1.28,<2 and revert this file's import — don't mix the two.

Tax reporting (live account)

get_quarterly_tax_summary computes realized capital gains/losses by quarter (Q126 format) using FIFO cost-basis matching against your LIVE account's deal history — genuinely different from get_quarterly_transaction_summary, which just counts trades on whichever account (paper by default) and does no cost-basis matching at all.

This is gated behind TAX_AUDIT_ENABLE_LIVE=true in .env — it's off by default and raises a clear PermissionError if you call it without enabling it first. See SAFETY.md US-8/US-9/US-10 before turning this on.

Not tax advice. FIFO cost basis, no wash-sale handling, no corporate actions, no dividends. Reconcile against your broker's 1099-B and talk to an actual tax professional before filing anything.

Available Tools

8 tools
check_healthA

Check whether moomoo OpenD is reachable and logged in. Read-only — cannot place, modify, or cancel orders.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It explicitly states the tool is read-only and cannot place, modify, or cancel orders, which is valuable behavioral context. It does not detail return format or potential error states, but for a health check the disclosure is reasonably complete.

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 and every word earns its place. It conveys the purpose, scope, and a key limitation without any fluff 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?

Given the simplicity of a health check and the lack of output schema, the description covers the essential purpose and limitations. It could be more explicit about the return value (e.g., status object or boolean), but it is adequate for a tool of this complexity.

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 tool has zero parameters, so the schema provides no complexity. The description adds no parameter details, but none are needed; the baseline for zero parameters is 4.

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 'Check' and identifies the resource 'moomoo OpenD' plus the state being verified ('reachable and logged in'). It also distinguishes itself from siblings by clarifying it is read-only and cannot place, modify, or cancel orders, which is a clear differentiator.

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

Usage Guidelines3/5

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

The usage context is implied: one would call this to verify connectivity and login status before performing other operations. However, there is no explicit statement about when to use it versus alternatives, nor any mention of exclusions or prerequisites.

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

get_account_positionsA

Get current positions in the connected moomoo account. Read-only — cannot place, modify, or cancel orders. Does not by itself confirm whether the connected account is paper or live; cross-check with check_health if that matters for the current task.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

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

Despite having no annotations, the description is highly transparent about the tool's read-only nature and its inability to place orders. It also discloses a critical limitation regarding paper vs. live account confirmation, which goes beyond what annotations would typically cover.

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 efficient sentences, with the purpose front-loaded and no redundant wording. Every sentence adds value.

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 no-parameter read tool, the description covers purpose, safety profile, and a caveat. The output schema presumably documents the return structure, so the description does not need to duplicate that.

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 zero parameters in the schema, so the description has no parameter-specific information to add. The baseline for 0-param tools is 4, and nothing in the description undermines that.

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

Purpose4/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 with a specific verb and resource ('Get current positions in the connected moomoo account'). While it does not explicitly distinguish from sibling tools, the scope is unambiguous and the read-only caveat adds clarity.

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: it is for reading positions and explicitly cautions that it cannot place/modify/cancel orders. It also directs the user to cross-check with check_health when paper vs. live status matters, which is an explicit alternative.

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

get_market_snapshotA

Get current price, volume, % change, and other live data for one or more stock codes (e.g. 'US.AAPL', 'US.TSLA'). Read-only — cannot place, modify, or cancel orders.

ParametersJSON Schema
NameRequiredDescriptionDefault
codesYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/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 explicitly states 'Read-only — cannot place, modify, or cancel orders,' which is a key safety-relevant trait. It also discloses that it handles multiple codes. Further details about rate limits or auth are absent, but for a simple read-only snapshot, this is sufficient.

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 core purpose, and every word adds value. The safety note is concise yet important. Zero fluff.

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 tool with one parameter and an output schema, the description covers purpose, parameter format, and read-only behavior. No critical operational gaps. The output schema likely documents return fields, so omitting them here is appropriate.

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%, but the description compensates by explaining the 'codes' parameter: it takes one or more stock codes, with concrete examples like 'US.AAPL' and 'US.TSLA'. This adds meaning beyond the bare schema, though it does not specify all accepted formats or limitations.

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 fetches current price, volume, % change, and other live data for stock codes, with specific examples. The verb 'get' and resource 'market snapshot' are specific, and the scope (one or more codes) distinguishes it from siblings like portfolio exposure or screeners.

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 implicitly defines when to use the tool: whenever live market data for specific stock codes is needed. It provides example code formats, making the intended use clear. It does not explicitly name alternative tools for exclusion, but sibling context makes the differentiation obvious.

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

get_portfolio_sector_exposureA

Compute sector/symbol concentration for the current portfolio. Returns total market value, breakdown by sector and symbol, and a list of concentration_flags for any position exceeding a 25% threshold. This is a deterministic calculation, not a model estimate. Read-only.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses read-only behavior, deterministic calculation, and detailed output structure (total market value, sector/symbol breakdown, concentration_flags at 25%). This provides meaningful behavioral context beyond a bare tool name.

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, front-loaded with the action verb, and every sentence adds distinct information: computation purpose, return contents, and behavioral traits. No wasted words.

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 no-parameter, read-only analytical tool, the description specifies the threshold, the output components, and the computational nature. It is complete enough to invoke correctly without additional 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 has zero parameters and coverage is 100%, so the baseline is 4. The description adds value by explaining what the zero-argument call returns, which is sufficient for invocation.

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 ('Compute') and identifies a clear resource ('sector/symbol concentration for the current portfolio'), which distinguishes it from sibling tools like get_account_positions and get_market_snapshot.

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 context is clear that this tool is for concentration analytics on the current portfolio, but it does not explicitly name alternatives or state when not to use it. The 'deterministic calculation, not a model estimate' note adds useful selection context.

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

get_quarterly_tax_summary_toolA

Realized capital gain/loss by quarter (Q126 format), split into short-term and long-term, using FIFO cost-basis matching against your LIVE trading account's deal history.

IMPORTANT — LIVE ACCOUNT, NOT TAX ADVICE:

  • Reads your real account's historical deals. Read-only — cannot place, modify, or cancel orders. Requires TAX_AUDIT_ENABLE_LIVE=true in the server's .env; if that's not set, this raises a clear error rather than silently failing or falling back to paper data.

  • Cost basis uses FIFO (IRS default absent another election). If your broker uses average-cost or specific-lot-ID, these figures won't match your official 1099-B exactly.

  • Does not account for wash sales, dividends, or corporate actions (splits/mergers) affecting cost basis.

  • Present any numbers from this tool as a planning estimate to reconcile against the broker's 1099-B, never as a final tax figure.

start/end are 'YYYY-MM-DD' strings — for a full tax year, pass an explicit start (e.g. start='2026-01-01'), since the ~90-day default lookback will otherwise silently miss earlier quarters.

ParametersJSON Schema
NameRequiredDescriptionDefault
endNo
startNo

TDQS

A5/5.0
Behavior5/5

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

With no annotations, the description fully carries the transparency burden. It discloses that the tool is read-only ('cannot place, modify, or cancel orders'), requires a specific environment variable, raises errors rather than silently failing, uses FIFO cost-basis, and does not account for wash sales, dividends, or corporate actions. It also clearly labels outputs as estimates, not final tax advice. This is comprehensive behavioral disclosure.

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?

Although the description is relatively long, every sentence serves a purpose: the opening line summarizes functionality, the IMPORTANT section groups safety and limitation warnings, and the parameter note at the end is practical. The structured use of bullet points and bold headings makes it easy for an agent to parse. No filler is present.

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 complexity of a tax-related tool with no annotations, no output schema, and two flexible parameters, the description covers all necessary aspects: what it computes, its data source, prerequisites, limitations, and parameter usage. It appropriately omits return-value details since no output schema exists, but the description still gives enough information for the agent to understand the tool's behavior and 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 description coverage is 0%, so the description compensates fully. It explains that `start` and `end` are 'YYYY-MM-DD' strings and warns about the ~90-day default lookback, with an explicit example for a full tax year. This adds meaningful semantics beyond the bare schema, which only shows nullable string defaults. It even clarifies the consequence of omitting `start`, which is crucial for correct invocation.

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: 'Realized capital gain/loss by quarter (Q126 format), split into short-term and long-term, using FIFO cost-basis matching against your LIVE trading account's deal history.' This specifies the exact verb (get/realized), resource (capital gain/loss), and scope (LIVE trading account, FIFO). It differentiates from siblings like `get_quarterly_transaction_summary_tool` by focusing on tax-specific figures rather than generic transactions.

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 when-to-use guidance: it is for planning estimates only and warns against treating it as final tax figures, recommending reconciliation with the broker's 1099-B. It also explains prerequisites (TAX_AUDIT_ENABLE_LIVE=true) and gives concrete advice on date handling (pass an explicit start for a full tax year). These guidelines help the agent decide when to invoke this tool over alternatives.

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

get_quarterly_transaction_summary_toolA

Compiles filled trades into quarterly buckets labeled Q126, Q226, Q326, Q426, etc. (Q<2-digit year>). Each quarter includes trade count, buy/sell split, gross notional traded, and symbols traded. No cost-basis matching — for realized gains/losses use get_quarterly_tax_summary instead.

start/end are 'YYYY-MM-DD' strings. If start is omitted, moomoo's default lookback (~90 days) applies and older quarters will be incomplete — the response includes a '_lookback_warning' field in that case. Read-only, works on paper trading (defaults to SIMULATE).

ParametersJSON Schema
NameRequiredDescriptionDefault
endNo
startNo

TDQS

A4.6/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 and does well: it discloses read-only nature, paper trading default (SIMULATE), and the _lookback_warning field when start is omitted. It does not fully specify the return structure (e.g., exact fields or error handling), but adds substantial behavioral context beyond the 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?

The description is two short paragraphs with no fluff. The first sentence states the core purpose, the second handles alternatives, and the third covers parameters and warnings. Every sentence earns its place, and it is front-loaded with the most important information.

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 2 optional parameters and no output schema, this description covers purpose, usage, parameter semantics, operational context (read-only, paper trading), and a returning warning field. It could mention the exact response format (e.g., a list of quarter objects) but the content is sufficiently complete for an AI agent to select and 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 description coverage is 0%, so the description must compensate. It explains start/end are 'YYYY-MM-DD' strings and details the consequence of omitting start (default lookback and warning). It doesn't explicitly explain what happens if end is omitted, but the provided format and behavior for start add significant meaning 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 tool compiles filled trades into quarterly buckets labeled Q126, etc., including trade count, buy/sell split, gross notional, and symbols. It also distinguishes itself from get_quarterly_tax_summary_tool by explicitly noting it does no cost-basis matching, a clear differentiator.

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 directs users to use get_quarterly_tax_summary_tool for realized gains/losses instead, and explains the behavior when start is omitted (default ~90-day lookback). This provides clear when-to-use and when-not-to-use guidance.

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

run_bull_milker_extended_screenerA

Bull Milker screener plus PE ratio filtering and short-interest enrichment (short_sell_rate, short_available_volume) per result.

Each result includes an institutional_pct field that is always None — moomoo's public OpenAPI does not expose institutional ownership data. Treat None as "unknown, not available," never as "0%." Read-only — returns candidates for you to evaluate, never places any order.

ParametersJSON Schema
NameRequiredDescriptionDefault
marketNoUS
pe_maxNo
pe_minNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior5/5

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

It discloses that institutional_pct is always None due to moomoo's API limitations, instructs to treat None as unknown, and explicitly states the tool is read-only and never places orders. This goes beyond the absent annotations and covers the tool's safety profile.

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 3 sentences, front-loaded with the tool's purpose, then adds critical behavioral details. 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?

The description covers the key behavioral caveat (institutional_pct always None) and read-only nature, and the output schema exists to document returns. However, it doesn't explain the base Bull Milker criteria or how the PE bounds interact, so some context is missing.

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 description mentions PE ratio filtering, which gives meaning to pe_min and pe_max, but does not describe the market parameter or the interaction of pe_min and pe_max. With 0% schema coverage, the description only partially compensates.

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 runs a 'Bull Milker screener' with additional PE ratio filtering and short-interest enrichment, and the name 'extended' differentiates it from the sibling run_bull_milker_screener.

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

Usage Guidelines3/5

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

The description implies usage for screening with PE and short-interest needs, but does not explicitly state when to prefer this over run_bull_milker_screener or other screeners, nor any exclusions.

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

run_bull_milker_screenerA

Run the Bull Milker screener: turnover ratio, volume, and % change filters. Defaults are turnover 2-10%, volume 500k-5M, change 1-8% — override any bound to widen or narrow the scan. market is 'US', 'HK', 'SH', or 'SZ'. Read-only — returns candidates for you to evaluate, never places any order.

ParametersJSON Schema
NameRequiredDescriptionDefault
marketNoUS
change_maxNo
change_minNo
volume_maxNo
volume_minNo
turnover_maxNo
turnover_minNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/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 'Read-only — returns candidates for you to evaluate, never places any order,' which is a crucial behavioral disclosure. It also explains the effect of overriding bounds. It does not mention rate limits or data freshness, but for a screening tool the key behavior is well covered.

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 four sentences, each serving a distinct purpose: purpose, defaults/overrides, market values, and safety guarantee. It is front-loaded with the main action and contains 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?

Given the 7 parameters, lack of annotations, and presence of an output schema, the description provides enough context for an agent to select and invoke the tool correctly. It covers defaults, market values, and read-only behavior. It does not mention the relationship to the extended screener or any limitations, but the output schema presumably covers return values, making the description reasonably complete.

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 0%, so the description must compensate. It does so effectively by naming the three filter dimensions (turnover, volume, % change) and providing default values with units (2-10%, 500k-5M, 1-8%). It also explains that any bound can be overridden and gives valid market values. This meaningfully adds to the bare schema, though it does not map each parameter name explicitly.

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

Purpose4/5

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

The description clearly states the tool runs a screener with turnover, volume, and % change filters. It is specific about the resource (Bull Milker screener) and action (run), but does not explicitly distinguish itself from the sibling run_bull_milker_extended_screener, so it lacks full sibling differentiation.

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

Usage Guidelines3/5

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

The description gives clear context on how to use the tool: it provides default filter ranges and explains that any bound can be overridden to widen or narrow the scan. It also lists allowed market values. However, it does not mention when to use this tool versus the extended screener or other alternatives, so usage guidance is implied rather than explicit.

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

TDQS

A4.3/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: health check, market snapshot, account positions, portfolio exposure, two screeners (basic vs extended), and two quarterly summaries (transactions vs tax). The screeners and summaries are differentiated by their specific scope and outputs, so an agent should have no trouble selecting the right tool.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern with lowercase and underscores (check_, get_, run_). However, the two quarterly summary tools end with '_tool', which breaks the pattern slightly, and the use of 'run_' for screeners versus 'get_' for others is a minor deviation. Overall, the naming is predictable and readable.

Tool Count5/5

With 8 tools, the server is well-scoped for its apparent purpose of trading analysis and portfolio monitoring. Each tool serves a distinct function without redundancy, and the count falls comfortably within the typical range for a focused MCP server.

Completeness4/5

The server covers the core workflows: health check, market data, position reading, portfolio concentration, screening (basic and advanced), and quarterly reporting. Minor gaps exist, such as no historical price data or individual order lookup, but these are not critical given the server's explicit read-only and analysis-oriented focus. The tax summary's caveats are well-documented, and the presence of both screeners adds flexibility.

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

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to access real-time market data, manage Moomoo trading accounts, and execute trades via the Moomoo platform.
    29
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables read-only access to Interactive Brokers data including contracts, market data, news, fundamentals, and portfolio/account information for LLM workflows and autonomous agents.
    17
    BSD 3-Clause
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to access stock prices, financial statements, earnings call transcripts, and fundamental data for 60,000+ public companies via 25 read-only tools.
    25
    2
    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/mDemarco12/bull-milker-mcp'

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