扩展指标
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
# MCP Server
|
||||
|
||||
ferro-ta ships an optional MCP (Model Context Protocol) server built on the
|
||||
official Python SDK's FastMCP layer. The server now exposes the broad public
|
||||
ferro-ta callable surface instead of a tiny hand-picked subset.
|
||||
|
||||
That means MCP clients can use:
|
||||
|
||||
- Exact top-level ferro-ta exports such as `SMA`, `RSI`, `MACD`, `about`,
|
||||
`methods`, `info`, `benchmark`, and `traced`
|
||||
- Non-top-level public tools such as `compute_indicator`, `run_backtest`,
|
||||
`check_cross`, `aggregate_ticks`, `TickAggregator`, and `AlertManager`
|
||||
- Legacy lowercase convenience aliases: `sma`, `ema`, `rsi`, `macd`,
|
||||
and `backtest`
|
||||
- Generic instance tools for stateful classes and stored callables:
|
||||
`list_instances`, `describe_instance`, `call_instance_method`,
|
||||
`call_stored_callable`, and `delete_instance`
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Install the optional MCP extra:
|
||||
|
||||
```bash
|
||||
pip install "ferro-ta[mcp]"
|
||||
```
|
||||
|
||||
If you are working from this repository, you can install the same extra into
|
||||
the project environment with:
|
||||
|
||||
```bash
|
||||
uv sync --extra mcp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running the server
|
||||
|
||||
Run the server over stdio:
|
||||
|
||||
```bash
|
||||
python -m ferro_ta.mcp
|
||||
```
|
||||
|
||||
The command exits immediately with an install hint if the optional `mcp`
|
||||
dependency is missing.
|
||||
|
||||
---
|
||||
|
||||
## Connect in Cursor
|
||||
|
||||
Add the server to Cursor's MCP settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"ferro-ta": {
|
||||
"command": "python",
|
||||
"args": ["-m", "ferro_ta.mcp"],
|
||||
"description": "ferro-ta technical analysis tools"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can place this in your user settings JSON or in a workspace-level
|
||||
`.cursor/mcp.json`.
|
||||
|
||||
---
|
||||
|
||||
## Tool naming
|
||||
|
||||
The MCP server prefers the real ferro-ta API names.
|
||||
|
||||
- Use exact public names when possible, for example `SMA`, `MACD`,
|
||||
`compute_indicator`, `trade_stats`, `TickAggregator`, or `AlertManager`
|
||||
- Use the legacy lowercase aliases only when you want the old MCP-friendly
|
||||
shortcuts and result shapes
|
||||
- Use `about`, `methods`, `indicators`, and `info` to discover what is
|
||||
available from inside an MCP client
|
||||
|
||||
---
|
||||
|
||||
## Stateful classes and object references
|
||||
|
||||
Class tools return stored object references instead of plain text placeholders.
|
||||
For example, calling `TickAggregator` or `AlertManager` returns a payload like:
|
||||
|
||||
```json
|
||||
{
|
||||
"instance_id": "tickaggregator-0001",
|
||||
"type": "ferro_ta.data.aggregation.TickAggregator",
|
||||
"repr": "TickAggregator(rule='tick:2')"
|
||||
}
|
||||
```
|
||||
|
||||
Use that `instance_id` with:
|
||||
|
||||
- `describe_instance` to inspect the stored object and list public methods
|
||||
- `call_instance_method` to call methods like `aggregate`, `update`,
|
||||
`run_backtest`, or `to_dict`
|
||||
- `delete_instance` to remove stored objects when you are done
|
||||
|
||||
If a tool returns a stored callable, use `call_stored_callable`.
|
||||
|
||||
---
|
||||
|
||||
## Callable references
|
||||
|
||||
Some ferro-ta APIs accept other callables, for example `benchmark`,
|
||||
`log_call`, `traced`, or `multi_timeframe(indicator=...)`.
|
||||
|
||||
Pass public ferro-ta callables using:
|
||||
|
||||
```json
|
||||
{"callable": "SMA"}
|
||||
```
|
||||
|
||||
Pass stored objects using:
|
||||
|
||||
```json
|
||||
{"instance_id": "function-0001"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Example prompts
|
||||
|
||||
Once connected, you can ask an MCP-compatible client things like:
|
||||
|
||||
> "Run `SMA` with `close=[100, 101, 102, 103, 104]` and `timeperiod=3`."
|
||||
|
||||
> "Use `compute_indicator` to calculate `MACD` for this close series."
|
||||
|
||||
> "Call `about` and summarize the current ferro-ta API surface."
|
||||
|
||||
> "Create a `TickAggregator` with `rule='tick:50'`, aggregate this tick data,
|
||||
> then delete the instance."
|
||||
|
||||
> "Benchmark `SMA` over this price series using a callable reference."
|
||||
|
||||
---
|
||||
|
||||
## Programmatic use
|
||||
|
||||
Use the server entrypoint:
|
||||
|
||||
```python
|
||||
from ferro_ta.mcp import create_server
|
||||
|
||||
server = create_server()
|
||||
# server.run(transport="stdio")
|
||||
```
|
||||
|
||||
Or call the handlers directly without starting the server:
|
||||
|
||||
```python
|
||||
from ferro_ta.mcp import handle_call_tool, handle_list_tools
|
||||
import json
|
||||
|
||||
tools = handle_list_tools()
|
||||
print(len(tools["tools"]))
|
||||
|
||||
close = [100, 101, 102, 103, 104]
|
||||
result = handle_call_tool("SMA", {"close": close, "timeperiod": 3})
|
||||
print(json.loads(result["content"][0]["text"]))
|
||||
|
||||
aggregator = json.loads(
|
||||
handle_call_tool("TickAggregator", {"rule": "tick:2"})["content"][0]["text"]
|
||||
)
|
||||
bars = handle_call_tool(
|
||||
"call_instance_method",
|
||||
{
|
||||
"instance_id": aggregator["instance_id"],
|
||||
"method": "aggregate",
|
||||
"args": [{"price": [1, 2, 3, 4], "size": [1, 1, 1, 1]}],
|
||||
},
|
||||
)
|
||||
print(json.loads(bars["content"][0]["text"]))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See also
|
||||
|
||||
- `python -m ferro_ta.mcp` - stdio MCP entrypoint
|
||||
- `ferro_ta.mcp.create_server()` - FastMCP server factory
|
||||
- `ferro_ta.tools.api_info` - API discovery helpers used by the MCP catalog
|
||||
- `ferro_ta.tools` - stable wrappers such as `compute_indicator`
|
||||
- `docs/agentic.md` - workflow and agent integration notes
|
||||
Reference in New Issue
Block a user