{
  "markdown": "<p align=\"center\">\n  <h1 align=\"center\">freshprobe</h1>\n  <p align=\"center\">\n    <strong>Data freshness verification for AI agents.</strong>\n    <br />\n    Stop your agents from acting on stale data.\n  </p>\n  <p align=\"center\">\n    <a href=\"https://github.com/Sudhan30/freshprobe/actions/workflows/ci.yml\"><img src=\"https://github.com/Sudhan30/freshprobe/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" /></a>\n    <a href=\"https://goreportcard.com/report/github.com/Sudhan30/freshprobe\"><img src=\"https://goreportcard.com/badge/github.com/Sudhan30/freshprobe\" alt=\"Go Report Card\" /></a>\n    <a href=\"https://github.com/Sudhan30/freshprobe/blob/main/LICENSE\"><img src=\"https://img.shields.io/github/license/Sudhan30/freshprobe\" alt=\"License\" /></a>\n    <a href=\"https://github.com/Sudhan30/freshprobe/releases\"><img src=\"https://img.shields.io/github/v/release/Sudhan30/freshprobe\" alt=\"Release\" /></a>\n    <img src=\"https://img.shields.io/badge/go-1.25-blue\" alt=\"Go Version\" />\n  </p>\n</p>\n\n---\n\n> *\"I asked my agent to check flight prices. It gave me options. I booked one. The fare had changed 3 hours ago.\"*\n\nAI agents routinely act on stale data without knowing it. A financial agent queries cached quotes from 47 minutes ago. A support bot tells a customer their order doesn't exist because the CRM hasn't synced. An RAG pipeline confidently answers with yesterday's docs.\n\n**freshprobe** sits between your agent and the external world. Before the agent acts, it asks: *is this data fresh enough?* The answer is always a deterministic JSON verdict: **FRESH**, **STALE**, or **UNKNOWN**.\n\n```\n$ freshprobe check https://api.example.com/v2/quotes\n\n{\n  \"verdict\": \"STALE\",\n  \"confidence\": 0.94,\n  \"endpoint\": \"https://api.example.com/v2/quotes\",\n  \"freshness\": {\n    \"data_age_seconds\": 2847,\n    \"freshness_score\": 0.12,\n    \"cache_control\": \"max-age=3600\"\n  },\n  \"liveness\": {\n    \"status\": \"DEGRADED\",\n    \"latency_p50_ms\": 342,\n    \"latency_p95_ms\": 1847,\n    \"body_size_bytes\": 4096,\n    \"error_rate\": 0.03\n  },\n  \"redirects\": {\n    \"total_hops\": 1,\n    \"final_url\": \"https://api-v2.example.com/quotes\",\n    \"has_redirect\": true\n  },\n  \"nist_mapping\": {\n    \"ai_rmf_function\": \"MEASURE\",\n    \"control\": \"MS-2.6-001\"\n  }\n}\n```\n\nSingle Go binary. No dependencies. Runs as CLI, MCP server, or HTTP microservice.\n\n## Why this matters\n\n| Problem | Cost |\n|---------|------|\n| E-commerce agent used 6-month-old product data | [$5M+ revenue loss](https://www.informatica.com/) |\n| Enterprise RAG with overlapping refresh infrastructure | $340K/year wasted |\n| AI project failures from data quality issues | [60%+ of failures (Gartner)](https://www.gartner.com/) |\n\nUnlike crashes that trigger alerts, stale data produces **confident, well-formatted, completely wrong responses**. Chain a few of those in a multi-agent pipeline and every component reports green while the output is catastrophically wrong.\n\n## Install\n\n**Go install (recommended):**\n\n```bash\ngo install github.com/Sudhan30/freshprobe/cmd/freshprobe@latest\n```\n\n**Docker:**\n\n```bash\ndocker run --rm ghcr.io/sudhan30/freshprobe:latest check https://example.com\n```\n\n**From source:**\n\n```bash\ngit clone https://github.com/Sudhan30/freshprobe.git && cd freshprobe && make build\n./bin/freshprobe --version\n```\n\n**GitHub Releases:** Download pre-built binaries for Linux, macOS, and Windows from [Releases](https://github.com/Sudhan30/freshprobe/releases).\n\n## Quick start\n\n```bash\n# Basic freshness check\nfreshprobe check https://api.example.com/data\n\n# Human-readable output\nfreshprobe check https://api.example.com/data --output text\n\n# Content fingerprinting: detect if data actually changes\nfreshprobe check https://api.example.com/data --repeat 3 --interval 2s\n\n# Check against a freshness policy\nfreshprobe check https://api.example.com/data --policy-dir ./policies --policy financial-data\n\n# Batch check multiple endpoints\nfreshprobe batch https://api1.example.com https://api2.example.com https://cdn.example.com\n\n# Continuous monitoring (Ctrl+C to stop)\nfreshprobe watch https://api.example.com/data --interval 30s --output text\n\n# Only alert on verdict changes (FRESH -> STALE)\nfreshprobe watch https://api.example.com/data --interval 1m --on-change --output text\n\n# View probe history for an endpoint\nfreshprobe history https://api.example.com/data --limit 20 --output text\n```\n\n## Six verification signals\n\n| Signal | What it checks |\n|--------|---------------|\n| **HTTP cache headers** | Parses `Last-Modified`, `Cache-Control`, `Age`, `ETag`, `Date`, `Expires`. Computes 0.0 to 1.0 freshness score |\n| **Endpoint liveness** | Measures response latency (P50/P95/P99), status codes, body size, degradation patterns |\n| **Content fingerprinting** | SHA-256 hashes response bodies across repeated probes to detect stale caches |\n| **TLS certificate health** | Certificate validity, days remaining, OCSP stapling status |\n| **DNS resolution timing** | DNS lookup latency as infrastructure health signal |\n| **Redirect chain analysis** | Tracks 301/302/307/308 hops, detects stale CDN configs |\n\n## Three deployment modes\n\n### CLI\n\n```bash\nfreshprobe check <url> [flags]\nfreshprobe batch <urls...> [flags]\nfreshprobe watch <url> --interval 30s [flags]\nfreshprobe history <url> --limit 20\n```\n\n### MCP server (for AI agents)\n\nAdd to your AI tool config:\n\n<details>\n<summary><strong>Claude Desktop / Claude Code</strong></summary>\n\n```json\n{\n  \"freshprobe\": {\n    \"type\": \"stdio\",\n    \"command\": \"freshprobe\",\n    \"args\": [\"serve\", \"--mode\", \"mcp\", \"--policy-dir\", \"/path/to/policies\", \"--stateless\"]\n  }\n}\n```\n</details>\n\n<details>\n<summary><strong>Cursor</strong></summary>\n\nIn `.cursor/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"freshprobe\": {\n      \"command\": \"freshprobe\",\n      \"args\": [\"serve\", \"--mode\", \"mcp\", \"--stateless\"]\n    }\n  }\n}\n```\n</details>\n\n<details>\n<summary><strong>VS Code (Copilot)</strong></summary>\n\nIn `.vscode/mcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"freshprobe\": {\n      \"type\": \"stdio\",\n      \"command\": \"freshprobe\",\n      \"args\": [\"serve\", \"--mode\", \"mcp\", \"--stateless\"]\n    }\n  }\n}\n```\n</details>\n\nThis exposes three tools to AI agents:\n\n| Tool | Description |\n|------|-------------|\n| `freshprobe_check` | Probe a single endpoint. Returns JSON verdict |\n| `freshprobe_batch` | Probe multiple endpoints concurrently |\n| `freshprobe_policy` | Check an endpoint against a named freshness policy |\n\n### HTTP server\n\n```bash\nfreshprobe serve --mode http --addr :8080\n```\n\n```\nPOST /api/v1/check    {\"url\": \"https://...\"}\nPOST /api/v1/batch    {\"urls\": [\"https://...\", \"https://...\"]}\nPOST /api/v1/policy   {\"url\": \"https://...\", \"policy_name\": \"api-realtime\"}\nGET  /healthz\nGET  /metrics          # Prometheus-compatible metrics\n```\n\n## Policies (freshness-as-code)\n\nDefine freshness thresholds per domain in YAML:\n\n```yaml\nversion: \"1\"\npolicies:\n  financial-data:\n    name: \"Financial Data\"\n    domains: [\"*.market.*\", \"*.trading.*\"]\n    max_staleness: \"30s\"\n    min_freshness_score: 0.9\n    max_latency_p95_ms: 200\n    require_tls: true\n    min_tls_days_left: 30\n    require_changing: true\n\n  api-standard:\n    name: \"Standard API\"\n    domains: [\"api.*\"]\n    max_staleness: \"5m\"\n    min_freshness_score: 0.6\n    max_latency_p95_ms: 2000\n    require_tls: true\n```\n\nWhen a probe violates a policy:\n\n```json\n{\n  \"policy_result\": {\n    \"policy_name\": \"Financial Data\",\n    \"passed\": false,\n    \"violations\": [\n      {\"check\": \"max_staleness\", \"expected\": \"<= 30s\", \"actual\": \"2m15s\"},\n      {\"check\": \"max_latency_p95\", \"expected\": \"<= 200 ms\", \"actual\": \"847 ms\"}\n    ]\n  }\n}\n```\n\nFour built-in policies included: `api-realtime`, `api-standard`, `static-content`, `financial-data`.\n\n## Continuous monitoring\n\n```bash\n# Watch an endpoint, print every probe\nfreshprobe watch https://api.example.com/quotes --interval 30s --output text\n\n# Only print when verdict changes (FRESH -> STALE transitions)\nfreshprobe watch https://api.example.com/quotes --interval 1m --on-change --output text\n\n# Run 10 probes and exit\nfreshprobe watch https://api.example.com/quotes --count 10 --interval 5s\n```\n\nExample output:\n```\nWatching https://api.example.com/quotes every 30s\n[14:22:01] FRESH conf=0.90 score=0.87 p95=142ms\n[14:22:31] FRESH conf=0.90 score=0.85 p95=156ms\n[14:23:01] STALE conf=0.85 score=0.22 p95=1847ms [FRESH -> STALE]\n```\n\n## Prometheus metrics\n\nThe HTTP server exposes `/metrics` with Prometheus-compatible text format:\n\n```\nfreshprobe_probes_total 142\nfreshprobe_verdict_total{verdict=\"FRESH\"} 98\nfreshprobe_verdict_total{verdict=\"STALE\"} 31\nfreshprobe_verdict_total{verdict=\"UNKNOWN\"} 13\nfreshprobe_latency_p95_seconds 0.234000\nfreshprobe_freshness_score 0.7200\n```\n\n## How it compares\n\n| Feature | freshprobe | Uptime Kuma | Gatus | freshcontext-mcp |\n|---------|-----------|-------------|-------|-----------------|\n| **Purpose** | Data freshness for AI agents | Uptime monitoring | Health dashboards | Web extraction timestamps |\n| **Knows data is stale** | Yes (cache headers + fingerprinting) | No (only checks HTTP status) | No (only checks response assertions) | Partial (timestamps, no verification) |\n| **MCP server** | Yes (3 tools) | No | No | Yes |\n| **Policy engine** | Yes (YAML, per-domain) | No | Yes (YAML conditions) | No |\n| **Continuous monitoring** | Yes (`watch` command) | Yes (dashboard) | Yes (dashboard) | No |\n| **Prometheus metrics** | Yes | No (push-based) | Yes | No |\n| **Deployment** | Single binary | Docker + DB | Single binary | npm package |\n\n## Architecture\n\n```\n                    +------------------+\n                    |   freshprobe     |\n                    |   single binary  |\n                    +--------+---------+\n                             |\n              +--------------+--------------+\n              |              |              |\n         +----+----+   +----+----+   +-----+-----+\n         |   CLI   |   |   MCP   |   |   HTTP    |\n         | (cobra) |   | (stdio) |   | (net/http)|\n         +---------+   +---------+   +-----------+\n              |              |              |\n              +--------------+--------------+\n                             |\n                    +--------+---------+\n                    |   Probe Engine   |\n                    |                  |\n                    | HTTP headers     |\n                    | Latency P50/95/99|\n                    | Content SHA-256  |\n                    | TLS/OCSP        |\n                    | DNS timing       |\n                    | Redirect chains  |\n                    +--------+---------+\n                             |\n              +--------------+--------------+\n              |              |              |\n         +----+----+   +----+----+   +-----+-----+\n         | Verdict |   | Policy  |   |   Store   |\n         | Engine  |   | Engine  |   | SQLite /  |\n         |         |   | (YAML)  |   | Stateless |\n         +---------+   +---------+   +-----------+\n```\n\n## Kubernetes deployment\n\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: freshprobe\nspec:\n  replicas: 1\n  selector:\n    matchLabels: { app: freshprobe }\n  template:\n    metadata:\n      labels: { app: freshprobe }\n    spec:\n      containers:\n        - name: freshprobe\n          image: ghcr.io/sudhan30/freshprobe:latest\n          args: [\"serve\", \"--mode\", \"http\", \"--addr\", \":8080\",\n                 \"--policy-dir\", \"/etc/freshprobe/policies\", \"--stateless\"]\n          ports:\n            - containerPort: 8080\n          resources:\n            requests: { cpu: 50m, memory: 64Mi }\n            limits: { cpu: 200m, memory: 128Mi }\n          readinessProbe:\n            httpGet: { path: /healthz, port: 8080 }\n          livenessProbe:\n            httpGet: { path: /healthz, port: 8080 }\n```\n\n## Claude Code plugin\n\n```\n/plugin install github:Sudhan30/freshprobe\n```\n\nAfter installing, ask Claude:\n- *\"Is the trading API returning fresh data?\"*\n- *\"Check all our endpoints before running the batch job\"*\n- *\"Does this API meet our real-time SLA?\"*\n\n## Development\n\n```bash\nmake build       # Build binary\nmake test        # Run tests with race detector\nmake lint        # go vet\nmake cross       # Cross-compile (linux, macOS, Windows)\nmake docker      # Docker build\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). High-value areas:\n- Policy packs for specific domains (healthcare, weather, finance)\n- WebSocket/gRPC/GraphQL probe signals\n- OpenTelemetry integration\n- Homebrew formula\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n---\n\n<p align=\"center\">\n  If freshprobe helps your agents make better decisions, <a href=\"https://github.com/Sudhan30/freshprobe\">give it a star</a>.\n</p>\n",
  "bytes": 12620,
  "sha": "3152696d19a4f380d3dd294f7556caed5824186e0913c42ad2f7f1578acf56e3",
  "repo_slug": "sudhan30/freshprobe",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/plg_sudhan30_freshprobe_freshprobe_fe777e46/readme"
}