Create a free account

Continue with Google

An account on the spot, no request needed.

or sign up with your email

No password: the link signs you in.

By continuing, you agree to our Terms of Service and Privacy Policy.

Already have an account? Sign in

Docs

KASPR Predict MCP

Reference for the hosted MCP servers at mcp.kasprdata.com: what they answer, how to install them in an MCP client, every tool with its parameters and results, the HTTP routes, limits, errors, privacy and terms.

Spec 0.5 · updated 3 October 2026 · beta · How the numbers are computed · Product page

Overview

KASPR Predict MCP is a timing planner for work that depends on the network. It is served as two Model Context Protocol servers over streamable HTTP, behind one bearer key. Any MCP client that can send an Authorization header can use them: Claude Code, Cursor, and Claude Desktop through the mcp-remote bridge.

The timing server (kaspr-timing) answers one question for calls, live streams, big uploads, agent batches and fixed live events: given a task at a proposed time and place, is there a materially better time? It answers in fixed wording, in every participant’s local time, and says nothing when nothing is better. It never blocks the time you proposed.

The scheduling server (kaspr-predict) ranks the hours between now and a deadline for batch jobs, agent loops and transfers: run now with timeout, retry and cache tuning for the hour, wait, or no good window. It can hold a chosen window and re-score it until it starts.

Both read the same model: KASPR’s typical week for every country, region and district, 168 hourly values of how usually rough the connection is, from a frozen data vintage named in every answer. Neither is a live measurement of the network.

ServerEndpointToolsFor
kaspr-timinghttps://mcp.kasprdata.com/timing/mcpcheck_timing, best_window, explain_last_verdictcalls, live streams, uploads, agent batches, fixed events
kaspr-predicthttps://mcp.kasprdata.com/mcpexposure_class, latency_forecast, best_window, schedule_hold, report_outcomebatch jobs and agent loops with a deadline
HTTPPOST https://mcp.kasprdata.com/verdict and /verdict/best_windowthe timing verdicts without MCPscripts, pipelines, cross-checks

Quick start

1. Get a key

Sign in and create a trial key under Account → API keys: it starts with kmcp_, works on every server, and answers ten calls over 72 hours. Developer and team keys with monthly allowances are issued by hand during the beta; ask through the contact page. Using a key means you accept the terms below.

2. Claude Code

One command per server. Afterwards /mcp inside Claude Code lists kaspr-timing with three tools and kaspr-predict with five.

claude mcp add --transport http kaspr-timing https://mcp.kasprdata.com/timing/mcp --header "Authorization: Bearer <your key>"
claude mcp add --transport http kaspr-predict https://mcp.kasprdata.com/mcp --header "Authorization: Bearer <your key>"

2. Cursor and other clients with a JSON configuration

Add one or both servers to the client’s MCP configuration (for Cursor, .cursor/mcp.json).

{
  "mcpServers": {
    "kaspr-timing": {
      "url": "https://mcp.kasprdata.com/timing/mcp",
      "headers": { "Authorization": "Bearer <your key>" }
    },
    "kaspr-predict": {
      "url": "https://mcp.kasprdata.com/mcp",
      "headers": { "Authorization": "Bearer <your key>" }
    }
  }
}

2. Claude Desktop

Claude Desktop reaches remote servers through the mcp-remote bridge; add this to claude_desktop_config.json, and a second entry with the other URL if you want both.

{
  "mcpServers": {
    "kaspr-timing": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.kasprdata.com/timing/mcp", "--header", "Authorization: Bearer <your key>"]
    }
  }
}

3. Ask

Ask the question you would ask anyway. The client picks the tool. For example: “Tim in Nairobi wants a video call at 9 PM his time. I’m in Melbourne. Is that a good hour?”

The answer should name the hour in both places and either propose a steadier one or say nothing about timing. If you get a 401, the key is missing or has been revoked; if a tool is missing from the list, the client has not reloaded the server.

Authentication

Every request to /timing/mcp, /mcp, /verdict and /verdict/best_window must carry Authorization: Bearer <key>. A missing or revoked key answers HTTP 401 with a JSON body whose error code is unauthorized; nothing else is returned.

