Metadata-Version: 2.4
Name: aiofmp
Version: 1.3.0
Summary: Asynchronous Financial Modeling Prep API Client with MCP Server
Project-URL: Homepage, https://github.com/codemug/aiofmp
Project-URL: Documentation, https://github.com/codemug/aiofmp#readme
Project-URL: Repository, https://github.com/codemug/aiofmp.git
Project-URL: Issues, https://github.com/codemug/aiofmp/issues
Author-email: codemug <u.manshahid@gmail.com>
Maintainer-email: codemug <u.manshahid@gmail.com>
License: Apache 2.0
License-File: LICENSE
Keywords: api,async,crypto,financial,financial-modeling-prep,forex,mcp,model-context-protocol,stocks
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: aiohttp>=3.12.15
Requires-Dist: click>=8.0.0
Requires-Dist: fastmcp>=2.0.0
Requires-Dist: pyarrow>=14.0.0
Requires-Dist: pytest-asyncio>=1.1.0
Requires-Dist: pytest-cov>=5.0.0
Requires-Dist: pytest>=8.4.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: ruff>=0.13.2
Provides-Extra: dev
Requires-Dist: black>=25.0.0; extra == 'dev'
Requires-Dist: isort>=6.0.0; extra == 'dev'
Requires-Dist: mypy>=1.18.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.2.0; extra == 'dev'
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
Requires-Dist: pytest-mock>=3.15.0; extra == 'dev'
Requires-Dist: pytest>=8.4.1; extra == 'dev'
Requires-Dist: python-semantic-release>=10.4.1; extra == 'dev'
Requires-Dist: ruff>=0.13.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# aiofmp

