newsdata-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. newsdata_mcp-0.1.0/.dockerignore +41 -0
  2. newsdata_mcp-0.1.0/.env.example +14 -0
  3. newsdata_mcp-0.1.0/.github/workflows/ci.yml +33 -0
  4. newsdata_mcp-0.1.0/.github/workflows/release.yml +85 -0
  5. newsdata_mcp-0.1.0/.gitignore +26 -0
  6. newsdata_mcp-0.1.0/.python-version +1 -0
  7. newsdata_mcp-0.1.0/Dockerfile +57 -0
  8. newsdata_mcp-0.1.0/LICENSE +21 -0
  9. newsdata_mcp-0.1.0/PKG-INFO +320 -0
  10. newsdata_mcp-0.1.0/README.md +270 -0
  11. newsdata_mcp-0.1.0/pyproject.toml +132 -0
  12. newsdata_mcp-0.1.0/src/newsdata_mcp/__init__.py +10 -0
  13. newsdata_mcp-0.1.0/src/newsdata_mcp/_mcp.py +84 -0
  14. newsdata_mcp-0.1.0/src/newsdata_mcp/formatters.py +256 -0
  15. newsdata_mcp-0.1.0/src/newsdata_mcp/http.py +358 -0
  16. newsdata_mcp-0.1.0/src/newsdata_mcp/params.py +459 -0
  17. newsdata_mcp-0.1.0/src/newsdata_mcp/server.py +41 -0
  18. newsdata_mcp-0.1.0/src/newsdata_mcp/settings.py +54 -0
  19. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/__init__.py +29 -0
  20. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/archive.py +149 -0
  21. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/count.py +144 -0
  22. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/crypto.py +115 -0
  23. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/crypto_count.py +109 -0
  24. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/latest.py +149 -0
  25. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/market.py +146 -0
  26. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/market_count.py +137 -0
  27. newsdata_mcp-0.1.0/src/newsdata_mcp/tools/sources.py +56 -0
  28. newsdata_mcp-0.1.0/src/newsdata_mcp/validators.py +75 -0
  29. newsdata_mcp-0.1.0/tests/__init__.py +0 -0
  30. newsdata_mcp-0.1.0/tests/conftest.py +41 -0
  31. newsdata_mcp-0.1.0/tests/test_formatters.py +367 -0
  32. newsdata_mcp-0.1.0/tests/test_http.py +596 -0
  33. newsdata_mcp-0.1.0/tests/test_integration.py +107 -0
  34. newsdata_mcp-0.1.0/tests/test_tools.py +688 -0
  35. newsdata_mcp-0.1.0/tests/test_validators.py +228 -0
  36. newsdata_mcp-0.1.0/uv.lock +1072 -0