Keys are tied to a tier (free, developer, team) that sets the scheduling server’s monthly credits and request rate. The timing server is not metered during the beta. Keys are personal: do not share them or embed them in client-side code. Tell us at once if a key may have leaked, and we rotate it.

Only bearer keys are supported today. Clients that require OAuth for remote servers, such as the connector screens in ChatGPT and claude.ai, cannot add these servers yet; that is planned.

Over stdio, for the local server, the key comes from the KASPR_MCP_KEY environment variable instead of a header.

Timing tools (kaspr-timing)

Three read-only tools. Descriptions are the server’s own; the client sees them verbatim. Every call returns a verdict object (next section) in structuredContent and the same JSON as text, and every outcome is a verdict, never an exception: a bad request is invalid_request, a cap is rate_limited, a backend failure is a silent no_recommendation.

check_timing

Checks whether a proposed time for a network-sensitive task (a call, a live stream, a large upload, an agent batch job, a fixed live event) is a usually rough hour on the networks involved, and whether a materially steadier hour exists nearby. You classify the task into `task_class`; the service never infers it. Give every participant’s location and the proposed time with its UTC offset; the service converts time zones itself. Returns a verdict object. How to use it: if `verdict` is `no_recommendation`, say nothing about timing and carry on; if `text` is present (`suggest_alternative`, `advise_only`, `insufficient_data`, `rate_limited`), show `text` verbatim, as the whole of your timing advice; never add timing advice of your own, never quote numbers that are not in `text`, and never claim a benefit beyond what `text` says. Keep `explanation` for when the user asks why (or call `explain_last_verdict`). The verdict never blocks anything: the user’s original time always stays available.

Parameters

