supercarto

io.github.Unselfisheologism由 GitHub 帳號 Unselfisheologism 發布v0.7.0更新於 Nov 6, 2026

Token-budgeted map context: OSM graph, terrain, weather, air, transit

概覽

AI 產生的概覽

把 OpenStreetMap、地形、天氣、空氣、日照與大眾運輸資料編譯成受 token 預算限制的 YAML 地圖圖結構,供助理直接推理。

可以做什麼
  • 依座標與半徑編譯出符合 token 預算的精簡拓撲地圖,含距離、方向與被省略圖層的紀錄
  • 搜尋地點、展開單一圖徵的精確幾何、給出兩點間的可行情報路線
  • 查詢某地的天氣、空氣品質、日照與地形
  • 設定車流服務金鑰後可取得即時路況
  • 從 GTFS 資料來源查詢站牌、班次、下一班發車與經認證的乘車方案,設定即時資料來源後附上誤點
適用情境
當助理需要空間脈絡——附近有什麼、多遠、往哪個方向、是否下雨或空氣不好、大眾運輸行程是否可行——又不想為原始 GeoJSON 花掉大量 token 時適用。也適合室內樓層圖與依時刻表判斷的大眾運輸問題。
執行需求
透過 npm 或 PyPI 以 stdio 在本機執行,硬性需求只有 Node 18 以上版本。預設需連線 Overpass、OSRM、Open-Meteo 與 Terrarium 圖磚。選用環境變數可啟用額外資料來源:SUPERCARTO_PMTILES、SUPERCARTO_GTFS、SUPERCARTO_GTFS_RT,以及供路況工具使用的 SUPERCARTO_OWM_KEY。預設資料來源不需帳號。
安裝前請注意
路況需要 TomTom 或 HERE 金鑰,未設定時該工具不會出現在工具清單中;此時路線只提供標示為自由車流的估算,而非即時路況。免費的 Open-Meteo 額度僅限非商業用途(每日少於 1 萬次呼叫),商業部署需自備訂閱。GTFS 資料來源可能有各機構自訂的授權條款。Overpass 有速率限制且較慢(每次 15-40 秒)。大型運輸資料來源會整份載入記憶體,可能需要調高 Node 堆積上限。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 supercarto,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

supercarto

mcp-name: io.github.Unselfisheologism/supercarto

[skills.sh]

LLM-native spatial middleware. Compiles geospatial data into token-budgeted topological graphs that an AI agent can reason over directly.

Give an agent a map without paying the token tax. One file in, both numbers out: examples/synthetic-dense.geojson is 272,993 bytes (~68,000 tokens) raw and compiles at a 1024-token budget to about 890 tokens - 26 nodes (10 named) on 34 edges (streets plus access links), ~99% smaller. Rerun it yourself: supercarto compile examples/synthetic-dense.geojson --budget 1024. Token counts are character-based estimates on a fixed test file; the sun and timestamp lines shift them by a few tokens run to run.

bash
npm install supercartopip install supercarto      # Python client, talks MCP over stdio

Give it coordinates

This is the whole product:

ts
import { SuperCarto } from 'supercarto';
const carto = new SuperCarto();
const result = await carto.maplet({  lat: 35.6833,  lon: 139.7620,  radiusM: 400,  budget: 1500,});
console.log(result.yaml);

The same file from the headline, compiled below (truncated output; warnings travel inside the map, where an agent reading only the map sees them):

yaml
map:  center: "37.7749, -122.4194"  source: geojson  note: Simplified for reasoning; call expand_feature for exact geometry.nodes:  n530: {type: poi, name: Bank 0, tags: [bank]}  n531: {type: poi, name: Cafe 1, tags: [cafe]}  n673: {type: transit, name: Station 0, tags: [subway_entrance]}edges:  n515->n516: {dist: 80m, dir: east, path: road}  n516->n517: {dist: 80m, dir: east, path: road}omitted:  - {layer: building, count: 259}  - {layer: poi, count: 141}  - {layer: road, count: 441}tools:  - expand_feature(id)

That is about 890 tokens for the whole extract at a 1024 budget: every drop named by layer, nothing silently vanished.


The problem

