수정본

This commit is contained in:
2026-02-22 17:23:20 +09:00
parent b147498c31
commit 32e2263f0a
109 changed files with 13979 additions and 4580 deletions

178
mcp-server/stdio_server.py Executable file
View File

@@ -0,0 +1,178 @@
#!/usr/bin/env python3
"""
MCP Server with stdio transport for Claude CLI
This server provides stock trading tools via Model Context Protocol
using stdio transport for direct integration with Claude CLI.
"""
import asyncio
import sys
from typing import Any
import httpx
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
# Import configuration
from config import settings
from utils import _dumps
# Initialize MCP Server
app = Server("auto-stock-mcp")
# Backend API base URL
BACKEND_URL = "http://localhost:8000/api/v1"
@app.list_tools()
async def list_tools() -> list[Tool]:
"""List available tools"""
return [
Tool(
name="get_portfolio",
description="Get current portfolio information including holdings and balance",
inputSchema={
"type": "object",
"properties": {},
"required": []
}
),
Tool(
name="get_market_data",
description="Get real-time market data for a specific stock",
inputSchema={
"type": "object",
"properties": {
"stock_code": {
"type": "string",
"description": "Stock code (e.g., '005930' for Samsung)"
}
},
"required": ["stock_code"]
}
),
Tool(
name="get_recommendations",
description="Get AI-generated stock recommendations based on technical analysis",
inputSchema={
"type": "object",
"properties": {},
"required": []
}
),
Tool(
name="get_trade_history",
description="Get recent trade history",
inputSchema={
"type": "object",
"properties": {
"limit": {
"type": "number",
"description": "Number of trades to return (default: 20)"
}
},
"required": []
}
),
Tool(
name="analyze_stock",
description="Perform detailed technical analysis on a stock",
inputSchema={
"type": "object",
"properties": {
"stock_code": {
"type": "string",
"description": "Stock code to analyze"
}
},
"required": ["stock_code"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: Any) -> list[TextContent]:
"""Handle tool calls"""
try:
async with httpx.AsyncClient(timeout=30.0) as client:
if name == "get_portfolio":
response = await client.get(f"{BACKEND_URL}/portfolio")
data = response.json()
return [TextContent(
type="text",
text=_dumps(data)
)]
elif name == "get_market_data":
stock_code = arguments.get("stock_code")
response = await client.get(
f"{BACKEND_URL}/market-data/prices",
params={"codes": stock_code}
)
data = response.json()
return [TextContent(
type="text",
text=_dumps(data)
)]
elif name == "get_recommendations":
response = await client.get(f"{BACKEND_URL}/recommendations/rule-based")
data = response.json()
return [TextContent(
type="text",
text=_dumps(data)
)]
elif name == "get_trade_history":
limit = arguments.get("limit", 10 if settings.TOKEN_SAVE_MODE else 20)
response = await client.get(
f"{BACKEND_URL}/trades",
params={"limit": limit}
)
data = response.json()
return [TextContent(
type="text",
text=_dumps(data)
)]
elif name == "analyze_stock":
stock_code = arguments.get("stock_code")
# Get chart data
response = await client.get(
f"{BACKEND_URL}/market-data/chart/{stock_code}",
params={"period": "D", "realtime": "true"}
)
data = response.json()
return [TextContent(
type="text",
text=_dumps(data)
)]
else:
return [TextContent(
type="text",
text=f"Unknown tool: {name}"
)]
except Exception as e:
return [TextContent(
type="text",
text=f"Error calling tool {name}: {str(e)}"
)]
async def main():
"""Run the MCP server with stdio transport"""
async with stdio_server() as (read_stream, write_stream):
await app.run(
read_stream,
write_stream,
app.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())