NameTypeRequiredMeaning
task_classstringyeslive_call, broadcast, upload_transfer, agent_batch, fixed_realtime or generic. broadcast, upload_transfer and agent_batch take exactly one location.
locationsarray of 1–2yesEach with a label (1–40 characters: letters, digits, space, _ . ' -; labels come back in the answer, so nothing else is accepted) and either query (a place name, ≤ 80 characters, e.g. “Nairobi, KE”) or lat and lon. The location labelled me is the user’s own endpoint; otherwise the first one is.
candidate_timestringyesISO 8601 with offset; a time without an offset is read as UTC. Not earlier than one hour ago; no upper limit.
windowobjectno{ start, end } with offsets, at most 12 hours, inside which an alternative may be proposed. Default: the candidate ± 3 hours.
feasibilityobjectno{ local_hours: [from, to) } in whole hours, applied in each endpoint’s local time. Default [8, 20].
user_timezonestringnoIANA zone for the user’s clock, e.g. Australia/Melbourne. Default: the user endpoint’s zone.

Returns

  • — verdict: suggest_alternative, no_recommendation, advise_only, insufficient_data, invalid_request or rate_limited.
  • — candidate and alternative: each with time_local (every endpoint, user last, with offsets), band, confidence and source; alternative also names the limiting_endpoint. Null when not evaluated.
  • — reason_code (always), evidence_level (with a suggestion or advice), text (the one sentence to show, when present), explanation (shown only when asked), data_vintage, usage.

best_window

Finds the steadiest hour inside a window for a network-sensitive task when no time has been proposed yet (a planning call; it returns no sentence to show). You classify the task into `task_class`. Give every participant’s location and the window (at most 12 hours) with UTC offsets. Returns a verdict object: `best_window` with `best` (the steadiest feasible hour, in every endpoint’s local time) when one hour is materially steadier than the rest; `no_recommendation` when the window is uniform (then `best` is still reported but any hour is as good) or when no hour fits the allowed local hours; `insufficient_data` or `rate_limited` with `text` to show verbatim. On `best_window`, propose `best` as the time; on `no_recommendation`, say nothing about timing. Keep `explanation` for when the user asks why. Never invent timing advice beyond the verdict.

Parameters

NameTypeRequiredMeaning
task_classstringyesAs for check_timing.
locationsarray of 1–2yesAs for check_timing.
windowobjectyes{ start, end } with offsets, at most 12 hours; hours are stepped from start.
feasibilityobjectnoAs for check_timing.
user_timezonestringnoAs for check_timing.

Returns

  • — verdict: best_window, no_recommendation, insufficient_data, invalid_request or rate_limited; best in place of candidate and alternative.
  • — reason_code: best_hour, window_uniform (best still reported), no_feasible_hour, insufficient_coverage, or a request or cap code.
  • — explanation, data_vintage, usage; no text on a planning call except for insufficient_data and rate_limited.

explain_last_verdict

Returns the reasoning behind the most recent timing verdict given to this user (within 24 hours): the verdict and its `explanation`. Call it only when the user asks why a time was or was not suggested, and show `explanation` as given. If no verdict has been made yet, it says so.

Parameters

NameTypeRequiredMeaning
—No parameters.

Returns

  • — spec_version, verdict and explanation of the last verdict for this key within 24 hours; otherwise verdict no_recommendation with the explanation “No timing check has been made yet.”

Verdict semantics

Every hour of a place’s typical week is one of three bands, from the chance that the hour is rough relative to that place’s own week. For two endpoints the hour is judged by the worse side, and that side is named. A suggestion needs an alternative that is at least one band steadier and materially so, inside the window and inside the local hours allowed at every endpoint; the nearest such hour wins, earlier before later. Otherwise the verdict is silent. A fixed event is never moved: it gets advice when its hour is usually congested, nothing otherwise.

Confidence comes from how much measurement backs the place: high or medium are usable; a place with low confidence falls back to its region, then its country, and if none qualifies the verdict is insufficient_data. Every verdict carries data_vintage, the date of the model data behind it.

The sentences are fixed. A client shows text verbatim when it is present and says nothing about timing when it is absent; explanation is kept for when the user asks why. The same words come back from any client and from the HTTP routes.

Verdict values

verdictMeaningtext
suggest_alternativeA materially steadier hour exists; the alternative is named.yes
no_recommendationNothing is materially better, or nothing feasible; say nothing about timing.no
advise_onlyA fixed event at a usually congested hour; advice, no other time.yes
best_windowPlanning call: best is the steadiest feasible hour in the window.no
insufficient_dataA place with too little measurement to say anything reliable.yes
invalid_requestThe request could not be evaluated; reason_code says why.no
rate_limitedA cap was reached; nothing was evaluated.yes

Bands and confidence

ValueMeaning
steadyUsually a calm hour for that place, relative to its own week.
mixedNeither calm nor rough by that place’s standards.
congestedUsually one of that place’s rougher hours.
highThe place’s own measurement, well supported.
mediumEnough measurement to judge, possibly inherited from the region.
lowNot enough to judge; the verdict falls back to a larger area or says insufficient_data.

The sentences

Examples of the fixed wording, with places and times filled in by the server:

  • — Call: “9 PM Nairobi (5 AM Melbourne (Tue)) is usually a congested hour on Nairobi networks; 7 PM Nairobi (3 AM Melbourne (Tue)) is typically steadier for a video call. Propose 7 PM Nairobi instead, or keep 9 PM Nairobi?”
  • — Upload: “3 PM Vienna is usually a congested hour on your network. If it’s not urgent, starting at 6 PM Vienna should be noticeably faster. Continue now or schedule for 6 PM Vienna?”
  • — Live stream: “3 PM Vienna is usually a congested hour on your network for live streaming. 6 PM Vienna is typically steadier. Keep 3 PM Vienna, or move it?”
  • — Agent batch: “Deferring to 6 PM Vienna: current window congested, alternative mixed, confidence high.”
  • — Fixed event: “It’s a fixed time so there’s nothing to change, but 2 PM Vienna is usually a congested hour on your network. If you can, use a wired connection and close cloud backups beforehand.”
  • — Too little data: “I don’t have enough measurements for Norfolk Island to say anything reliable about 10 AM Melbourne, so I’d book it as planned.”

Reason codes

reason_codeWithMeaning
endpoint_congested_hoursuggest_alternativeThe proposed hour is congested at the limiting endpoint.
endpoint_mixed_hoursuggest_alternativeThe proposed hour is mixed and a steady hour is near.
no_material_differenceno_recommendationNo hour in the window is materially steadier.
no_feasible_alternativeno_recommendationThe hour is not steady but no alternative fits the window and local hours.
fixed_time_congestedadvise_onlyA fixed event at a usually congested hour.
best_hourbest_windowOne hour in the window is a band steadier than its worst.
window_uniformno_recommendationEvery feasible hour in the window has the same band; best is still reported.
no_feasible_hourno_recommendationNo hour in the window fits the allowed local hours.
insufficient_coverageinsufficient_dataNo area with usable confidence for an endpoint, or no data for that hour.
service_unavailableno_recommendationThe data could not be reached; silent, not counted.
daily_cap_reached, minute_cap_reached, spread_limit_reached, area_limit_reachedrate_limitedA per-key cap; see Limits.
missing_field, bad_task_class, too_many_locations, bad_location, bad_timezone, bad_time, time_in_past, window_too_long, bad_feasibilityinvalid_requestWhat was wrong with the request, in the order it is checked.

Scheduling tools (kaspr-predict)

Five tools for work with a deadline. Credits meter the forecast and scheduling calls; classification is free, and run now answers are free. Every error carries recommendation run_now with fallback true, so an agent is never left without an answer.

exposure_class

Classifies a task as none, low, high or critical, and infers its profile (kind, duration, whether it is interactive, retry policy). Call it before any long-running, retry-heavy, real-time or human-facing task; for high or critical, call best_window next.

Parameters

NameTypeRequiredMeaning
descriptionstringyesWhat the task is, in plain words (≤ 4,000 characters).
kindstringnoA task kind from the taxonomy, if the client already knows it.
duration_minintegerno1–1440.
interactivebooleannoWhether a person is waiting on it.
retry_policyobjectnotimeout, retries, backoff, if known.

Returns

  • — class, inferred_profile and suggested_next. Free.

latency_forecast

The hourly chance of a rough connection, with jitter and latency levels, for up to 20 places over up to 720 hours. For when the agent needs the whole curve rather than a decision.

Parameters

NameTypeRequiredMeaning
locationsarray of 1–20yesEach with place (free text), area_id, lat and lon, a region code or a cloud region name, and an optional role.
horizon_hintegerno1–720, default 24. Free keys: up to 24.
resolution_min15 or 60noDefault 60.
metricsarraynoWhich metrics to include.
pairbooleannoScore the two places as one path.

Returns

  • — series per place with hourly points, the places as resolved, issued_at (the data vintage), notes and credits_charged (1 per place per 24 hours; pair doubles).

best_window

Ranked windows between the earliest start and the deadline, a comparison with running now, and the decision: run now, wait, or no good window, with timeout, retry, backoff and cache tuning for the hour. Calls and live sessions with a deadline that leaves room to choose are ranked too, by the chance of a degraded session; a session already under way is only flagged, never delayed.

Parameters

NameTypeRequiredMeaning
profileobjectyesThe task profile, usually inferred_profile from exposure_class: kind, duration_min, interactive, and optionally retry_policy, cache_ttl_s, baseline_ms.
locationsarray of 1–20yesAs for latency_forecast, with roles such as origin, destination, cloud_region or participant.
deadlinedatetimeyesISO 8601; a naive time is UTC. Up to 30 days ahead.
not_beforedatetimenoEarliest start, default now.
n_windowsintegerno1–10, default 3.
compare_to_nowbooleannoInclude the now comparison, default true.
business_hours, min_gap_minnoAccepted for compatibility; not part of the decision rule.

Returns

  • — recommendation (run_now, wait, no_good_window), windows with local times, score, confidence and expected saving, now, tuning, must_start_by, recheck_at, explanation, notes, calibrated, credits_charged (0 for run now; otherwise 1, plus 1 per place beyond two).

schedule_hold

Holds a chosen window, re-scores it every fifteen minutes against the forecast service, and notifies the session (or a callback URL) when its score drops.

Parameters

NameTypeRequiredMeaning
window_idstringyesA window id from best_window, issued to the same key.
ttl_hnumbernoHow long to keep the hold, up to 720 hours.
reschedule_policystringnonotify_only (default) or auto_shift_within_deadline.
callback_urlstringnoAn https URL to POST re-score events to.

Returns

  • — hold_id, status, the re-score interval, next check, credits_remaining. 1 credit.

report_outcome

Records what happened for a held or issued window, so the model gets better. Opt-in, job metrics only; refunds one credit, once per window.

Parameters

NameTypeRequiredMeaning
hold_id or window_idstringone ofWhat the outcome is for.
started_at, ended_atdatetimenoWhen it ran.
retriesintegernoHow many retries it took.
failedbooleannoWhether it failed.
qualitystringnogood, choppy, failed or unknown, for sessions.
followed_recommendation, cost_unitsnoOptional detail.

Returns

  • — credited (1 or 0) and credits_remaining.

Resources on the scheduling server: kaspr://taxonomy (task kinds and their defaults), kaspr://coverage (places covered, by level), kaspr://calibration (the decision parameters and whether they are calibrated), kaspr://changelog. Prompt: schedule_task(task), which walks an agent through exposure_class and best_window.

HTTP routes

The timing verdicts are also plain HTTP, for scripts, pipelines and cross-checks: POST /verdict for check_timing and POST /verdict/best_window for best_window, with the same bearer key, a JSON body in the shape of the tool parameters, and the verdict object as the response. Every verdict is HTTP 200, including invalid_request and rate_limited; only a missing key is 401.

{
  "task_class": "live_call",
  "locations": [{ "label": "me", "query": "Melbourne" }, { "label": "Tim", "query": "Nairobi" }],
  "candidate_time": "2026-10-06T21:00:00+03:00",
  "feasibility": { "local_hours": [0, 24] },
  "user_timezone": "Australia/Melbourne"
}
{
  "spec_version": "0.3",
  "verdict": "suggest_alternative",
  "data_vintage": "2026-07-16",
  "candidate": { "time_local": [{ "label": "Tim", "time": "2026-10-06T21:00+03:00", "tz": "Africa/Nairobi" }, { "label": "me", "time": "2026-10-07T05:00+11:00", "tz": "Australia/Melbourne" }], "band": "congested", "confidence": "high", "source": "typical_week" },
  "alternative": { "time_local": [ … ], "band": "mixed", "confidence": "high", "source": "typical_week", "limiting_endpoint": "Tim" },
  "reason_code": "endpoint_congested_hour",
  "evidence_level": 1,
  "text": "9 PM Nairobi (5 AM Melbourne (Wed)) is usually a congested hour on Nairobi networks; 7 PM Nairobi (3 AM Melbourne (Wed)) is typically steadier for a video call. Propose 7 PM Nairobi instead, or keep 9 PM Nairobi?",
  "explanation": "Based on KASPR's typical weekly pattern for Nairobi networks (data up to July 2026), not a live forecast. …",
  "usage": { "tier": "beta", "verdicts_today": 1, "cap": null }
}
curl -s -X POST https://mcp.kasprdata.com/verdict \
  -H "Authorization: Bearer $KASPR_MCP_KEY" -H "content-type: application/json" \
  -d '{"task_class":"live_call","locations":[{"label":"me","query":"Melbourne"},{"label":"Tim","query":"Nairobi"}],"candidate_time":"2026-10-06T21:00:00+03:00","feasibility":{"local_hours":[0,24]},"user_timezone":"Australia/Melbourne"}'

Limits

  • — Timing server: no daily or per-minute caps during the beta. A key that touches more than 15 distinct places in an hour is answered rate_limited until the hour passes, as a guard against enumeration.
  • — Timing requests: at most 2 locations (exactly 1 for broadcast, upload_transfer and agent_batch); a window of at most 12 hours; a candidate no earlier than one hour ago; no upper limit on how far ahead.
  • — Scheduling server: credits per month by tier (free 500, developer 20,000, team 250,000) and requests per minute (10, 60, 300); free keys can forecast up to 24 hours ahead for up to 2 places; best_window takes up to 5, 10 or 20 places by tier; deadlines up to 30 days ahead; holds up to 720 hours, at most 20 active per key. The whole-week route used by the client library needs a developer or team key.
  • — Place queries: a plain name (“Nairobi”, “Vienna”), “City, CC” or “City, Country” (“Nairobi, KE”), a district with its city and country (“Prahran, Melbourne, AU”), or coordinates; at most four comma-separated parts, ≤ 80 characters. Five micro-territories are not covered.
  • — Requests per key: the key’s per-minute limit (10 for free keys) applies to the timing tools as well and comes back as a rate_limited verdict; request bodies are capped (64 KB on the routes); at most 20 active holds per key.
  • — Distinct places per day: a key may touch 50 (free), 500 (developer) or 5,000 (team) different places per UTC day across every tool; places already looked up that day cost nothing. Over the allowance, the scheduling decision and its tuning still come but without per-place numbers, raw forecasts are refused, and the timing tools answer rate_limited with “You’ve checked a lot of different places today, so I’d go ahead as planned.”

Errors

The timing server never raises: every outcome is a verdict object over HTTP 200, and a client shows text when it is present and otherwise says nothing. The scheduling server answers structured errors with recommendation run_now and fallback true, so an agent can always carry on.

WhereCodeMeaning
anyunauthorized (HTTP 401)No key, or a revoked one, in the Authorization header.
timinginvalid_requestThe request could not be evaluated; reason_code names the first problem found, from missing_field to bad_feasibility.
timingrate_limitedA cap; text says to go ahead as planned.
timingno_recommendation / service_unavailableThe data could not be reached; silent and not counted.
schedulingno_coverageA place could not be resolved or is not modelled.
schedulinghorizon_exceededA deadline or horizon beyond the limit for the key.
schedulinginvalid_profileA malformed profile, deadline or window id.
schedulingquota_exhausted, rate_limitedCredits or requests per minute used up.
schedulingbackend_unavailableThe forecast service could not be reached; run now.

Data and privacy

  • — The hosted servers never measure you. They answer from the model and your request alone. The timing server returns no numbers: bands, times and a sentence.
  • — The model is KASPR’s typical week for each place, from a frozen data vintage named in every answer. Verdicts say so in their own words (“usually”, “typically”, “not a live forecast”).
  • — We log each call: the key, the tool, the task class, the verdict, its confidence and source, the number of places, and timing. Place names and coordinates you send are resolved and are not kept beyond the request log needed to operate the service and enforce the terms.
  • — In the on-device mode of the scheduling server, the rolling series of your own latency measurements lives in one file on your machine, readable only by you; the only call to KASPR is a forecast by place id. Outcome reports are opt-in and carry job metrics only.

Terms

Use of the MCP servers, the HTTP routes and everything they return is governed by the KASPR Schedule terms and conditions, including the additional terms for the KASPR Predict MCP. A key is issued to someone who has accepted them, and using a key, directly or through an agent you configure, is acceptance of them. In short: the outputs are statistical tendencies from past measurement, not live conditions, not advice, and not a promise that any hour will be better than another; you and your agents decide what to do with them, at your own risk.

Read the terms and conditions

Changelog

DateChange
3 Oct 2026Spec 0.5: a daily allowance of distinct places per key on every tool; the whole-week route for developer and team keys.
3 Oct 2026Spec 0.4: labels restricted to plain characters, place resolution bounded; per-minute limit on the timing tools, body-size and hold limits, hardening after a security review.
3 Oct 2026Spec 0.3: shared place resolution (“City, CC” and “City, Country” queries), wording refinements, no caps on the timing server during the beta. Timing server and HTTP routes deployed.
3 Oct 2026Spec 0.2: the timing server (check_timing, best_window, explain_last_verdict) on /timing/mcp; verdicts from the typical week’s local rough-hour probability.
2 Oct 2026Scheduling server: deadlines up to 30 days; calls and sessions with a deadline that leaves room to choose are ranked; explanations name the slot in every participant’s local time.
1 Oct 2026Scheduling server (exposure_class, latency_forecast, best_window, schedule_hold, report_outcome) on /mcp; hosted beta with bearer keys.