You want an agent to know where things are and how to get between them. Three options, all bad:

  • Paste GeoJSON into the prompt. Thousands of tokens per block. The model reasons badly about raw coordinates and will hallucinate them.
  • Call a map API. You get back the same GeoJSON. The token cost is unchanged; only the HTTP round trip differs.
  • Invent a compact wire format and teach the model to read it. A novel grammar in a context window produces hallucinated coordinates and tokens burned inferring the grammar. A model was not trained on your format.

supercarto takes the third option seriously and solves it the only way it can be solved: the model never reads the wire format.

  coordinates          live sources             reasoning format  35.68, 139.76  ──▶  Overpass / PMTiles  ──▶  topological YAML graph                                           distances in metres,                                           compass directions,                                           built for models

The wire format is a spec you own, optimized for machines. The reasoning format is standard YAML in flow style, using only constructs a model has read billions of times. A deterministic compiler in the middleware does the translation.


An agent works for a person

The person is standing outside. Rain and traffic change whether the trip happens at all, so those are first-class layers here, not an afterthought bolted onto a routing engine.

Weather

No API key. No account. No billing.

ts
const w = await carto.weatherAt(35.6833, 139.7620, 12);
w.now.summary;          // "heavy rain"w.now.precipitation;    // "rain" | "snow" | "sleet" | "hail" | "drizzle"w.now.feelsLikeC;       // what they actually feel
$ supercarto weather --lat 35.6833 --lon 139.762now  clear night, 23.2C (feels 26.9C), wind 4.3km/h, precip none  2026-10-01T13:00:00Z  22.7C  none      3.5km/h  2026-10-01T14:00:00Z  22.1C  none      3.1km/h

The MCP tool returns prose rather than fields, because a model repeats "it is raining, take the bus" reliably and re-derives it from twelve numbers unreliably.

When the source is unreachable it returns NaN for every reading and sets degraded, and the tool raises. It does not return zeroes. An agent handed precipitationMm: 0 concludes the weather is dry and sends someone cycling into a storm.

Traffic

ts
const t = await carto.routeWithTraffic({ from, to, mode: 'drive' });
t.freeFlowOnly;   // true when no flow credential is configuredt.worstLevel;     // "severe" - the segment that makes someone latet.delayS;

Traffic needs a credential, so get_traffic is absent from the tool list until you set one. With no key the routing path reports free-flow and labels it:

$ supercarto traffic --from 37.7749,-122.4194 --to 37.7849,-122.4194traffic: unknown (no flow source configured)free-flow estimate: 244s, ignores congestionnote: set TOMTOM_API_KEY or HERE_API_KEY for live conditions

A free-flow estimate for a congested route is worse than no answer, because the person leaves on the schedule the agent gave them. Presenting one as live is the single most damaging thing this library could do, so it does not.

Set TOMTOM_API_KEY or HERE_API_KEY and it becomes live, reporting the worst segment rather than an average.

Air quality

Same keyless contract as weather, one pollutant further:

ts
const a = await carto.airAt(35.6833, 139.7620, 12);
a.now.europeanAqi;      // 62 - the raw indexa.now.pm25UgM3;         // 28.1 - the fraction that sends asthmatics indoorsa.hourly;               // forward-looking window, trimmed at "now"
$ supercarto air --lat 35.6833 --lon 139.762now  air poor (AQI 62 EU, 65 US), PM2.5 28.1µg/m³, PM10 29.7µg/m³     gases above good range: NO2 63.5µg/m³  2026-10-27T08:00:00Z  AQI 74  33.4µg/m³ PM2.5  2026-10-27T09:00:00Z  AQI 55  21.2µg/m³ PM2.5

The MCP answer names a gas only when it clears its own good bound on the European scale, so a clean day costs four tokens instead of twelve. Every answer carries the distance to the model's sample grid, because a metro with one diesel corridor out of four is not one number. A missing gas reading renders as unknown, never as 0: a zero invented from a gap is how a tool certifies airspace as clean.

Indoor floors

Nobody else publishes this. Google builds indoor maps for its own users and has no reason to hand a third-party agent a clean floor-by-floor graph; Mapbox has nothing comparable; every MCP wrapper returns the same flat GeoJSON.