@@ -0,0 +1,41 @@
1
+ # Build context: the Dockerfile only COPYs pyproject.toml, uv.lock,
2
+ # README.md, src/, and LICENSE. Everything else listed here is
3
+ # excluded from the build context so `docker build` uploads less and
4
+ # layer hashes stay stable when these change.
5
+
6
+ # Python build / runtime artifacts
7
+ __pycache__
8
+ *.pyc
9
+ *.pyo
10
+ *.egg-info/
11
+ .venv/
12
+ dist/
13
+ build/
14
+
15
+ # Tooling caches
16
+ .mypy_cache/
17
+ .pytest_cache/
18
+ .ruff_cache/
19
+ .coverage
20
+ .coverage.*
21
+ htmlcov/
22
+
23
+ # Tests, CI, editor config — not needed inside the image
24
+ tests/
25
+ .github/
26
+ .vscode/
27
+ .idea/
28
+
29
+ # Local scratch / per-machine markers
30
+ .codex
31
+ temp.py
32
+ .claude/
33
+
34
+ # VCS / environment
35
+ .git/
36
+ .gitignore
37
+ .env
38
+
39
+ # Project docs not shipped in the image (README.md is needed by
40
+ # Dockerfile and is NOT listed here).
41
+ CLAUDE.md
@@ -0,0 +1,14 @@
1
+ # NewsData.io credentials — copy this file to `.env` and fill in.
2
+ NEWSDATA_API_KEY="your_newsdata_api_key_here"
3
+
4
+ # Optional: request timeout in seconds (default: 30)
5
+ # REQUEST_TIMEOUT=30
6
+
7
+ # Optional: override the API base URL (e.g. for staging or a local mock)
8
+ # NEWSDATA_BASE_URL=https://newsdata.io/api/1
9
+
10
+ # Optional: retry policy for transient failures (network, 5xx, 429).
11
+ # Defaults sleep ~62s total across 5 attempts (2s → 4s → 8s → 16s → 32s, capped at 60s).
12
+ # NEWSDATA_MAX_RETRIES=5
13
+ # NEWSDATA_RETRY_BACKOFF=2.0
14
+ # NEWSDATA_RETRY_BACKOFF_MAX=60.0
@@ -0,0 +1,33 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - name: Install uv
16
+ uses: astral-sh/setup-uv@v3
17
+ with:
18
+ enable-cache: true
19
+
20
+ - name: Set up Python
21
+ run: uv python install 3.12
22
+
23
+ - name: Install dependencies (runtime + dev)
24
+ run: uv sync --all-groups --frozen
25
+
26
+ - name: Lint (ruff)
27
+ run: uv run ruff check src/ tests/
28
+
29
+ - name: Type-check (mypy)
30
+ run: uv run mypy
31
+
32
+ - name: Test (pytest, unit only by default)
33
+ run: uv run pytest --cov=newsdata_mcp --cov-report=term-missing
@@ -0,0 +1,85 @@
1
+ name: release
2
+
3
+ # Tag-triggered: build sdist + wheel, publish to PyPI via Trusted
4
+ # Publishing (OIDC, no API token), then create a GitHub Release with
5
+ # auto-generated notes and the same artifacts attached.
6
+ #
7
+ # Requires a one-time PyPI Trusted Publisher config:
8
+ # PyPI project "newsdata-mcp" → Publishing → Add a new pending /
9
+ # trusted publisher with
10
+ # Owner: newsdataapi
11
+ # Repository: newsdata.io-mcp
12
+ # Workflow: release.yml
13
+ # Environment: pypi
14
+
15
+ on:
16
+ push:
17
+ tags:
18
+ - "v*"
19
+
20
+ jobs:
21
+ build:
22
+ name: Build distribution
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+
27
+ - name: Install uv
28
+ uses: astral-sh/setup-uv@v3
29
+ with:
30
+ enable-cache: true
31
+
32
+ - name: Set up Python
33
+ run: uv python install 3.12
34
+
35
+ - name: Build sdist + wheel
36
+ run: uv build
37
+
38
+ - name: Show artifacts
39
+ run: ls -la dist/
40
+
41
+ - name: Upload artifacts
42
+ uses: actions/upload-artifact@v4
43
+ with:
44
+ name: dist
45
+ path: dist/
46
+
47
+ pypi-publish:
48
+ name: Publish to PyPI
49
+ needs: build
50
+ runs-on: ubuntu-latest
51
+ environment:
52
+ name: pypi
53
+ url: https://pypi.org/p/newsdata-mcp
54
+ permissions:
55
+ id-token: write # required for Trusted Publishing
56
+ steps:
57
+ - name: Download artifacts
58
+ uses: actions/download-artifact@v4
59
+ with:
60
+ name: dist
61
+ path: dist/
62
+
63
+ - name: Publish to PyPI
64
+ uses: pypa/gh-action-pypi-publish@release/v1
65
+
66
+ github-release:
67
+ name: Create GitHub Release
68
+ needs: pypi-publish
69
+ runs-on: ubuntu-latest
70
+ permissions:
71
+ contents: write
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+
75
+ - name: Download artifacts
76
+ uses: actions/download-artifact@v4
77
+ with:
78
+ name: dist
79
+ path: dist/
80
+
81
+ - name: Create release
82
+ uses: softprops/action-gh-release@v2
83
+ with:
84
+ generate_release_notes: true
85
+ files: dist/*
@@ -0,0 +1,26 @@
1
+ # Python build artifacts
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ build/
6
+ dist/
7
+
8
+ # Virtual environment
9
+ .venv/
10
+
11
+ # Secrets
12
+ .env
13
+
14
+ # Tooling caches (mypy, pytest, ruff, coverage)
15
+ .mypy_cache/
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+ .coverage
19
+ .coverage.*
20
+ htmlcov/
21
+
22
+ # Local-only files
23
+ .codex
24
+ temp.py
25
+ CLAUDE.md
26
+ .vscode/
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,57 @@
1
+ # Multistage build: resolve and install with uv against the lockfile in
2
+ # the builder, then copy the resulting venv into a minimal runtime stage.
3
+
4
+ # ---------- Builder ----------
5
+ FROM python:3.12-slim AS builder
6
+
7
+ ENV PYTHONDONTWRITEBYTECODE=1 \
8
+ UV_COMPILE_BYTECODE=1 \
9
+ UV_LINK_MODE=copy
10
+
11
+ # uv is a small Rust binary; pip-install it once in the builder.
12
+ RUN pip install --no-cache-dir uv
13
+
14
+ WORKDIR /app
15
+
16
+ # Install dependencies first (without the project itself) so this layer
17
+ # stays cached when only application source changes. LICENSE is needed
18
+ # at build time because pyproject.toml declares `license = { file = ... }`.
19
+ COPY pyproject.toml uv.lock README.md LICENSE /app/
20
+ RUN uv sync --frozen --no-install-project --no-dev
21
+
22
+ # Now copy source and install the project itself into the same venv.
23
+ COPY src /app/src
24
+ RUN uv sync --frozen --no-dev
25
+
26
+ # ---------- Runtime ----------
27
+ FROM python:3.12-slim AS runtime
28
+
29
+ ENV PYTHONDONTWRITEBYTECODE=1 \
30
+ PYTHONUNBUFFERED=1 \
31
+ REQUEST_TIMEOUT=30 \
32
+ PATH="/app/.venv/bin:$PATH"
33
+
34
+ WORKDIR /app
35
+
36
+ # Copy the populated venv + project source from the builder. LICENSE
37
+ # is already inside /app from the builder stage.
38
+ COPY --from=builder /app /app
39
+
40
+ # Run as a non-root user.
41
+ RUN useradd --create-home --uid 1000 app \
42
+ && chown -R app:app /app
43
+ USER app
44
+
45
+ EXPOSE 8000
46
+
47
+ # TCP-level liveness probe; only meaningful for streamable-http transport.
48
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=10s \
49
+ CMD python -c "import socket; s=socket.socket(); s.settimeout(2); s.connect(('localhost',8000)); s.close()" || exit 1
50
+
51
+ LABEL org.opencontainers.image.title="newsdata-mcp" \
52
+ org.opencontainers.image.description="MCP server for NewsData.io" \
53
+ org.opencontainers.image.licenses="MIT" \
54
+ org.opencontainers.image.source="https://github.com/newsdataapi/newsdata.io-mcp"
55
+
56
+ ENTRYPOINT ["newsdata-mcp"]
57
+ CMD ["--transport", "streamable-http", "--host", "0.0.0.0", "--port", "8000"]
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NewsData.io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,320 @@
1
+ Metadata-Version: 2.4
2
+ Name: newsdata-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for the NewsData.io REST API (latest/archive/crypto/market news, source discovery, aggregate counts).
5
+ Project-URL: Homepage, https://newsdata.io
6
+ Project-URL: Documentation, https://newsdata.io/documentation
7
+ Project-URL: Repository, https://github.com/newsdataapi/newsdata.io-mcp
8
+ Project-URL: Issues, https://github.com/newsdataapi/newsdata.io-mcp/issues
9
+ Author-email: "NewsData.io" <contact@newsdata.io>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 NewsData.io
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: api,crypto,market,mcp,model-context-protocol,news,newsdata
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Framework :: AsyncIO
35
+ Classifier: Framework :: Pydantic
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Operating System :: OS Independent
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Topic :: Internet :: WWW/HTTP
43
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
44
+ Requires-Python: >=3.12
45
+ Requires-Dist: httpx<1,>=0.28.1
46
+ Requires-Dist: mcp[cli]<2,>=1.27.0
47
+ Requires-Dist: pydantic<3,>=2.7.0
48
+ Requires-Dist: python-dotenv<2,>=1.2.2
49
+ Description-Content-Type: text/markdown
50
+
51
+ # NewsData MCP Server
52
+
53
+ An MCP server for [NewsData.io](https://newsdata.io/documentation) that exposes real-time, historical, crypto, market, source-discovery, and aggregate-count tools to any MCP-compatible client.
54
+
55
+ ## Available Tools
56
+
57
+ | Tool | Endpoint | Description |
58
+ |---|---|---|
59
+ | `get_latest_news` | `/api/1/latest` | Recent and breaking news (last 48h) |
60
+ | `get_archive_news` | `/api/1/archive` | Historical news, filterable by `from_date` / `to_date` |
61
+ | `get_crypto_news` | `/api/1/crypto` | Crypto and blockchain-focused coverage |
62
+ | `get_market_news` | `/api/1/market` | Stock, financial, and market-related news |
63
+ | `get_news_sources` | `/api/1/sources` | Source discovery by country, category, or language |
64
+ | `get_news_counts` | `/api/1/count` | Aggregate article counts over a date range (`hour` / `day` buckets or single `all` total) |
65
+ | `get_crypto_counts` | `/api/1/crypto/count` | Aggregate crypto article counts over a date range |
66
+ | `get_market_counts` | `/api/1/market/count` | Aggregate market article counts over a date range |
67
+
68
+ All tools are read-only and idempotent; the MCP-protocol annotations let compatible clients (Claude Code, MCP Inspector, etc.) cache and parallelize calls.
69
+
70
+ ---
71
+
72
+ ## Installation
73
+
74
+ The server is published on PyPI as [`newsdata-mcp`](https://pypi.org/project/newsdata-mcp/). The recommended path is to let your MCP client launch it via [`uvx`](https://docs.astral.sh/uv/guides/tools/) — no clone, no `uv sync`, no virtualenv to manage. The package is downloaded and cached on first launch.
75
+
76
+ ```bash
77
+ # verify uvx + the server work end-to-end (optional)
78
+ uvx newsdata-mcp --version
79
+ ```
80
+
81
+ Then add the server to your MCP client (see [Editor & Client Integrations](#editor--client-integrations) below). Every client config uses the same launch command:
82
+
83
+ ```json
84
+ "command": "uvx",
85
+ "args": ["newsdata-mcp"]
86
+ ```
87
+
88
+ For a local development checkout, see [Development](#development) below.
89
+
90
+ ### Configure environment
91
+
92
+ Set `NEWSDATA_API_KEY` in your client config's `env` block (per the per-client examples below). When running the server outside an MCP client (development, Docker, `streamable-http`), use a `.env` file:
93
+
94
+ ```bash
95
+ cp .env.example .env
96
+ # then edit .env
97
+ ```
98
+
99
+ | Variable | Default | Notes |
100
+ |---|---|---|
101
+ | `NEWSDATA_API_KEY` | _(required)_ | NewsData.io credential. Missing key returns an error envelope on every call. |
102
+ | `REQUEST_TIMEOUT` | `30` | Per-request timeout in seconds. |
103
+ | `NEWSDATA_BASE_URL` | `https://newsdata.io/api/1` | Override for staging or a local mock. |
104
+ | `NEWSDATA_MAX_RETRIES` | `5` | Maximum attempts for transient failures (network, 5xx, 429). |
105
+ | `NEWSDATA_RETRY_BACKOFF` | `2.0` | Base for exponential backoff (`base * 2^(attempt-1)`). Seconds. |
106
+ | `NEWSDATA_RETRY_BACKOFF_MAX` | `60.0` | Cap on a single retry sleep, seconds. |
107
+ | `NEWSDATA_INTEGRATION_KEY` | _(unset)_ | Used only by `pytest -m integration`. Without it, live-API tests skip. |
108
+
109
+ All values are read at module import time; restart the server after changing them.
110
+
111
+ ---
112
+
113
+ ## Docker
114
+
115
+ ```bash
116
+ docker build -t newsdata-mcp .
117
+ docker run --rm -p 8000:8000 -e NEWSDATA_API_KEY=your_newsdata_api_key newsdata-mcp
118
+ ```
119
+
120
+ Run in stdio mode:
121
+
122
+ ```bash
123
+ docker run --rm -i -e NEWSDATA_API_KEY=your_newsdata_api_key newsdata-mcp --transport stdio
124
+ ```
125
+
126
+ Pass a `.env` file:
127
+
128
+ ```bash
129
+ docker run --rm -p 8000:8000 --env-file .env newsdata-mcp
130
+ ```
131
+
132
+ The image is a multistage build: dependencies are installed from `uv.lock` in a `python:3.12-slim` builder, then the resulting venv plus `LICENSE` is copied into a fresh `python:3.12-slim` runtime. The container runs as a non-root `app` user.
133
+
134
+ ---
135
+
136
+ ## Editor & Client Integrations
137
+
138
+ The simplest way is to add the server to your MCP client's JSON config. Each client picks up the config on restart. All examples use `uvx`, which downloads + caches the published package — no local clone required.
139
+
140
+ ### Claude Code
141
+
142
+ Either edit `~/.claude/mcp.json` (global) or `.claude/mcp.json` (per-project):
143
+
144
+ ```json
145
+ {
146
+ "mcpServers": {
147
+ "newsdata-mcp": {
148
+ "command": "uvx",
149
+ "args": ["newsdata-mcp"],
150
+ "env": {
151
+ "NEWSDATA_API_KEY": "your_newsdata_api_key"
152
+ }
153
+ }
154
+ }
155
+ }
156
+ ```
157
+
158
+ Then restart Claude Code.
159
+
160
+ ### Claude Desktop
161
+
162
+ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows) — same JSON block as above. Restart Claude Desktop.
163
+
164
+ ### Cursor
165
+
166
+ Create or edit `.cursor/mcp.json` in your project root (or `~/.cursor/mcp.json` globally) — same JSON block. Restart Cursor; the server appears under **Cursor Settings → MCP**.
167
+
168
+ ### VS Code (GitHub Copilot)
169
+
170
+ Create `.vscode/mcp.json` in your workspace (or add an `mcp` key to user settings):
171
+
172
+ ```json
173
+ {
174
+ "servers": {
175
+ "newsdata-mcp": {
176
+ "type": "stdio",
177
+ "command": "uvx",
178
+ "args": ["newsdata-mcp"],
179
+ "env": {
180
+ "NEWSDATA_API_KEY": "your_newsdata_api_key"
181
+ }
182
+ }
183
+ }
184
+ }
185
+ ```
186
+
187
+ Reload VS Code. Picked up by Copilot Chat in agent mode.
188
+
189
+ ### Windsurf
190
+
191
+ Edit `~/.codeium/windsurf/mcp_config.json` — same JSON block as the Claude Code example. Restart Windsurf.
192
+
193
+ ### ChatGPT Desktop (OpenAI)
194
+
195
+ Run the server in HTTP mode locally:
196
+
197
+ ```bash
198
+ NEWSDATA_API_KEY=your_key uvx newsdata-mcp \
199
+ --transport streamable-http --host 127.0.0.1 --port 8000
200
+ ```
201
+
202
+ Then in **ChatGPT → Settings → Connectors → Add custom connector**, register `http://127.0.0.1:8000/mcp` as the connector endpoint.
203
+
204
+ ---
205
+
206
+ ## Example Tool Calls
207
+
208
+ ```text
209
+ get_latest_news(
210
+ q="((pizza OR burger) AND healthy)",
211
+ country=["us", "gb"],
212
+ language="en",
213
+ size=10
214
+ )
215
+ ```
216
+
217
+ ```text
218
+ get_archive_news(
219
+ q="ukraine war",
220
+ from_date="2025-01-01",
221
+ to_date="2025-01-31",
222
+ language="en"
223
+ )
224
+ ```
225
+
226
+ ```text
227
+ get_crypto_news(
228
+ coin=["btc", "eth"],
229
+ sentiment="positive"
230
+ )
231
+ ```
232
+
233
+ ```text
234
+ get_market_news(
235
+ symbol=["AAPL", "NVDA"],
236
+ country="us"
237
+ )
238
+ ```
239
+
240
+ ```text
241
+ get_news_sources(
242
+ language="en",
243
+ priority_domain="top"
244
+ )
245
+ ```
246
+
247
+ ```text
248
+ get_news_counts(
249
+ from_date="2024-01-01",
250
+ to_date="2024-01-31",
251
+ q="bitcoin",
252
+ interval="day"
253
+ )
254
+ ```
255
+
256
+ ```text
257
+ get_market_counts(
258
+ from_date="2024-01-01",
259
+ to_date="2024-03-31",
260
+ symbol=["AAPL", "NVDA"],
261
+ interval="hour"
262
+ )
263
+ ```
264
+
265
+ ```text
266
+ get_latest_news(
267
+ q="elections",
268
+ sentiment="positive",
269
+ sentiment_score=70
270
+ )
271
+ ```
272
+
273
+ Notes on parameter shapes:
274
+ - CSV-style filters accept either a Python list (preferred) or a comma-separated string.
275
+ - Boolean flags accept `True`/`False` or `1`/`0`.
276
+ - `timeframe` accepts an integer for hours (e.g. `24`) or a string with `m` suffix for minutes (e.g. `90m`).
277
+ - `interval` (count tools only) accepts `hour`, `day`, or `all` (`all` returns a single aggregate count instead of buckets).
278
+ - `sentiment_score` is a 0–100 minimum confidence percentage and requires `sentiment` to also be set — e.g. `sentiment="positive", sentiment_score=70` returns only articles whose positive-sentiment score is at least 70.
279
+
280
+ ---
281
+
282
+ ## Notes
283
+
284
+ - Latest, crypto, and market endpoints return recent coverage — typically up to 48 hours.
285
+ - Free plan results are delayed relative to paid plans.
286
+ - Result `size` is capped by plan tier: commonly 10 results on free, up to 50 on paid plans.
287
+ - The count endpoints return aggregate buckets (one per `interval` slot) rather than article content.
288
+ - Every tool returns plain text (the MCP-protocol return type). Errors come back as `Error (HTTP 4xx): …` with the status code and a friendly message; HTTP 429 errors include a `retry after Ns` hint when the upstream `Retry-After` header was parseable.
289
+
290
+ Full API reference: [https://newsdata.io/documentation](https://newsdata.io/documentation).
291
+
292
+ ---
293
+
294
+ ## Development
295
+
296
+ ```bash
297
+ git clone https://github.com/newsdataapi/newsdata.io-mcp.git
298
+ cd newsdata.io-mcp
299
+ uv sync --all-groups # install runtime + dev deps
300
+
301
+ uv run pytest # unit tests only (default)
302
+ NEWSDATA_INTEGRATION_KEY=<key> uv run pytest -m integration # live-API tests
303
+ uv run pytest --cov=newsdata_mcp --cov-report=term-missing # with coverage
304
+ uv run ruff check src/ tests/
305
+ uv run mypy
306
+ ```
307
+
308
+ CI (`.github/workflows/ci.yml`) runs the same four commands on every push/PR to `main`.
309
+
310
+ ### Releasing
311
+
312
+ 1. Bump `__version__` in `src/newsdata_mcp/__init__.py`.
313
+ 2. Commit and tag: `git tag vX.Y.Z && git push --tags`.
314
+ 3. `.github/workflows/release.yml` builds the sdist + wheel, publishes to PyPI via Trusted Publishing (no token), and creates a GitHub Release with auto-generated notes.
315
+
316
+ One-time PyPI setup: configure a Trusted Publisher on the `newsdata-mcp` project pointing at `newsdataapi/newsdata.io-mcp`, workflow `release.yml`, environment `pypi`.
317
+
318
+ ## License
319
+
320
+ MIT. See the [LICENSE](LICENSE) file.