[![PyPI Version](https://img.shields.io/pypi/v/aiofmp.svg?color=0A7BBB)](https://pypi.org/project/aiofmp/)

**aiofmp** is a comprehensive Python SDK that provides seamless access to the Financial Modeling Prep API through an intuitive, category-based interface. Built with asyncio for high-performance concurrent operations, it offers:

- **Complete FMP API Coverage**: Access to 22+ API categories including financial statements, market data, news, technical indicators, and more
- **Async-First Design**: Built with asyncio for high-performance concurrent operations and non-blocking I/O
- **MCP Server Integration**: Built-in Model Context Protocol server that exposes all FMP APIs as AI-friendly tools
- **Type Safety**: Full type hints throughout the codebase for better IDE support and error prevention
- **Clean Architecture**: Category-based organization that mirrors the FMP API structure
- **Comprehensive Error Handling**: Robust error handling with custom exceptions and retry logic
- **Rate Limiting**: Built-in rate limiting and retry logic to respect API limits
- **AI-Ready**: MCP tools designed specifically for AI assistants with natural language prompts
- **CachedClient**: Intelligent caching wrapper that stores time-series data locally and only fetches missing date ranges from the API

### Key Features

- **22 API Categories**: Complete coverage of all FMP API endpoints
- **Flexible Configuration**: Environment-based configuration for easy deployment
- **160+ MCP Tools**: Every FMP API function exposed as an MCP tool for AI assistants
- **Dual Transport Support**: Both STDIO and HTTP transport modes for MCP server
- **Comprehensive Testing**: Full test coverage with 500+ unit tests
- **Production Ready**: Built for reliability and performance in production environments

## Installation

### Prerequisites

- Python 3.10 or higher
- Financial Modeling Prep API key ([Get one here](https://site.financialmodelingprep.com/developer/docs/pricing))

### Install from Source

```bash
# Clone the repository
git clone https://github.com/your-username/aiofmp.git
cd aiofmp

# Install dependencies using uv (recommended)
uv sync

# Install the package in development mode
uv pip install -e .

# Or using pip
pip install -e .

# Activate virtual environment (if using uv)
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
```

## Usage

### Basic Client Usage

```python
import asyncio
from aiofmp import FmpClient

async def main():
    # Initialize client with your API key
    client = FmpClient(api_key="your_api_key_here")

    # Use async context manager for automatic session management
    async with client:
        # Search for symbols
        symbols = await client.search.symbols("AAPL", limit=10)
        print(f"Found {len(symbols)} symbols")

        # Get company profile
        profile = await client.company.profile("AAPL")
        print(f"Company: {profile['companyName']}")
        
        # Get financial statements
        income_statement = await client.statements.income_statement("AAPL", limit=5)
        print(f"Retrieved {len(income_statement)} periods of income statement data")

# Run the example
asyncio.run(main())
```

### CachedClient Usage

The CachedClient wraps `FmpClient` with an intelligent caching layer. It intercepts time-series API calls, stores data locally in Parquet files, and only fetches missing date ranges from the FMP API on subsequent calls. This dramatically reduces API usage when working with historical data.

By default, data is cached under `~/.aiofmp/cache`. Override the location with the `AIOFMP_CACHE_FILE_PATH` environment variable.

```python
import asyncio
from aiofmp import FmpClient
from aiofmp.cachedclient import CachedClient

async def main():
    fmp = FmpClient(api_key="your_api_key_here")
    cached = CachedClient(fmp)  # caches to ~/.aiofmp/cache by default

    async with cached:
        # First call: fetches from FMP API, stores locally in Parquet
        data = await cached.chart.historical_price_full("AAPL", "2020-01-01", "2023-12-31")
        print(f"Fetched {len(data)} records")

        # Second call: extends the range — only fetches the 2024 gap from the API
        data = await cached.chart.historical_price_full("AAPL", "2020-01-01", "2025-01-01")
        print(f"Got {len(data)} records (2020-2023 from cache, 2024+ from API)")

        # Repeated call with same range: fully served from cache, zero API calls
        data = await cached.chart.historical_price_full("AAPL", "2020-01-01", "2025-01-01")

        # Financial statements: merges fresh data with stored history
        stmts = await cached.statements.income_statement("AAPL", limit=5, period="annual")

        # Non-cacheable endpoints pass through unchanged
        profile = await cached.company.profile("AAPL")

asyncio.run(main())
```

**Supported caching patterns:**

- **Date-range endpoints** (chart, economics, calendar, news, technical indicators, etc.): gap detection fetches only the missing date ranges
- **Period-based endpoints** (income statements, balance sheets, ratios, etc.): fetches fresh data and merges with stored historical records
- **Non-cacheable endpoints** (profiles, quotes, search, etc.): pass through directly to the FMP API

**Storage is pluggable** — `ParquetStorage` is the built-in default, but you can pass any `StorageBackend` subclass to `CachedClient(fmp, storage=my_storage)`.

### MCP Server Usage

The aiofmp package includes a built-in MCP server that exposes all FMP APIs as AI-friendly tools.

#### Configuration

Set up environment variables for MCP server configuration:

```bash
# Required: FMP API Key
export FMP_API_KEY="your_api_key_here"

# Optional: MCP Server Configuration
export MCP_TRANSPORT="stdio"  # or "http"
export MCP_HOST="localhost"   # for HTTP transport
export MCP_PORT="3000"        # for HTTP transport
export MCP_LOG_LEVEL="INFO"   # DEBUG, INFO, WARNING, ERROR
```

#### Running the MCP Server

**STDIO Transport (for MCP clients like Claude Desktop):**
```bash
aiofmp-mcp-server
```

**HTTP Transport (for web-based MCP clients):**
```bash
aiofmp-mcp-server --transport http
```

**Custom Configuration:**
```bash
aiofmp-mcp-server --transport http --host 0.0.0.0 --port 8080
```

**With API Key:**
```bash
aiofmp-mcp-server --api-key your_api_key_here
```

**With Debug Logging:**
```bash
aiofmp-mcp-server --log-level DEBUG
```

**Include text content alongside structured content:**
```bash
aiofmp-mcp-server --text-content
```

**Enable local caching of time-series data:**
```bash
aiofmp-mcp-server --cached
```

When `--cached` is enabled, the MCP server uses `CachedClient` under the hood. Time-series API calls are cached locally in Parquet files so repeated queries for the same historical data don't consume API quota. Cache directory defaults to `~/.aiofmp/cache` (override with `AIOFMP_CACHE_FILE_PATH`).

#### Selective Tool Registration

By default the server exposes 177 tools across 22 categories. To reduce the surface area an AI agent has to reason about, restrict which tools are registered using `--tools` (allowlist) and/or `--exclude-tools` (denylist). The spec grammar mixes category-level and per-tool selection:

| Spec | Meaning |
|---|---|
| `chart` | all tools in the chart category |
| `chart(*)` | same — explicit form |
| `chart(get_intraday_1hour)` | just that one chart tool |
| `chart(get_intraday_1hour,get_historical_price_full)` | exactly those chart tools |
| `*` | every tool in every category (default) |

A spec is a comma-separated list of these entries. When both flags are set, `--tools` defines the universe and `--exclude-tools` prunes from it.

```bash
# Only chart, quote, and search are visible to the AI
aiofmp-mcp-server --tools "chart(*),quote(*),search(*)"

# A single tool from quote, all of search
aiofmp-mcp-server --tools "quote(get_stock_quote),search"

# Everything except form13f, senate, and chart.get_intraday_1min
aiofmp-mcp-server --exclude-tools "form13f,senate,chart(get_intraday_1min)"

# Allowlist with a carve-out
aiofmp-mcp-server --tools "chart(*),quote(*)" --exclude-tools "chart(get_intraday_1min)"

# Discover available categories and tool names
aiofmp-mcp-server --list-tools
```

Environment variable equivalents (useful for Claude Desktop configs): `AIOFMP_MCP_TOOLS` and `AIOFMP_MCP_EXCLUDE_TOOLS`. Invalid category or tool names fail fast at startup with the valid list printed.

#### Claude Desktop Integration

Add to your Claude Desktop configuration (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "aiofmp": {
      "command": "aiofmp-mcp-server",
      "args": ["--api-key", "your_api_key_here"]
    }
  }
}
```

**Alternative with environment variable:**
```json
{
  "mcpServers": {
    "aiofmp": {
      "command": "aiofmp-mcp-server",
      "env": {
        "FMP_API_KEY": "your_api_key_here"
      }
    }
  }
}
```

### CLI Reference

The `aiofmp-mcp-server` command provides a user-friendly interface for running the MCP server:

```bash
# Basic usage
aiofmp-mcp-server

# Show help
aiofmp-mcp-server --help

# HTTP transport
aiofmp-mcp-server --transport http --host 0.0.0.0 --port 8080

# With API key
aiofmp-mcp-server --api-key your_api_key_here

# Debug logging
aiofmp-mcp-server --log-level DEBUG

# Include text content alongside structured content
aiofmp-mcp-server --text-content

# Enable local caching
aiofmp-mcp-server --cached

# Restrict the tools that get registered
aiofmp-mcp-server --tools "chart(*),quote(get_stock_quote),search"
aiofmp-mcp-server --exclude-tools "form13f,senate"

# List available categories and tools
aiofmp-mcp-server --list-tools

# All options
aiofmp-mcp-server --transport http --host localhost --port 3000 --log-level INFO --api-key your_key --text-content --cached
```

**Command Options:**
- `--transport`: Transport mode (`stdio` or `http`, default: `stdio`)
- `--host`: Host for HTTP transport (default: `localhost`)
- `--port`: Port for HTTP transport (default: `3000`)
- `--log-level`: Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, default: `INFO`)
- `--api-key`: FMP API key (can also be set via `FMP_API_KEY` environment variable)
- `--text-content`: Include text content alongside structured content in MCP tool responses (default: text content is empty when structured content is present)
- `--cached`: Enable CachedClient to cache time-series data locally in Parquet files, minimizing API calls (default: off). Cache dir: `~/.aiofmp/cache` (override with `AIOFMP_CACHE_FILE_PATH`)
- `--tools`: Restrict which MCP tools are registered. Spec syntax: `category` or `category(*)` for a whole category, `category(tool1,tool2)` for specific tools; comma-separated. Env: `AIOFMP_MCP_TOOLS`. Default: all tools.
- `--exclude-tools`: Same syntax as `--tools`, but prunes from the include set. Env: `AIOFMP_MCP_EXCLUDE_TOOLS`.
- `--list-tools`: Print available categories and tool names, then exit. Does not require `FMP_API_KEY`.

### Available API Categories

The aiofmp client provides access to 22+ FMP API categories:

- **Analyst**: Financial estimates, ratings, price targets, and analyst recommendations
- **Calendar**: Earnings, dividends, IPOs, and economic events
- **Chart**: Historical price data and technical analysis
- **Company**: Company profiles, key metrics, and corporate information
- **Commodity**: Commodity prices, quotes, and historical data
- **COT**: Commitment of Traders reports for commodities
- **Crypto**: Cryptocurrency prices, quotes, and market data
- **DCF**: Discounted Cash Flow valuations and analysis
- **Directory**: Symbol lists, exchanges, sectors, and reference data
- **Economics**: Economic indicators, treasury rates, and macro data
- **ETF**: ETF holdings, performance, and analysis
- **Forex**: Foreign exchange rates and currency data
- **Form 13F**: Institutional holdings and filings
- **Indexes**: Stock market indices and performance
- **Insider Trades**: Insider trading activity and statistics
- **Market Performance**: Sector performance, market movers, and P/E ratios
- **News**: Financial news, press releases, and market updates
- **Quote**: Real-time quotes, price changes, and market data
- **Search**: Symbol search, company search, and stock screening
- **Senate**: Congressional trading disclosures and activity
- **Statements**: Financial statements, ratios, and metrics
- **Technical Indicators**: Moving averages, RSI, and technical analysis tools

## Examples

### Client Examples

The `examples/` directory contains comprehensive examples for each API category:

```bash
# Run specific examples
python examples/fmp_search_example.py
python examples/fmp_company_example.py
python examples/fmp_statements_example.py
python examples/fmp_cachedclient_example.py
```

### MCP Server Examples

**Example 1: Basic MCP Tool Usage**
```python
# These are example prompts that would be sent to an AI assistant using the MCP server
"What is the current stock quote for Apple (AAPL)?"
"Show me the 20-day Simple Moving Average for Microsoft (MSFT)"
"Get the latest financial statements for Tesla (TSLA)"
```

**Example 2: Advanced Financial Analysis**
```python
# Complex analysis prompts
"Compare the P/E ratios of Apple, Microsoft, and Google over the past year"
"Find all technology stocks with market cap over $100 billion"
"Show me the insider trading activity for Tesla in the last 3 months"
```

**Example 3: Market Research**
```python
# Market research prompts
"What are the biggest gainers in the market today?"
"Show me the sector performance for the technology sector"
"Get the latest earnings calendar for next week"
```

### Example Files

- `fmp_cachedclient_example.py` - CachedClient caching wrapper
- `fmp_analyst_example.py` - Analyst estimates and ratings
- `fmp_calendar_example.py` - Earnings and dividend calendars
- `fmp_chart_example.py` - Historical price data
- `fmp_company_example.py` - Company profiles and metrics
- `fmp_commodity_example.py` - Commodity prices and data
- `fmp_cot_example.py` - Commitment of Traders reports
- `fmp_crypto_example.py` - Cryptocurrency data
- `fmp_dcf_example.py` - DCF valuations
- `fmp_directory_example.py` - Symbol lists and reference data
- `fmp_economics_example.py` - Economic indicators
- `fmp_etf_example.py` - ETF analysis
- `fmp_forex_example.py` - Foreign exchange data
- `fmp_form13f_example.py` - Institutional holdings
- `fmp_indexes_example.py` - Market indices
- `fmp_insider_trades_example.py` - Insider trading
- `fmp_search_example.py` - Symbol and company search
- `fmp_statements_example.py` - Financial statements

### MCP Server Testing

Test the MCP server functionality:

```bash
# Run all MCP tests
uv run pytest tests/test_mcp_tools.py tests/test_mcp_server.py -v

# Run specific category tests
uv run pytest tests/test_mcp_tools.py::TestSearchTools -v
uv run pytest tests/test_mcp_server.py::TestMCPServer -v

# Test with debug logging
aiofmp-mcp-server --log-level DEBUG
```

### Harvester

`aiofmp harvest` is a long-running CLI that proactively warms the local Parquet cache. It runs one async task per enabled category, each on its own configurable interval, and uses category-specific strategies to minimise redundant fetches (target: stay under 20 GB/month on FMP starter plan).

**Quick start:**

```bash
cp examples/harvester.example.yaml ~/harvester.yaml
export FMP_API_KEY=your_key_here

# Print the plan, fetch nothing
aiofmp harvest --config ~/harvester.yaml --dry-run

# One cycle per enabled category, then exit
aiofmp harvest --config ~/harvester.yaml --once

# Run a single category once
aiofmp harvest --config ~/harvester.yaml --once --category statements

# Run forever (Ctrl-C to stop cleanly)
aiofmp harvest --config ~/harvester.yaml

# Inspect state
aiofmp harvest-status --config ~/harvester.yaml
```

**State:** SQLite at `<state_dir>/harvester.sqlite` (checkpoints, bandwidth ledger, symbol catalogs). Parquet under `<state_dir>/cachedclient_data/`.

See `docs/superpowers/specs/2026-05-15-harvester-v2-design.md` for the full design.

## Configuration

### Environment Variables

| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `FMP_API_KEY` | Financial Modeling Prep API key | None | Yes |
| `MCP_TRANSPORT` | MCP server transport mode | `stdio` | No |
| `MCP_HOST` | MCP server host (HTTP mode) | `localhost` | No |
| `MCP_PORT` | MCP server port (HTTP mode) | `3000` | No |
| `MCP_LOG_LEVEL` | Logging level | `INFO` | No |
| `AIOFMP_CACHED` | Enable CachedClient (`true`/`false`) | `false` | No |
| `AIOFMP_CACHE_FILE_PATH` | Cache directory for Parquet files | `~/.aiofmp/cache` | No |
| `AIOFMP_MCP_TOOLS` | Restrict MCP tools (allowlist; same grammar as `--tools`) | unset | No |
| `AIOFMP_MCP_EXCLUDE_TOOLS` | Prune MCP tools (denylist; same grammar as `--exclude-tools`) | unset | No |

### MCP Server Modes

**STDIO Mode (Default):**
- Used by MCP clients like Claude Desktop
- Communicates via standard input/output
- No network configuration required

**HTTP Mode:**
- Used by web-based MCP clients
- Requires host and port configuration
- Supports multiple concurrent connections

## API Reference

### Client Categories

Each API category provides methods that mirror the FMP API structure:

```python
# Search and discovery
await client.search.symbols("AAPL")
await client.search.companies("Apple")
await client.search.screener(sector="Technology")

# Company information
await client.company.profile("AAPL")
await client.company.key_metrics("AAPL")

# Financial statements
await client.statements.income_statement("AAPL")
await client.statements.balance_sheet("AAPL")
await client.statements.cash_flow_statement("AAPL")

# Market data
await client.quote.stock_quote("AAPL")
await client.chart.historical_price_full("AAPL")

# Technical analysis
await client.technical_indicators.simple_moving_average("AAPL", 20, "1day")
await client.technical_indicators.relative_strength_index("AAPL", 14, "1day")
```

### MCP Tools

The MCP server exposes 160+ tools across all categories. Each tool includes:
- Detailed descriptions and parameter documentation
- Natural language examples for AI assistants
- Comprehensive error handling
- Type validation and parameter checking

## Error Handling

The client includes comprehensive error handling:

```python
from aiofmp.exceptions import FmpError, FmpRateLimitError, FmpAPIError

try:
    data = await client.search.symbols("INVALID")
except FmpAPIError as e:
    print(f"API Error: {e}")
except FmpRateLimitError as e:
    print(f"Rate limit exceeded: {e}")
except FmpError as e:
    print(f"General error: {e}")
```

## Testing

Run the comprehensive test suite:

```bash
# Run all tests
uv run pytest

# Run specific test categories
uv run pytest tests/test_search.py -v
uv run pytest tests/test_mcp_tools.py -v

# Run with coverage
uv run pytest --cov=aiofmp --cov-report=html
```

## Performance

- **Async Operations**: All API calls are non-blocking
- **Connection Pooling**: Efficient HTTP connection management
- **Rate Limiting**: Built-in rate limiting to respect API limits
- **CachedClient**: Intelligent time-series caching with gap detection — only fetches missing data from the API
- **Concurrent Requests**: Support for multiple simultaneous API calls

## Security

- **API Key Management**: Secure handling of API keys
- **Environment Variables**: Support for environment-based configuration
- **No Hardcoded Secrets**: All sensitive data via configuration
- **HTTPS Only**: All API communications over secure connections

## Release Process

This project uses [Semantic Release](https://semantic-release.gitbook.io/) for automated versioning and publishing. The release process is fully automated through GitHub Actions.

### How It Works

1. **Conventional Commits**: All commits must follow the [Conventional Commits](https://conventionalcommits.org/) specification
2. **Automatic Versioning**: Semantic Release analyzes commit messages to determine the next version
3. **Automatic Publishing**: When a new version is detected, it automatically:
   - Creates a git tag
   - Updates the CHANGELOG.md
   - Publishes to PyPI
   - Creates a GitHub release

### Commit Message Format

```
<type>(<scope>): <subject>

<body>

<footer>
```

**Types:**
- `feat`: New features
- `fix`: Bug fixes
- `docs`: Documentation changes
- `style`: Code style changes (formatting, etc.)
- `refactor`: Code refactoring
- `perf`: Performance improvements
- `test`: Test additions or changes
- `chore`: Build process or auxiliary tool changes

**Examples:**
```bash
feat(mcp): add new search tools for financial data
fix(api): resolve authentication error in client
docs: update installation instructions
test: add unit tests for MCP server
chore: update dependencies
```

### Setting Up Releases

1. **Configure Git** (run once):
   ```bash
   ./scripts/setup-git.sh
   ```

2. **Set up PyPI Token**:
   - Go to [PyPI Account Settings](https://pypi.org/manage/account/)
   - Create an API token
   - Add it to GitHub Secrets as `PYPI_API_TOKEN`

3. **Update Repository URLs**:
  - Update URLs in `pyproject.toml`
  - Update author information

4. **Make Changes and Commit**:
   ```bash
   git add .
   git commit -m "feat: add new feature"
   git push origin main
   ```

The GitHub Action will automatically:
- Run quick tests and linting
- Check code quality
- Determine if a release is needed
- Create a new version and publish to PyPI

### Manual Testing

For comprehensive testing, you can manually trigger the test workflow:

1. Go to the "Actions" tab in your GitHub repository
2. Select the "Test" workflow
3. Click "Run workflow"
4. Choose:
   - **Python version**: 3.10, 3.11, 3.12, or 3.13
   - **Test type**: all, unit, mcp, or integration
5. Click "Run workflow"

This allows you to run tests on specific Python versions or test categories without using your free tier minutes unnecessarily.

## Contributing

Contributions are welcome! We appreciate any help in improving aiofmp.

### Development Setup

```bash
# Clone and setup development environment
git clone https://github.com/your-username/aiofmp.git
cd aiofmp
uv sync --dev

# Install pre-commit hooks
pre-commit install

# Run tests
uv run pytest

# Run linting
uv run ruff check .
uv run ruff format .
```

### Contribution Guidelines

1. **Fork the repository** and create a feature branch
2. **Follow the coding standards** (type hints, docstrings, error handling)
3. **Add comprehensive tests** for new functionality
4. **Update documentation** for any API changes
5. **Ensure all tests pass** before submitting a PR
6. **Use conventional commits** for commit messages

### Areas for Contribution

- **New API Endpoints**: Add support for new FMP API endpoints
- **Performance Improvements**: Optimize existing functionality
- **Documentation**: Improve examples and documentation
- **Testing**: Add more comprehensive test coverage
- **MCP Tools**: Enhance MCP tool descriptions and examples
- **Error Handling**: Improve error messages and handling

### Reporting Issues

Please report bugs and request features through GitHub Issues. Include:
- Python version and operating system
- Steps to reproduce the issue
- Expected vs actual behavior
- Relevant error messages and logs

## License

This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

- [Financial Modeling Prep](https://financialmodelingprep.com/) for providing the comprehensive financial data API
- [FastMCP](https://github.com/jlowin/fastmcp) for the MCP server framework
- The Python asyncio community for excellent async programming tools

## Support

- **Documentation**: Check the examples directory and inline docstrings
- **Issues**: Report bugs and request features via GitHub Issues
- **Discussions**: Use GitHub Discussions for questions and community support
- **API Reference**: Full API documentation available in the code

---

**Built with ❤️ for the financial data community**