yaml
indoor:  storeys: 0,1,2  multi_storey: true  0: {label: ground, rooms: 12}    L0n1: {type: corridor}    L0n2: {type: shop, name: "Blue Bottle"}    L0n1->L0n2: {dist: 11m}  v1: {type: lift, levels: [0,1,2], wheelchair: true}  missing: [1]

Lifts are collapsed across storeys into one vertical link. Rooms only connect to corridors on the same floor — an edge through a concrete slab would send someone through a floor. A room more than 40m from any corridor is left unattached, because a straight line through intervening walls is worse than no edge. Untagged storeys are reported as missing rather than invented.

Transit schedules

Set SUPERCARTO_GTFS to any static GTFS feed (an unzipped directory or a .zip) and get_transit appears: stops, lines, and a service window for the queried day. It is the one agent map tool that answers "can you be somewhere by 9" from an actual schedule, and every agency's failure mode is covered by an honest state rather than a guess:

yaml
transit:  center: "36.913, -116.77"  radius: 3.0km  feed: sample-feed  note: Stop distances are straight-line. Schedule from GTFS feed for 2007-01-11 in America/Los_Angeles.nodes:  STAGECOACH: {type: stop, name: "Stagecoach Hotel & Casino", tags: [bus], routes: ["30", "40"], first: 06:00, last: 06:58}  NADAV: {type: stop, name: "North Ave / D Ave N", tags: [bus], routes: ["40"], first: 06:14, last: 06:44}edges:  NADAV->DADAN: {dist: 601m, dir: south, path: bus 40}
  • Three service states, never two. Running today shows routes and first/last departures. A date with nothing running keeps the stops with routes: [] — no transit is not no stops — and the note says so. A feed without a calendar shows the whole network and says the service window is unknown instead of presenting whole-feed data as today's schedule.
  • Times past midnight stay past midnight. GTFS expresses a departure after the service day's midnight as hours beyond 24 (25:10). Rendering that as 01:10 fits the eye and misleads the decision, so it renders as recorded, in the feed's own timezone.
  • Edges are structure; schedules attach to nodes. The adjacency survives a no-service day because an agent walking between stops still wants it.
  • Live delays when you point GTFS-Realtime at it. Set SUPERCARTO_GTFS_RT to the agency's TripUpdates URL and predictions join onto the schedule: node lines gain a live: attribute such as bus 16 +300s or bus 16 cancelled, and the note says how fresh the feed is. Spec precedence holds — an explicit stop update beats the trip-level delay; absolute-time predictions convert through the feed's timezone. The honesty rule that matters most: a stop with no live entry is unknown, not on time, and the note says so in words. A feed that will not read (404, timeout, malformed data) degrades to the pure schedule answer with a one-sentence explanation, never a silent drop.
  • Next departures, not just the day's window. A next: attribute on each node lists the upcoming departures at that stop, in feed time order and in the feed's clock (tram 9 25:10 stays past midnight), capped at three with the hidden rest counted (+2 more). With a realtime feed configured the board speaks the prediction inline — bus 16 07:05 +300s or cancelled — and the live: list omits anything the board already said, so nothing prints twice. When the day's last departure has run, the note says the day is over instead of letting an empty board read as a broken feed.
  • A certified ride plan between two coordinates. get_transit_route walks to a stop, rides one line that serves both catchments, and walks it off — all straight-line legs labelled as such, never an interchange the feed cannot prove. Plans ride on the departure board's honesty: certified against the service day, predictions decorate their trips, cancelled trips drop out with a counted note, and when nothing can be certified the note names the leg that failed.
  • The signal is explicit. Departure times, the schedule date, and the feed's timezone travel in the note, where a model reading only the map sees them.

The budget is a real budget

Most map-for-agents code truncates and hopes. supercarto treats truncation as a correctness problem:

  • Ranking. Named landmarks survive; anonymous intersections are cut first.
  • Connectivity. Cut vertices are never removed, so the surviving network stays connected. A map the agent can traverse but not connect is worse than a smaller map it can use.
  • No stranded names. A landmark the agent can see but cannot route to is removed. It would confidently try to walk to it.
  • Verification. emitAndVerify re-measures the actual emitted YAML and cuts again until it fits. The reported budget is the budget delivered, not an estimate.
  • Honesty. Every drop is recorded in omitted:, aggregated per layer, so the model can tell "not there" from "not shown".

