|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This is the canonical repository guide for every coding agent and harness working on `tiingo-mcp`. `CLAUDE.md` is a symlink to this file so the guidance stays identical across tools. |
| 4 | + |
| 5 | +## Operating rules |
| 6 | + |
| 7 | +- Keep the implementation Rust-only. Do not reintroduce Python packaging, virtual environments, or `uvx` compatibility. |
| 8 | +- Preserve the public MCP contract unless the task explicitly changes it: 17 tools, three fixed resources, one resource template, five prompts, stdio transport, and `TIINGO_API_KEY` authentication. |
| 9 | +- Keep stdout protocol-only. Send diagnostics to stderr and never log credentials or authorization headers. |
| 10 | +- Make surgical changes and preserve unrelated user work. Inspect `git status` before editing. |
| 11 | +- Do not run the quota-consuming live test without explicit authorization. |
| 12 | +- Do not publish crates, create or push tags, create releases, or upload MCPB bundles without explicit authorization. |
| 13 | + |
| 14 | +## Commands |
| 15 | + |
| 16 | +```bash |
| 17 | +cargo fmt --check |
| 18 | +cargo clippy --all-targets --all-features -- -D warnings |
| 19 | +cargo test --all-targets --locked |
| 20 | +cargo build --release --locked |
| 21 | +cargo deny check |
| 22 | +cargo run --quiet -- --version |
| 23 | +TIINGO_API_KEY=key cargo run --quiet |
| 24 | +dist plan |
| 25 | +``` |
| 26 | + |
| 27 | +The test suite binds local mock HTTP servers. The ignored live-smoke test consumes quota and must be invoked deliberately with `TIINGO_API_KEY`. |
| 28 | + |
| 29 | +To build an MCPB bundle from an existing target binary directory: |
| 30 | + |
| 31 | +```bash |
| 32 | +bash packaging/mcpb/package.sh <target-triple> <binary-directory> |
| 33 | +``` |
| 34 | + |
| 35 | +## Architecture |
| 36 | + |
| 37 | +This is a native RMCP stdio server wrapping the Tiingo financial-data REST API. |
| 38 | + |
| 39 | +- `src/main.rs` parses the CLI, initializes stderr-only tracing, and starts the RMCP stdio service. `--help` and `--version` exit without starting MCP. |
| 40 | +- `src/lib.rs` exports the server modules used by the binary and integration tests. |
| 41 | +- `src/config.rs` loads `TIINGO_API_KEY` lazily so discovery, resources, and prompts work without credentials. |
| 42 | +- `src/client/mod.rs` owns the shared `reqwest::Client`, request bounds, retry policy, same-origin enforcement, and family-specific clients. |
| 43 | +- `src/client/{eod,iex,forex,crypto,news,fundamentals,corporate_actions}.rs` maps tool inputs to exact Tiingo routes and query parameters. |
| 44 | +- `src/client/query.rs` serializes optional query values without sending absent fields. |
| 45 | +- `src/error.rs` classifies configuration, validation, transport, HTTP, and response-size failures and maps them to sanitized MCP tool errors. |
| 46 | +- `src/mcp/tools.rs` exposes the 17 typed tools and returns both legacy JSON text and structured content. |
| 47 | +- `src/mcp/resources.rs` serves three fixed resources plus the `tiingo://guide/{asset_class}` template from embedded JSON under `src/mcp/data/`. |
| 48 | +- `src/mcp/prompts.rs` exposes the five compatible, corrected analysis prompts. |
| 49 | + |
| 50 | +## Runtime contracts |
| 51 | + |
| 52 | +- `tiingo-mcp` uses stdio transport by default. Protocol output belongs on stdout; diagnostics belong on stderr. |
| 53 | +- Closing stdin must terminate the process promptly and without stdout noise. |
| 54 | +- The credential contract is `TIINGO_API_KEY`. Never log it or the authorization header. |
| 55 | +- Requests must remain on the configured Tiingo origin, retry at most three total attempts, and enforce the 8 MiB decoded-response limit. |
| 56 | +- Recoverable tool failures set MCP `isError: true` while retaining the sanitized JSON text block expected by older clients. |
| 57 | +- Optional MCP tool inputs use closed JSON schemas and omit absent Tiingo query parameters. |
| 58 | + |
| 59 | +## Tests |
| 60 | + |
| 61 | +- `tests/client_http.rs` covers authentication, validation, retries, redaction, origin safety, and response bounds. |
| 62 | +- `tests/client_market_routes.rs` and `tests/client_data_routes.rs` cover exact REST paths and query mappings. |
| 63 | +- `tests/mcp_contract.rs` compares discovery against `tests/contract/baseline/python-mcp.json`, the historical v1 parity oracle, plus only the approved correctness deltas. |
| 64 | +- `tests/mcp_tools.rs`, `tests/mcp_resources.rs`, and `tests/mcp_prompts.rs` cover the RMCP surface. |
| 65 | +- `tests/stdio_process.rs` covers negotiation, stdout purity, CLI behavior, and EOF shutdown in a child process. |
| 66 | +- `tests/live_smoke.rs` keeps offline validators enabled and the quota-consuming live test ignored by default. |
| 67 | +- `examples/migration_probe.rs` contains the reproducible startup, process-tree RSS, and wrapper-latency probe. |
| 68 | + |
| 69 | +## Distribution |
| 70 | + |
| 71 | +`cargo-dist` produces shell and PowerShell installers and native artifacts for: |
| 72 | + |
| 73 | +- `aarch64-apple-darwin` |
| 74 | +- `x86_64-apple-darwin` |
| 75 | +- `aarch64-unknown-linux-musl` |
| 76 | +- `x86_64-unknown-linux-musl` |
| 77 | +- `x86_64-pc-windows-msvc` |
| 78 | + |
| 79 | +Each native CI job builds and validates an MCPB 0.3 bundle. Release automation is tag-triggered. |
| 80 | + |
| 81 | +## Release preparation |
| 82 | + |
| 83 | +- Keep the version synchronized in `Cargo.toml`, the root `tiingo-mcp` entry in `Cargo.lock`, and `packaging/mcpb/manifest.json`. |
| 84 | +- Add the matching `CHANGELOG.md` section as `X.Y.Z (Unreleased)` while changes are accumulating. |
| 85 | +- Before creating the release tag, replace `Unreleased` with the release date. cargo-dist uses that heading for the GitHub Release title; tagging first will publish an incorrect `(Unreleased)` title. |
| 86 | +- Keep current-release URLs in `README.md` pointed at the latest published tag until the replacement release exists. |
| 87 | +- Run the full verification set plus `dist plan` and `cargo publish --dry-run --locked` before requesting release authorization. |
0 commit comments