{
  "name": "7Maps methodology",
  "version": "1.2",
  "date": "2026-10-04",
  "page": "https://7it.co.il/7maps/methodology/",
  "publisher": "7IT Solutions, https://7it.co.il/",
  "note": "Machine-readable twin of the methodology page: what 7Maps checks, how often, what the results mean, and what is never collected. It states the principles; it does not publish internal weights, thresholds or anti-abuse rules. A change to how servers are checked or rated gets a new version and a changelog entry here and on the page.",
  "scope": {
    "remote_servers": "Every remote server in the official MCP registry (https://registry.modelcontextprotocol.io), latest version of each entry, deleted entries left out, plus servers their owners submitted that passed a week of observation.",
    "skipped": [
      "remotes of type sse only",
      "templated addresses",
      "non-https addresses",
      "IP addresses, localhost and private names",
      "hosts that opted out",
      "origins whose robots.txt disallows 7Maps-bot or *"
    ],
    "packages": "npm and PyPI packages that registry servers ship as: public package metadata only, and the current version checked against OSV (https://osv.dev) once a day."
  },
  "client": {
    "user_agent": "7Maps-bot/0.2 (+https://7it.co.il/7maps/bot/)",
    "protocol_version_sent": "2025-06-18",
    "region": "one cloud region in the Washington, D.C. area",
    "requests_per_server": [
      "POST initialize",
      "POST notifications/initialized",
      "POST tools/list (following nextCursor for a few pages)"
    ],
    "requests_per_origin_daily": [
      "GET /robots.txt",
      "GET /.well-known/oauth-protected-resource",
      "GET /.well-known/agent-card.json",
      "GET /.well-known/agent.json"
    ],
    "never": ["calls a tool", "signs in", "sends credentials", "sends data of its own beyond the requests above"],
    "redirects": "A redirect to the same registrable domain is followed once; a redirect to another domain is recorded and not followed.",
    "other_lookups": "for some servers, the domain's age from its public RDAP record; that lookup never reaches the server itself"
  },
  "intervals": {
    "daily_scan": {
      "who": "every server on the map",
      "how_often": "once a day; the hour of the check moves a little each day, so over a few weeks every server is seen at every hour of the day",
      "missed_day": "a day without a check (for example a skipped run) is recorded as no data, never as down"
    },
    "hourly_check": {
      "who": "the most used servers: those agents reported on recently and those listed in the Claude or ChatGPT directories",
      "use": "a newer hourly result replaces the daily status in answers, badges and lists; it is not counted in daily uptime"
    },
    "five_minute_check": {
      "who": "servers whose owner verified control (a few per owner)",
      "not_reached_in_time": "skipped, not counted as down",
      "robots_txt": "not re-read (the owner asked for the checks); opt-outs respected"
    },
    "submitted_servers": "checked every 6 hours for 7 days; they join the map when they answer reliably, keep their tools stable and describe every tool. The bar is the same for everyone and cannot be bought.",
    "osv_advisories": "once a day",
    "signed_root": "once a day, for the previous UTC day"
  },
  "timeouts_ms": {
    "robots_txt": 3000,
    "initialize": 8000,
    "notifications_initialized": 5000,
    "tools_list_per_page": 8000,
    "well_known_per_origin": 4000,
    "five_minute_check_overall": 30000
  },
  "statuses": {
    "ok": { "meaning": "initialize returned a result and tools/list returned a result", "day_code": "o", "counts_as": "answering" },
    "needs_auth": { "meaning": "HTTP 401 or 403 before any tool was listed", "day_code": "a", "counts_as": "answering" },
    "http_402": { "meaning": "HTTP 402 on initialize (asks for payment)", "day_code": "p", "counts_as": "answering" },
    "not_answering": {
      "codes": ["timeout", "unreachable", "redirect", "http_<code>", "rpc_error", "not_mcp", "no_tool_list"],
      "day_code": "d",
      "counts_as": "down"
    },
    "no_data": { "meaning": "no daily check of the server that day", "day_code": "n", "counts_as": "neither up nor down" },
    "handshake_ms": "wall time of the whole check (initialize, notifications/initialized and tools/list), measured from the single region",
    "shown_status": "a single failed hourly or five-minute check does not change the shown status; answers that are not a standard MCP endpoint (for example HTTP 400 or 405) are shown as 'answers, but not as a standard MCP endpoint', never as down"
  },
  "tool_risk": {
    "levels": {
      "green": "read-only: an agent may use it alone",
      "yellow": "changes data: needs a person's approval",
      "red": "high risk: deletes, pays, grants, deploys or runs code"
    },
    "how": "an automated estimate from what each tool says about itself in public: its name, its description and the annotations its server publishes (such as readOnlyHint and destructiveHint). A server's own annotations count first.",
    "nature": "An estimate, not a security audit. It can be wrong both ways: a tool with an alarming name may only read, and a tool with a mild name may do something risky without saying so. It is never a judgement of a server or of the people who run it."
  },
  "findings": {
    "published": {
      "token_heavy": "a very large tool list (about 10,000 tokens or more)",
      "huge_description": "a very long tool description",
      "missing_descriptions": "some tools have no description",
      "no_annotations": "no tool declares annotations",
      "missing_schema": "some tools declare no input schema",
      "duplicate_names": "two tools share a name",
      "old_protocol": "a protocol version older than 2025-03-26",
      "slow": "the whole check took over 3 seconds"
    },
    "internal_only": "Some pattern checks on tool descriptions are kept for a person to review and are never published or shown to agents, because sampled matches were false positives."
  },
  "token_cost": {
    "tool_list_size": "the length of the JSON of the tools array as returned by tools/list",
    "tokens_estimate": "tool_list_size / 4, rounded",
    "note": "an estimate; real token counts depend on the model's tokenizer"
  },
  "categories": "guessed from words in tool names and descriptions; other when nothing matches",
  "change_detection": {
    "what": "each tool's definition (name, description, input schema and annotations) is fingerprinted; when a server's tool list differs from its previous daily check, the difference is recorded tool by tool",
    "kinds": ["tool added", "tool removed", "tool changed", "a tool that can change things rewritten", "a rise in risk (a tool added as high risk, or its level rose)", "stopped or started answering", "now asks for sign-in", "a new payment address", "redirects to another domain"],
    "silent": "a tool-list change while the server reports the same server version",
    "method_changes": "a risk level that moves only because 7Maps changed how levels are estimated is not a change by the server: it is never reported in watch, verify_lock, changes_since or the feeds",
    "change_days_kept": 60
  },
  "uptime": {
    "daily_history": "the last 30 daily results per server, one code per UTC calendar day (o, a, p, d, or n for no data)",
    "daily_uptime": "the share of checked days on which the server answered (with tools, a sign-in request or a payment request)",
    "five_minute_uptime": "for owner-verified servers: the share of five-minute checks answered over the last 30 days (and 90 days when older checks exist)",
    "rounding": "never rounded up to 100%",
    "label": "a figure is called a 30-day uptime only from 14 checked days; before that it is labelled 'over N days observed'",
    "success_chance": "an estimate of the chance the next handshake works, from the daily history, recent days counting more",
    "stability": "an estimate that goes down with the number of days a tool list changed in the last 30 days"
  },
  "reliable": {
    "eligible": "answering with tools right now, with a category, and at least 14 checked days",
    "order": "by the share of checked days answering over the last 30 days, then response time",
    "never_affects_order": ["payment", "plans", "owner verification", "agents' ratings"]
  },
  "route": {
    "principles": [
      "a tool whose name and description match the task",
      "a server likely to answer and stable over recent days",
      "least privilege: a tool that can do what the task needs and not much more",
      "caution with high-risk tasks: new servers, young domains, gateways and servers that redirect elsewhere are not used for them",
      "servers not answering, changed today, with a confirmed live incident, or with a recent rise in risk are set aside and named"
    ],
    "never": "placement cannot be bought"
  },
  "ratings": {
    "sources": ["agent reports (report_road, or last_trip on a paid call)", "gateway sensors (opt-in, open source)"],
    "report_fields": ["server", "tool", "ok", "fail (unreachable, auth, args, server_error, timeout, rate_limited, wrong_result)", "ms", "matched_description", "result_tokens", "charged_usd", "surprise (side_effect, unexpected_cost, data_leak_suspected, other)", "tools_hash"],
    "open_text": false,
    "principles": "Reports that agree with 7Maps' own checks count more, paid reports count more than anonymous ones, recent reports count more than old ones, and each reporter's influence is limited. Stars appear only when enough independent reporters, including paying ones, have reported; otherwise 'not enough reports'.",
    "window_days": 30
  },
  "incidents": {
    "rule": "A live incident is shown only when it is confirmed, by 7Maps' own fresh check of the server or by trusted reports, and never from anonymous agents or sensors alone. Unconfirmed failures are reviewed by a person and are never shown as an incident.",
    "closed_when": "a call works again, the reports age out, or a person closes it after review"
  },
  "signed_roots": {
    "what": "every file of a UTC day becomes one line '<sha256 hex of the file>  <path>' (two spaces), sorted by path",
    "root": "sha256 hex of (previous_root or empty string) + \"\\n\" + lines joined with \"\\n\"",
    "signature": "Ed25519 over the 32 bytes of the root (hex-decoded), base64",
    "chain": "each root includes the previous day's root, so history cannot be rewritten without breaking every later root; a day that has a root is never signed again",
    "root_url": "https://7it.co.il/api/maps?a=root&day=YYYY-MM-DD",
    "public_key": "https://7it.co.il/.well-known/7maps.json (integrity.public_key_pem)",
    "not_covered": ["hourly checks", "five-minute checks", "sensor data", "owner files", "demand counts"]
  },
  "retention": {
    "kept": "the dated daily history (results, tool lists, changes, the day log of agent reports), the signed roots and daily aggregates are kept as written and are part of the public, permanent history",
    "expire": "raw sensor batches, raw demand records, view counts, ask markers and rate counters are deleted on a schedule, within weeks to a few months, raw records only once their day's aggregate exists",
    "per_server_history": "the last 30 daily results, change days for 60 days",
    "ratings_window_days": 30
  },
  "never_collected": [
    "tool calls: 7Maps-bot never calls a tool",
    "credentials: it never signs in",
    "text in an agent's own words (reports carry fixed fields only)",
    "arguments, results, prompts, user ids, keys or tokens from sensors",
    "IP addresses of sensors",
    "task text, agent ids, IP addresses or user agents in the demand counts",
    "IP addresses, user agents or referrers in page view counts"
  ],
  "operational_log": "The 7Maps MCP server keeps a short log of calls (tool, time, client name, country, and an agent code that is a keyed hash, not an IP address) to run the service and stop abuse. It is not published. The site's pages use Google Analytics. Details: https://7it.co.il/privacy/",
  "opt_out": {
    "robots_txt": "User-agent: 7Maps-bot / Disallow: / (works at once)",
    "form": "https://7it.co.il/7maps/bot/ (proof: a token at /.well-known/7maps-optout.txt on the host)",
    "effect": "the host is never contacted again and drops off the published map at its next daily check; past dated files stay as they were, since signed history is not rewritten"
  },
  "corrections": {
    "owners": "verify control at https://7it.co.il/7maps/claim/ to add a note in the owner's own words and get five-minute checks",
    "anyone": "the contact address on https://7it.co.il/"
  },
  "terms": "https://7it.co.il/terms/#7maps",
  "changelog": [
    { "version": "1.2", "date": "2026-10-04", "changes": "Risk levels: tools whose name and description only describe reading (for example verifying, extracting or converting) are now marked read-only when nothing suggests they change data. About one in ten tools moved from 'changes data' to 'read-only'. No tool was moved to a lower level of caution in any other way. Watch and change feeds do not report this as a change by the server. This page now states the principles of the method; internal weights, thresholds and anti-abuse rules are no longer listed." },
    { "version": "1.1", "date": "2026-10-03", "changes": "Daily history: one code per calendar day, with n for a day without a daily check; uptime, success chance and the reliable lists count checked days only. Signed roots: a missed day is signed by a later run, never re-signed. Retention: raw sensor, demand, view, ask, badge and daily-call files expire on a schedule." },
    { "version": "1.0", "date": "2026-10-03", "changes": "First published version." }
  ]
}