The benchmark

Lives in its own repo now: supercarto-bench.

Same question, same model, same map — the only variable is what sits in the context window: compiled graph vs raw GeoJSON vs nothing. Raw runs, frozen test maps, and the scoring code all live there, so anyone building a rival map tool can run the same test and try to beat the score.

Current headline there: 9/9 for the compact graph against ~4/9 raw and 0/9 with no map, on two AI models. Route questions are unmeasurable (the public test router gives impossible answers) — so route is demoted to a feasibility answer: straight-line distance, compass direction, then "verify the approach on arrival". Turn-by-turn requires a router you host and have verified; OSRM is opt-in, not default. Stated, not hidden.

The score now ships with its own reproduction recipe (scoreC certificate, re-derived from raw answer archives without model calls), a per-model leaderboard, and adapter arms: a rival tool registers itself with a single { name, prepare } module and gets the same tasks, models and pass rules. The current certificate: supercarto 38/47 · geojson 15/44 · none 0/47 across every archived run.

  • Live certificate — every number, re-derivable from committed archives with no model calls.
  • Live leaderboard — per model and per arm, including the free models you can run yourself.

What this repo keeps is a quick token-cost check:

bash
npx supercarto bench <file.geojson>

Data sources

SourceStatusUse
OverpassdefaultDevelopment. 15-40s per call, rate limited.
PMTiles / ProtomapsSUPERCARTO_PMTILESProduction. Range requests against object storage, milliseconds, no rate limit.
OSRMdefaultTurn-by-turn routing, walk/bike/drive.
Open-MeteodefaultWeather. No key.
TomTom / HEREkey requiredLive traffic.
Terrarium tilesdefaultElevation and slope. No key.
GTFS feedsSUPERCARTO_GTFSTransit stops, lines, and schedules. Any static feed, no key. Live delays join from a GTFS-Realtime TripUpdates URL via SUPERCARTO_GTFS_RT.
bash
export SUPERCARTO_PMTILES=https://your-bucket/planet.pmtiles

PMTiles is the answer at production volume. The reader is included — no pmtiles dependency, no mapbox-gl, zero transitive packages.

Everything is read from the environment by one factory, so the CLI and the MCP server cannot disagree about where data came from. They did once, and nothing reported it.

SUPERCARTO_PMTILES      PMTiles archive URL; primary source when setOVERPASS_ENDPOINT       your own Overpass instanceTERRARIUM_ENDPOINT      elevation tile templateTOMTOM_API_KEY          enables get_trafficHERE_API_KEY            enables get_trafficSUPERCARTO_NO_TERRAIN   disable elevationSUPERCARTO_NO_WEATHER   disable weatherSUPERCARTO_GTFS         path to a GTFS feed (dir or .zip); enables get_transitSUPERCARTO_GTFS_RT      TripUpdates URL; adds live delay lines to get_transit

Attribution and the BYO-key contract

supercarto never ships keys. You configure every source with your own credentials, so every upstream relationship — Open-Meteo, TomTom, HERE, a transit agency's feed — is a direct one between you and the provider:

  • Traffic without a key returns free-flow, labelled. get_traffic is absent from tools/list until TOMTOM_API_KEY or HERE_API_KEY is set, and a free-flow estimate always says "free flow" in its own output. A congestion-free answer presented as live is the one failure this library refuses on principle.
  • Weather and air without a key use the non-commercial Open-Meteo API. That free tier is explicitly non-commercial: under 10,000 calls/day and not for products, subscriptions, or ad-supported apps. A commercial deployment gives it its own Open-Meteo subscription and endpoints, and the terms stay between you and OpenMeteo GmbH. Attribution is stated either way: weather and air answers name their source, and the Open-Meteo CC BY 4.0 term is spelled out.
  • Transit answers only what your feed proves. The feed comes from SUPERCARTO_GTFS; the note lines name it, its timezone, and its service date. Some agencies license their feeds with agency-specific terms — check the feed you import before a commercial deployment.
  • Attribution rides on the answer, not in it. ODbL is a licence term, so every REST response carries X-Data-Attribution: © OpenStreetMap contributors (ODbL) and an attribution field in the JSON body, and MCP map answers carry the same line in a comment. The compiled document itself is untouched — the attribution costs tokens at transport level only.

Nothing abhors a key like a self-hosted install, and nothing is attributed except what was actually fetched: arithmetic carries no line, and a custom weather or air source is named by its own name rather than handed a licence it did not grant.

Whole-metro feeds load entirely into memory. Since 0.6.1 the load is columnar — stop_times go straight into per-trip arrays, no row objects — so a feed the size of Translink SEQ (35 MB zip) fits Node's default heap and the answer is byte-identical to the pre-0.6.1 build. Verified live at that size: schedule, departure boards, and 750+ realtime predictions join in one answer with no NODE_OPTIONS at all. Bigger feeds load in proportion to their own inflated size; give such a run NODE_OPTIONS=--max-old-space-size=4096.


Agent integration

Claude Desktop (one-click)

Every release ships supercarto-X.Y.Z.mcpb — an MCPB bundle: download it from the latest release, open it with Claude Desktop, and the maps tools install with one click. Optional install-time configuration: an Open-Meteo key for higher weather limits, and a local GTFS feed path (plus the operator's TripUpdates URL) for the transit tools. Node ≥ 18 is the only requirement; the bundle carries the server, which has zero npm dependencies, so it is half a megabyte.

MCP

json
{  "mcpServers": {    "supercarto": { "command": "npx", "args": ["supercarto", "mcp"] }  }}

Eight tools: get_maplet, route, search_places, expand_feature, get_daylight, get_terrain, get_weather, get_air, plus get_traffic when a key is present, get_transit and get_transit_route when a GTFS feed is configured. Each maplet lists exactly the tools that deployment can answer, so an agent never calls one that cannot work. get_daylight is always available: sun position is arithmetic, needing no source and no credential. get_weather and get_air are keyless by default: an agent never tells someone it is safe to go out without knowing rain or air first.

What a maplet says about a place

Beyond topology and distance, a node can carry the facts that decide whether a trip is worth making:

yaml
n3: {type: poi, name: Blue Bottle, tags: [cafe], hours: 07:00-18:00, brand: Blue Bottle}n4: {type: poi, name: Central Rx, tags: [pharmacy], hours: 09:00-17:00}map:  sun: up, elevation: 43.4deg, twilight: day, azimuth: 22deg, sunrise: "..."

Both shops above are open at 12:00 local. At 04:00 the same two read hours: closed, because their hours are known and they are shut. A bench with no recorded hours emits no hours field at all.

hours is evaluated against an instant and evaluated in the map's timezone, not the server's. Three states, never two: a time range, closed, or absent because nobody recorded it. Absent is deliberately not closed — those lead to opposite advice, one means go and find out, the other means go elsewhere.

twilight is day, civil, nautical, or night rather than a boolean, because the three lead to different decisions: walking is fine at civil twilight and unwise at nautical. Above the Arctic circles in summer and winter the map reports polar: day or polar: night instead of inventing a sunrise.

Pass compile.utcOffsetMinutes and compile.now to fix both to a known place and instant, which is what the tests do.

Python

python
import asynciofrom supercarto import SuperCarto
async def main():    async with SuperCarto() as carto:        m = await carto.maplet(lat=35.6833, lon=139.7620, radius_m=400, budget=1500)        print(m.yaml)        w = await carto.weather(lat=35.6833, lon=139.7620)
asyncio.run(main())

Zero runtime dependencies. It speaks JSON-RPC to the Node server over stdio rather than importing an SDK, because the mcp package pulls in httpx and pydantic and an agent framework that already depends on one of them should not get a second copy.

HTTP

bash
curl 'localhost:8787/maplet?lat=35.6833&lon=139.762&radiusM=400&budget=1500&format=yaml'

Hosted mode (deployed)

The compile path is Workers-compatible (fetch-based sources, no Node built-ins), and cloud/worker/ packages it as a Cloudflare Worker: the same /maplet, /scr, weather, daylight and terrain surface as the local HTTP API above, with per-IP rate limiting and ODbL attribution on every map response. It is deliberately a subset — transit and traffic are not served, because a Worker has no filesystem for a GTFS feed and hosted mode ships no flow-provider keys, and GET / states that openly. See cloud/worker/README.md.

Deployed at https://supercarto-compile.jeffrinjames99.workers.dev. Data source chain for /maplet and /scr: live Overpass first, then a hosted PMTiles planet build of the OpenStreetMap basemap — every known public Overpass instance refuses the shared Cloudflare egress range (HTTP 521), so the fallback is what actually serves a hosted maplet. The archive's detail level is coarse beyond z10-ish, and the deployment caps a request's tile and feature fetches so a planet tile stays inside a Worker CPU budget; truncation travels in the document as warnings, and the source: line says protomaps when the fallback served it. Weather, daylight and rate limiting are live; terrain answers an honest 503 (Terrarium tiles are PNG-encoded and the bundled zero-dependency decoder reads raw Terrarium buffers only); transit and traffic are absent for the reasons GET / lists. GET /healthz probes Overpass only, so a 503 there means the Overpass leg is unreachable — not that the PMTiles fallback is down.


CLI

bash
supercarto fetch --lat 35.6833 --lon 139.762 --radiusM 400 --budget 1500 --metricssupercarto weather --lat 35.6833 --lon 139.762 --hours 12supercarto traffic --from 37.7749,-122.4194 --to 37.7849,-122.4194supercarto transit --feed city-gtfs.zip --lat 36.913 --lon -116.77 --radiusM 3000supercarto route --from 37.7749,-122.4194 --to 37.7849,-122.4194 --mode walksupercarto mcpsupercarto serve --port 8787supercarto compile city.geojson --budget 1024 --metricssupercarto encode city.geojson --out city.scrsupercarto decode city.scrsupercarto bench city.geojson

fetch layers accept road and poi alongside raw OSM tags; anything else is rejected rather than silently returning nothing. A request that would yield named places with no streets fails with a clear error instead of a misleading map — pass --layers poi for a POI-only map. Warnings travel inside the map output, not just stderr, so agents see them.


Accuracy

Distances are verified against haversine ground truth at mid and high latitude:

  • 0.11% error at San Francisco (37.77°N)
  • 0.11% error at Oslo (59.91°N)

This required getting the Web Mercator scale correction right: mercator distances exceed ground distance by 1/cos(latitude) on both axes, and getting the sign wrong produces a 26% error at mid latitude that compounds toward the poles. A mean isotropic scale is also wrong for a non-square bbox, so the scale is applied per axis.

The benchmark task set spans 64°N to 33°S deliberately. A benchmark run only at 37°N measures one case and hides every sign error toward the poles.


Status

461 tests passing: 328 unit (including 42 for the GTFS transit layer, 14 for the protobuf wire and TripUpdates schema, 5 for the real-time overlay join, and 7 for the PNG elevation decoder), 121 against live sources, and 12 MCP end-to-end. Outputs are byte-identical to the Python port - the parity engine runs on every push. Verified against live OpenStreetMap, live Open-Meteo, and the live MCP server driven from Python.

Implemented: SCR codec (text and binary, delta geometry, ring groups, three heat encodings, omissions, routes, refs), Web Mercator with per-axis scale correction, Visvalingam-Whyatt simplification, GeoJSON ingestion with OSM classification, topology compilation with junction welding and landmark attachment, token budgeting with connectivity guarantees, YAML emission, indoor floor graphs with vertical circulation, place-density heatmaps, live Overpass, PMTiles with a built-in MVT decoder, routing demoted to feasibility (straight-line distance and direction by default; OSRM turn-by-turn is opt-in for an engine you have verified — the public demo router returns impossible distances), keyless weather with a degraded path that refuses to invent readings, traffic with an honest free-flow fallback, terrain elevation and slope, GTFS transit schedules with three honest service states, GTFS-Realtime trip updates joined onto those schedules with unknown-not-on-time semantics, MCP over stdio, HTTP API, CLI, a Python client, and a task-level benchmark with OSRM ground truth.

Not implemented: hosted vector tiles with style delivery, and full indoor room geometry beyond centroids.


License

Apache-2.0

來源:README.md,提交 6a42f2d

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

2
  1. v0.7.0最新Oct 29, 2026
  2. v0.6.2Oct 26, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分