Developer docs

MCP server

Connect ChatGPT, Claude, Cursor, Codex and your own agents to Prolepsia, and install the agent skill.

Read as Markdown · llms.txt

The Prolepsia MCP server lets AI assistants and agents use Prolepsia directly. Ask in plain words for a forecast, and the assistant writes the question, starts the forecast and reads the result for you. MCP (Model Context Protocol) is the open standard most AI tools use to call outside tools.

  • Server address: https://app.prolepsia.com/api/v1/mcp/
  • Transport: Streamable HTTP. Every request stands alone, so there is no session to keep.
  • Tools: 153, listed at the end of this page.
  • Logging in: browser assistants such as ChatGPT and Claude log in with your Prolepsia account (OAuth). Developer tools such as Claude Code, Cursor and Codex use an API key.

Both ways of connecting reach the same account, permissions, credits and limits as the API. Every tool calls the same code as the matching API call.

A forecast takes from about 5 minutes to about 1.5 hours, depending on its run mode. create_forecast returns a task id within a second, and the forecast keeps running on our servers. A well-behaved agent tells you the id straight away and checks back every few minutes. It never starts the same forecast twice because a result has not arrived yet. The agent skill teaches an agent exactly this.

Connect a browser assistant

ChatGPT, Claude.ai and Perplexity connect with OAuth, so you never paste a key into them.

  1. In the assistant, add a custom connector (or search for Prolepsia in its connector directory).
  2. Enter the server address: https://app.prolepsia.com/api/v1/mcp/
  3. Log in to Prolepsia when asked, and approve the permissions.

The assistant then sees Prolepsia's tools. To remove its access, open Settings → API and AI clients in Prolepsia and choose Disconnect under Connected AI clients. That ends the connection at once.

Connect a developer tool

Create an API key first: Settings → API and AI clients → API keys → Create new key. Give it the forecasts:read and forecasts:write scopes, and questions:read and questions:write for the question tools. Then add Prolepsia to your tool. Replace pre_... with your key.

Claude Code

claude mcp add --transport http prolepsia https://app.prolepsia.com/api/v1/mcp/ \
  --header "Authorization: Bearer pre_..."

Restart Claude Code. The server shows as prolepsia under /mcp.

Cursor

Add this to ~/.cursor/mcp.json, then restart Cursor:

{
  "mcpServers": {
    "prolepsia": {
      "url": "https://app.prolepsia.com/api/v1/mcp/",
      "headers": { "Authorization": "Bearer pre_..." }
    }
  }
}

Codex CLI

Add this to ~/.codex/config.toml:

[mcp_servers.prolepsia]
url = "https://app.prolepsia.com/api/v1/mcp/"

[mcp_servers.prolepsia.headers]
Authorization = "Bearer pre_..."

Claude Desktop

Claude Desktop reaches remote servers through mcp-remote, which needs Node.js. Add this to claude_desktop_config.json (on macOS in ~/Library/Application Support/Claude/, on Windows in %APPDATA%\Claude\):

{
  "mcpServers": {
    "prolepsia": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://app.prolepsia.com/api/v1/mcp/",
        "--header",
        "Authorization: Bearer pre_..."
      ]
    }
  }
}

Windsurf

Add this under mcpServers in ~/.codeium/windsurf/mcp_config.json, then restart the Cascade panel:

{
  "mcpServers": {
    "prolepsia": {
      "serverUrl": "https://app.prolepsia.com/api/v1/mcp/",
      "headers": { "Authorization": "Bearer pre_..." }
    }
  }
}

Any other client

Use the server address and send the key in an Authorization: Bearer pre_... header, or in X-Api-Key: pre_.... Check that the key works:

curl -sS -X POST https://app.prolepsia.com/api/v1/mcp/ \
  -H "Authorization: Bearer $PROLEPSIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'

The answer lists every tool.

Install the agent skill

The agent skill is a Markdown file that teaches an agent when to use Prolepsia, how to write a good question, how to wait for a forecast without starting it twice, and how to read the answer. The server works without it, but agents that have it make far fewer mistakes. The current version is 2026-10-24.2.

There are two forms of the same text:

File For Address
SKILL.md with a header that tells the agent when to use it Claude Code and Codex https://app.prolepsia.com/api/v1/mcp-skill/prolepsia.md
Plain Markdown Cursor, Windsurf and other agents that read a rules file https://app.prolepsia.com/api/v1/mcp-skill/agents.md

Install the skill as a file of its own. Never write it over AGENTS.md or another file that holds your own instructions. The agent replaces an out-of-date copy only when the file holds nothing but the skill.

For Claude Code:

mkdir -p ~/.claude/skills/prolepsia && \
  curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/prolepsia.md -o ~/.claude/skills/prolepsia/SKILL.md

For Codex, from your project folder. Codex reads skills from .agents/skills, and each skill needs the header:

mkdir -p .agents/skills/prolepsia && \
  curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/prolepsia.md -o .agents/skills/prolepsia/SKILL.md

For Cursor, from your project folder. Cursor reads rules from .cursor/rules and needs a header on each one:

mkdir -p .cursor/rules && { \
  printf -- '---\ndescription: How to use the Prolepsia forecasting tools\nalwaysApply: false\n---\n'; \
  curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/agents.md; \
} > .cursor/rules/prolepsia.mdc

For Windsurf, from your project folder. Windsurf reads rules from .windsurf/rules:

mkdir -p .windsurf/rules && { \
  printf -- '---\ntrigger: model_decision\ndescription: How to use the Prolepsia forecasting tools\n---\n'; \
  curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/agents.md; \
} > .windsurf/rules/prolepsia.md

For any other agent, save agents.md as a file of its own in the folder where that agent reads rules.

Keep the skill up to date

An installed skill is a copy. It does not change when Prolepsia updates the skill, so Prolepsia tells your agent when its copy is old:

  1. The skill file states its own version at the top: Skill version: 2026-10-24.2.
  2. Every time an agent connects, the MCP server tells it the current version and where to download it.
  3. When the two versions differ, the agent asks you to update. It updates the file itself only when the file holds nothing but the skill and it can write files.

https://app.prolepsia.com/api/v1/mcp-skill/version answers with the current version and both download addresses:

{
  "version": "2026-10-24.2",
  "skill_url": "https://app.prolepsia.com/api/v1/mcp-skill/prolepsia.md",
  "plain_url": "https://app.prolepsia.com/api/v1/mcp-skill/agents.md"
}

To update by hand, run the install command again. To update on a schedule, run this script from cron or your CI. It downloads the skill only when the version changed:

#!/bin/sh
# update-prolepsia-skill.sh: replace the installed skill when Prolepsia has a newer one.
# For Codex, use .agents/skills/prolepsia/SKILL.md in your project instead.
# Point this only at a file that holds the skill alone, never at AGENTS.md.
SKILL_FILE="$HOME/.claude/skills/prolepsia/SKILL.md"
INFO=$(curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/version) || exit 1
LATEST=$(printf '%s' "$INFO" | python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])')
INSTALLED=$(sed -n 's/^Skill version: //p' "$SKILL_FILE" 2>/dev/null)
if [ "$LATEST" != "$INSTALLED" ]; then
  mkdir -p "$(dirname "$SKILL_FILE")"
  curl -fsSL https://app.prolepsia.com/api/v1/mcp-skill/prolepsia.md -o "$SKILL_FILE"
  echo "Updated the Prolepsia skill from ${INSTALLED:-nothing} to $LATEST."
fi

The script suits the Claude Code and Codex installs above, where the file is the skill alone. For Cursor and Windsurf, run the install command again. Never point the script at AGENTS.md or any file that holds more than the skill. Compare versions for equality only: a version is a date and a number, such as 2026-10-12.2.

How an agent should run a forecast

The skill teaches this flow. Follow it too if you write your own agent:

  1. Write the question. normalize_question drafts a complete question from a rough idea. Show the user every field before anything runs, above all the resolution criteria.
  2. Start it. create_forecast with the approved question, the run mode the user chose (runMode; list_run_modes gives each mode's time and price) and a fresh idempotencyKey. Tell the user the task id and the expected wait at once.
  3. Watch it, briefly. wait_for_forecast waits up to 55 seconds and streams progress while it waits. It usually returns with waitTimedOut: true and the forecast still going. That is normal, not a failure.
  4. Check back. Call get_forecast every few minutes until the status is completed, failed or cancelled. If the session ends, hand the user the task id; they can ask about it later.
  5. Read it. On completed, give the number from forecast.forecastData, the medium report and the sources, next to the resolution criteria.

Never call create_forecast again because a result has not arrived: that starts a second paid forecast. Never cancel because a wait ended early. To retry a lost create_forecast call, send the same arguments with the same idempotencyKey.

Templates, presets and your own servers

The server can do what the Templates page and the Connections and Forecast presets tabs in Settings do:

  • Question templates. list_question_templates lists the templates you can use. fill_question_template fills a template's blanks from a short request, such as "Nvidia, next quarter, revenue above $60 billion". create_question takes templateId and templateValues in its question, and the template writes the rest. save_question_as_template and create_question_template make new templates.
  • Forecast presets. list_forecast_presets lists your presets and your organization's. create_forecast takes presetId to pick one for a forecast, or "none" for no preset, and connections with off and on lists to switch single connections for that forecast. set_forecast_preset_defaults sets your default.
  • Your own servers. list_connections lists the MCP servers your forecasts can call and their tools. create_connection, update_connection and test_connection manage them, with the connections:read and connections:write permissions. A server that needs an OAuth sign-in gives a link through start_connection_sign_in, and a person opens it in a browser to finish.

Call the server from your own code

The server speaks JSON-RPC 2.0 over HTTP POST. Each request needs three headers: your key, Content-Type: application/json and Accept: application/json, text/event-stream. The answer is a short stream of server-sent events: progress notifications first when a tool sends them, then one data: line with the result.

These examples start a forecast and read its status. TypeScript uses the official SDK (npm install @modelcontextprotocol/sdk). Python uses plain HTTP with requests, which works whatever MCP library you have.

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";

const transport = new StreamableHTTPClientTransport(
  new URL("https://app.prolepsia.com/api/v1/mcp/"),
  {
    requestInit: {
      headers: { Authorization: `Bearer ${process.env.PROLEPSIA_API_KEY}` },
    },
  },
);
const client = new Client({ name: "my-app", version: "1.0.0" });
await client.connect(transport);

const { tools } = await client.listTools();
console.log(`${tools.length} tools`);

const started = await client.callTool({
  name: "create_forecast",
  arguments: {
    question: {
      type: "binary",
      title: "Will Brent crude settle above $90 a barrel on 31 December 2026?",
      resolutionCriteria:
        "Resolves YES if the ICE Brent front-month settlement price on 31 December 2026 is above 90.00 USD.",
    },
    idempotencyKey: crypto.randomUUID(),
  },
});
const task = started.structuredContent as { id: string; status: string };
console.log(task.id, task.status); // "queued"

const latest = await client.callTool({
  name: "get_forecast",
  arguments: { taskId: task.id },
});
console.log((latest.structuredContent as { status: string }).status);
await client.close();
import json
import os
import uuid

import requests

MCP_URL = "https://app.prolepsia.com/api/v1/mcp/"
HEADERS = {
    "Authorization": f"Bearer {os.environ['PROLEPSIA_API_KEY']}",
    "Content-Type": "application/json",
    "Accept": "application/json, text/event-stream",
}


def call_tool(name: str, arguments: dict) -> dict:
    """Call one MCP tool and return its structured result."""
    message = {
        "jsonrpc": "2.0",
        "id": str(uuid.uuid4()),
        "method": "tools/call",
        "params": {"name": name, "arguments": arguments},
    }
    response = requests.post(MCP_URL, headers=HEADERS, json=message, timeout=90)
    response.raise_for_status()
    # The answer is a server-sent event stream. Progress notifications come
    # first; the last "data:" line holds the result.
    reply = None
    for line in response.text.splitlines():
        if line.startswith("data: "):
            reply = json.loads(line[len("data: "):])
    if reply is None or "error" in reply:
        raise RuntimeError(f"MCP error: {reply}")
    result = reply["result"]
    if result.get("isError"):
        raise RuntimeError(result["content"][0]["text"])
    return result["structuredContent"]


task = call_tool(
    "create_forecast",
    {
        "question": {
            "type": "binary",
            "title": "Will Brent crude settle above $90 a barrel on 31 December 2026?",
            "resolutionCriteria": "Resolves YES if the ICE Brent front-month settlement price on 31 December 2026 is above 90.00 USD.",
        },
        "idempotencyKey": str(uuid.uuid4()),
    },
)
print(task["id"], task["status"])  # "queued"

latest = call_tool("get_forecast", {"taskId": task["id"]})
print(latest["status"])
curl -sS -X POST https://app.prolepsia.com/api/v1/mcp/ \
  -H "Authorization: Bearer $PROLEPSIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_forecast",
      "arguments": { "taskId": "2e1cc0b7-fa66-4ad4-a583-6da0e1f07ac7" }
    }
  }'

The curl answer looks like this. structuredContent holds the result as an object, and content[0].text holds the same result as JSON text for clients that read only text:

event: message
data: {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"{\"id\":\"2e1cc0b7-...\",\"type\":\"forecast_task\",\"status\":\"completed\",...}"}],"structuredContent":{"id":"2e1cc0b7-...","type":"forecast_task","status":"completed","...":"..."},"isError":false}}

initialize is optional, because every request stands alone. A tool that refuses answers with isError: true and a text such as permission_denied: connection is missing required scope 'forecasts:write'. Add "_meta": {"progressToken": "any-id"} to params to get progress notifications from wait_for_forecast.

Permissions and limits

Scope Tools it opens
questions:read Read questions, tags, context, decisions, subscriptions and question templates.
questions:write Create, draft, import and edit questions, notes, files, share links, tags, question templates and decisions.
forecasts:read Read forecasts, schedules, watches, forecast presets, chats, webhooks, deliveries and credits.
forecasts:write Start and cancel forecasts, chat, and manage schedules, watches, forecast presets and webhooks.
connections:read List your connected MCP servers and the tools they offer.
connections:write Add, change, test and delete connected MCP servers, and start their sign-in.
  • A browser assistant asks you to approve scopes when it connects. An API key keeps the scopes it was created with. When a tool needs a scope the connection lacks, it answers permission_denied and names the scope.
  • Only tool calls count against the rate limit. A browser assistant's connection may make 60 tool calls a minute. An API key shares its own per-minute limit (60 unless Prolepsia set another) with the API. Over the limit, a tool answers rate_limit_error and says how many seconds to wait.
  • An assistant's OAuth access token lasts an hour, and the assistant renews it with a refresh token. Each refresh token works once; using an old one again ends the whole connection.
  • Tools that start forecasts cost credits, like the API. get_credit_balance shows your balance, prices and plan.

Common errors

The tool answers What to do
permission_denied: connection is missing required scope '...' Reconnect and approve the scope, or create an API key that has it.
not_found: forecast task <id> is not visible to this connection The id is wrong, or belongs to another account.
invalid_request: <field>: <problem> Fix the named field. A numeric question without scaleType is the most common cause.
rate_limit_error: per-connection limit exceeded; retry after <n>s Wait that many seconds.
wait_for_forecast returns waitTimedOut: true Not an error. The forecast is still running; check again in a few minutes.
The wait ends with a connection error Not a failed forecast. Call get_forecast to see where it is.

The Prolepsia Traces server

A second, read-only server at https://app.prolepsia.com/api/v1/mcp-traces/ reads the full trace of a forecast run: what the forecaster searched, what each research branch found and what it cost. It is open to Prolepsia admins and analysts only, needs the traces:read scope, and cannot start, change or cancel anything. Its skill is at https://app.prolepsia.com/api/v1/mcp-skill/prolepsia-traces.md.

Tool reference

Every tool of the server at https://app.prolepsia.com/api/v1/mcp/, by area. Your MCP client shows each tool's arguments; the agent skill lists them with their defaults.

Forecasts

Tool What it does Scope
cancel_forecast Cancels one queued or running forecast task. Already-spent compute cannot be recovered. Repeating the same cancellation is safe. forecasts:write
cancel_many_forecasts Cancels up to 25 queued or running forecast tasks in one call and reports each one separately. A task that already finished is reported as such rather than as a failure. Compute already spent cannot be recovered. forecasts:write
create_forecast Starts one paid forecast and returns its taskId within a second; the run takes 5-90 minutes depending on the run mode. Pass a question object or a questionId, not both. context adds notes first and also needs questions:write. Reuse idempotencyKey with the same payload to retry safely for 24 hours. Files still processing block it unless allowIncompleteContext=true. forecasts:write
create_forecast_batch Starts up to 25 asynchronous Prolepsia forecasts in one call; each entry is a whole create_forecast request. Returns a task id or an error per item, so one bad entry leaves the rest running. These are paid runs: reuse idempotencyKey with the identical payload for safe retries within 24 hours. There is no stored batch record: keep the returned task ids. forecasts:write
get_forecast Returns the status and, when complete, the result for one forecast task. A run makes several subforecasts, then combines them into one answer. Every response says how many finished. partial=true means there is no combined answer, which includes failed and cancelled runs. includeSubforecasts=true adds each one's estimate, write-up and sources, making it much larger. forecasts:read
list_forecast_results Returns forecasts with their estimates, newest first, from your own questions and runs; scope=all_visible widens it. Filter by status, by several questionIds or taskIds, or by autoforecast (watch, schedule or any). Each report holds only its status and short text. fields=numeric leaves out the report and sources. Page with cursor (limit up to 100). forecasts:read
list_forecasts Returns the forecast runs on your questions or that you started, newest first, with their status but not their numbers. all=true widens it to every run you can read. Filter by status or questionId. Page with limit (default 50, up to 200) and offset. list_forecast_results returns the numbers. forecasts:read
list_question_forecasts Returns the forecasts on one question, newest first, with cursor pagination (limit up to 100). Only completed runs by default; status=null returns runs in every state. Each report holds only its status and short text; get_forecast has all three lengths. forecasts:read
list_run_modes Lists the five run modes a forecast can use, lightest first: light, moderate, standard, deep and max. Each has a label, a description, a rough time and its price in credits. defaultRunMode is the mode a forecast gets when create_forecast leaves runMode out. forecasts:read
wait_for_forecast Watches one forecast task for up to 55 seconds and returns its latest status and how many of its subforecasts have finished. The forecast continues after the wait ends. includeSubforecasts=true also returns each finished subforecast's estimate, write-up and sources, which makes the response much larger. forecasts:read

Questions

Tool What it does Scope
clarify_question Sends the user's answer to a clarification the drafting model asked for. Pass the title, draft, completionSession and clarification from the previous answer. Returns an updated draft. Uses a model call. questions:write
create_question Creates a fully-specified question without starting a forecast, optionally with tags and context notes attached in the same call. Put defaultPresetId in question (a preset id, "none", or null) to set the preset its forecasts use when none is named. Put templateId and templateValues in question to start from a template; title and type may then be left out. questions:write
get_question Return the full definition and visible tags of an existing question. questions:read
import_question Import a Metaculus, Kalshi, or Polymarket URL or identifier without starting a forecast. templateId adds a template's notes, files, tags and preset; the imported wording stays. questions:write
list_questions Returns the questions you created, newest first, 50 at a time (limit up to 200; page with offset). all=true, or scope organization, public or all_visible, widens the list. Filter by q (text), tag, questionType, source, forecastStatus and resolutionStatus; sort sets the order. questions:read
list_tags Returns the tags in use on questions visible to the connected Prolepsia account, with a question count for each. questions:read
normalize_question Drafts a complete forecast question from a rough title, using a model and web search. Nothing is saved: pass the result to create_question or create_forecast. status=unsupported comes with a suggestedReframe. templateId makes the model follow a template's drafting guidance. questions:write
revise_question Redrafts a question draft from your guidance. Pass the completionSession from the previous drafting answer to keep its context. Returns the new draft and a new completionSession. Uses a model call; drafting tools share a limit of 20 calls a minute. questions:write
set_question_tags Replaces the free-text tags on one question the connected account created. Tags organize questions and stay out of the forecasting model's inputs. questions:write
update_question Changes a question. Put the fields to change in changes; others stay as they are. After a forecast, only description, resolutionCriteria, finePrint, visibility and tags can change. The four unit fields can be set once, only while all are empty. The creator can always set defaultPresetId (a preset id, "none", or null). questions:write

Question context

Tool What it does Scope
add_question_note Adds a note for the forecaster to read on the next forecast of this question; forecasts already made stay as they are. treatment says how to use it: consider, look_into, assume_true, or ignore (the forecaster is told not to rely on it). questions:write
get_question_file Read one context file, its extraction status and metadata. questions:read
list_question_context Returns the notes and files currently attached to one question. Check a file's status here before starting a forecast: only a ready file is used by a run. questions:read
remove_question_file Stops future forecasts from using this file. Forecasts already made keep it. Calling it again is safe. questions:write
remove_question_note Stops future forecasts from using this note. Forecasts already made keep it. Calling it again is safe. questions:write
replace_question_file Replaces a file's content in one step and keeps its settings. Forecasts already made keep the old file. Returns a new file id with status processing; call wait_for_question_context before starting a forecast. questions:write
update_question_file Changes how future forecasts use one file: artifactType, treatment, targetSubforecastIndex, userNote or publicData. A field left null stays as it is; clearTarget=true removes the target. publicData=true shows a data file to everyone who can see the question; only the question's creator may set it. The content stays; replace_question_file changes it. questions:write
update_question_note Changes one context note. Put text, treatment or targetSubforecastIndex in changes; targetSubforecastIndex=null removes the target. The change applies to future forecasts. questions:write
upload_question_file Attaches a document for the forecaster to read, sent base64-encoded: up to 10 MiB per file, 10 active files and 500 MiB in all per question. Text is extracted in the background, so the file starts as processing and reaches a forecast only once it is ready. Call wait_for_question_context before create_forecast. questions:write
wait_for_question_context Waits up to timeoutSeconds (default 30; 1 to 55, other values are refused) for the question's files to become ready. Returns at once when a file failed. Running out of time ends only the wait; text extraction goes on. questions:read

Forecast chat

Tool What it does Scope
accept_forecast_context Saves the context a forecast chat answer suggested (its rerunSuggestion) as a note on the question, linked to that message. treatment is consider, look_into, assume_true or ignore. rerunNow=true also starts a paid forecast and needs forecasts:write. questions:write
chat_with_forecast Asks a question about a completed forecast and returns the answer, grounded in the stored reasoning behind that run rather than a fresh guess. Use it for why the number is what it is, what would move it, and whether a factor was considered. Costs a model call per message and takes several seconds. Omit threadId to start a conversation and pass it back to continue one. forecasts:write
get_forecast_chat Read messages in one of your forecast chat threads. forecasts:read
list_forecast_chats Returns your existing conversations about one forecast, newest first, without their messages. Use it to find a threadId to continue. forecasts:read

Schedules and automatic reruns

Tool What it does Scope
delete_schedule Permanently removes the recurring schedule for one question without cancelling runs already in progress. Repeating the deletion is safe. forecasts:write
delete_watch Turns off the automatic reforecast watch on one question, like set_watch with enabled=false. The watch and its history stay, and set_watch turns it on again. forecasts:write
get_schedule Returns the recurring forecast schedule for one visible question. forecasts:read
get_watch Returns the automatic reforecast watch on one question and its status. A watch starts a new paid forecast when the evidence behind the question changes by more than its threshold. forecasts:read
list_schedules Returns the recurring forecast schedules you set up or that run on your questions. all=true widens it to every schedule you can read. status is active or ended. Page with limit (default 50, up to 200) and offset. forecasts:read
list_watches Returns the automatic reforecast watches you can read, 20 at a time (limit up to 100). enabled=true or false filters by state. Pass nextCursor back as cursor for the next page. forecasts:read
set_schedule Creates or replaces a recurring forecast schedule for one question. Each occurrence creates a paid forecast; replacing a schedule resets its cadence. presetId sets the forecast preset its reruns use. forecasts:write
set_watch Turns the automatic reforecast watch on one question on (enabled=true) or off. While on, it starts a new paid forecast when the evidence changes by more than changeThreshold, in the question's units. Turning it on charges the monthly watch fee unless this month is already paid. presetId sets the forecast preset its reruns use. forecasts:write

Sharing and notifications

Tool What it does Scope
create_share_link Create an unlisted link granting anyone holding its token read access to the question and completed forecasts. questions:write
delete_share_link Deletes one share link and its access history; the link stops working. To keep the history, use revoke_share_link instead. questions:write
get_question_subscription Read your notification subscription for a public question. questions:read
list_share_links Lists the share links on a question you own. Anyone holding a link's token can read the question and its completed forecasts without signing in, so listing them needs write access. questions:write
revoke_share_link Turns off one share link. The link record and its access history stay, and other links keep working. questions:write
set_question_subscription Follows (enabled=true) or unfollows (enabled=false) a public question, so you start or stop getting its forecast notifications. questions:write
update_share_link Changes a share link. Put label or expiresAt in changes; expiresAt=null makes the link last until it is revoked. questions:write

Webhooks

Tool What it does Scope
create_webhook Register an HTTPS callback. Select forecast.started, forecast.completed, forecast.failed, forecast.cancelled, or forecast.report.completed; default forecast.completed. Returns a signing secret once. Up to five endpoints per user. forecasts:write
delete_webhook Delete your endpoint and cancel queued deliveries. A request already in flight may finish. Delivery history remains available. forecasts:write
get_webhook Read one of your webhook endpoints; signing secrets are omitted. forecasts:read
get_webhook_delivery Read delivery status, last error, attempt count, retry budget and next retry time. forecasts:read
list_webhook_deliveries Browse your delivery history with optional webhookId and status filters and cursor pagination. forecasts:read
list_webhook_delivery_attempts Browse every HTTP attempt for a delivery with cursor pagination, including manual replays. forecasts:read
list_webhooks List your endpoints with cursor pagination; signing secrets are omitted. forecasts:read
replay_webhook_delivery Requeue a failed or cancelled delivery to its enabled endpoint using the current URL. Preserves payload and delivery ID, retains history and resets the retry budget. forecasts:write
rotate_webhook_secret Issues a new signing secret and shows it once. For 24 hours each delivery also carries a signature made with the old secret, so your receiver can switch over. forecasts:write
test_webhook Sends a signed webhook.test event to your webhook, even while it is paused. Returns the delivery; read the result with get_webhook_delivery. forecasts:write
update_webhook Changes a webhook. Put url, description, enabled (false pauses, true resumes) or eventKinds in changes. A new url cancels deliveries still waiting; a request already sent can still arrive. forecasts:write

Connections

Tool What it does Scope
create_connection Add an MCP server that forecasts can call. scope is personal (your forecasts) or organization (every member's, organization admins only). authKind is none, api_key (send api_key, write-only) or oauth (then call start_connection_sign_in). The server is tested and its tools listed; tools that change data start off. connections:write
delete_connection Deletes a connection. Forecasts already running keep the list they started with and report it as unavailable; past forecasts keep what they recorded. When presets switch the connection off, nothing is deleted and the answer is in_use with the number of presets; call again with confirm=true to delete it anyway, and those presets lose the entry. connections:write
get_connection Read one connection with its status, last error and the tools its server offers, each with an allowed switch. Keys are not shown. connections:read
list_connections List the MCP servers your forecasts can call: your own and your organization's. Keys and sign-ins are not shown; hasApiKey and signedIn say whether one is stored. connections:read
set_connection_member_switch Turns an organization connection on or off for your own forecasts only. Others keep using it. A personal connection has its own enabled switch (update_connection). connections:write
start_connection_sign_in Starts an OAuth sign-in for an oauth connection and returns authorizationUrl, which the person must open in a browser to sign in at the server. Call get_connection afterwards until signedIn is true. connections:write
test_connection Connects to the server again and refreshes its tool list. A failure comes back as status failing with the reason, not as an error. Tool switches you set stay as they are. connections:write
update_connection Changes a connection. Put name, url, authKind, api_key, apiKeyHeader, enabled or tools in changes; tools maps a tool name to true (allowed) or false. A new url, key or header tests the connection again. connections:write

Forecast presets

Tool What it does Scope
create_forecast_preset Adds a preset. scope is personal (only you) or organization (everyone in it; organization admins only). disabledConnectionIds lists the connections the preset switches off; every other enabled connection stays on. notes is a list of {"text", "treatment"} entries added to each forecast that uses the preset. Add files afterwards with upload_forecast_preset_file. forecasts:write
delete_forecast_preset Deletes a preset and its files. When defaults, questions, schedules, watches or live decisions still use it, nothing is deleted and the answer is in_use with the counts. Call again with confirm=true to delete it anyway; those then use the defaults. Past forecasts keep what the preset gave them. forecasts:write
delete_forecast_preset_file Deletes a file and its extracted text from a preset. Past forecasts keep what they used. forecasts:write
get_forecast_preset Reads one preset with its notes, its files (each with a status; a run uses a file once it is ready) and the connections it switches off. forecasts:read
get_forecast_preset_defaults Reads your default preset and your organization's. A forecast with no preset named uses the question's own preset, then yours, then your organization's. presetRemovedAt is set when a default's preset was deleted. forecasts:read
list_forecast_presets Lists the forecast presets you can use: your own and your organization's. A preset holds standing notes, files and a list of connections to switch off, and a forecast can start with one. Each preset shows isUserDefault and isOrganizationDefault. forecasts:read
set_forecast_preset_defaults Sets your default preset with userPresetId and your organization's with organizationPresetId (organization admins only, and an organization preset), given in changes. A preset id sets it and null clears it; a key you leave out stays as it is. forecasts:write
update_forecast_preset Changes a preset. Put name, description, disabledConnectionIds or notes in changes. disabledConnectionIds and notes are the whole new list: a note with its id keeps that note, and a note left out is removed. Fields you leave out stay as they are. forecasts:write
update_forecast_preset_file Changes a preset file's artifactType, treatment or userNote, given in changes. Replace a file by deleting it and adding the new one. forecasts:write
upload_forecast_preset_file Adds a file to a preset from filename and contentBase64. The file is read in the background; a run uses it once its status is ready, and a forecast that would use the preset waits for it unless allowIncompleteContext is set. artifactType and treatment work as for question files. A preset holds at most 10 files. forecasts:write

Question templates

Tool What it does Scope
create_question_template Adds a template. scope is personal or organization (organization admins only). fields holds the question fields (title, description, resolutionCriteria, finePrint, options, bounds) and may use {key} blanks, each declared in blanks as {"key", "label"}. notes are {"text", "treatment"} entries. Add files with upload_question_template_file. questions:write
delete_question_template Deletes a template, its notes and its files. When questions or waiting decision drafts still use it, nothing is deleted and the answer is in_use with the counts. Call again with confirm=true to delete it anyway. Questions made from it keep their wording. questions:write
delete_question_template_file Deletes a file and its extracted text from a template. Questions already made from it keep their own copies. questions:write
fill_question_template Asks the AI for a value for every blank of a template that you have not filled in, from a short prompt such as "Acme, next quarter". templateValues keeps the blanks you already filled. Answers templateValues for every blank; send them to create_question or create_forecast. questions:write
get_question_template Reads one template with its fields, blanks, notes, files (each with a status; a question can use a file once it is ready), tags and preset. questions:read
list_question_templates Lists the question templates you can use: Prolepsia's built-in ones, your organization's and your own. A template holds question fields with named {blank} markers, starting notes and files, tags and a forecast preset. scope keeps one kind. questions:read
save_question_as_template Saves a question you can read as a template named name. scope is personal or organization (organization admins only). The template takes the question's fields without blanks. For the question's creator it also takes the tags, starting notes, ready files and default preset. questions:write
update_question_template Changes a template. Put the fields to change in changes: name, description, questionType, fields, blanks, draftingGuidance, tags, shareWithOrganization, forecastPresetId or notes. notes is the whole new list: a note with its id keeps that note and a note left out is removed. Questions already made from it stay as they are. questions:write
update_question_template_file Changes a template file's artifactType, treatment or userNote, given in changes. Replace a file by deleting it and adding the new one. questions:write
upload_question_template_file Adds a file to a template from filename and contentBase64. The file is read in the background; a question can be made from the template once every file is ready. artifactType and treatment work as for question files. A template holds at most 10 files. questions:write

Decisions

Tool What it does Scope
acknowledge_decision_handover Dismisses the notice a new owner reads after a decision was handed to them. acknowledged is false when no notice was open. questions:write
add_decision_comment Adds a comment to a decision's discussion: nodeId or linkId for one of them, neither for the whole decision, or parentId to reply (a reply takes no nodeId or linkId). The author and organization members can comment on a shared decision; observers cannot. Comments reach no forecast or summary. questions:write
add_decision_note Adds a note to the whole decision. A copy goes into the notes of each question on the map that you created; other people's questions get none (see receivesDecisionNotes in get_decision). type is consider, look_into, assume_true or ignore. questions:write
add_question_to_decision Puts a question on a decision's map: an existing one (questionId) or a new one from a template (templateId, templateValues). While live mode is on, includeInLiveMode true keeps it up to date for its fee (quote it with estimate_decision_live and questionId; send the fee as maxFeeCredits). Left out, it stays off and monitoring says so. questions:write
answer_decision_live_continuation Answers the question a decision asks when it moves on with live mode on (get_decision live.monitoring.continuation names it). keepMonitoring true keeps live mode on for that situation; false turns it off and stopped says what stopped. Nothing open changes nothing. timeZone is the zone the deadline was read in. Author only. forecasts:write
approve_decision_research_plan Approves the plan you read: keeps its forecast drafts and items. It starts no forecast and charges nothing; start_decision_forecasts does that. entryIds must be every waiting entry not put aside (else plan_changed). A moved price answers price_changed. Reuse idempotencyKey to retry. questions:write
archive_decision Archives a decision, which makes its map read-only. Pass archived=false to make an archived decision editable again. Author only. questions:write
check_decision_questions Author only. Asks the model which questions on the map look like a fact, an action or an assumption, and stores a flag with a reason for each (questionFlags in get_decision). No question changes; a question already flagged is not asked about again. Counts toward the shared limit of 10 decision model calls a minute. questions:write
convert_decision_work Author only. draft_to_item turns a question draft (draftId) into a fact, action or assumption (kind); the draft is discarded. item_to_draft turns an item (itemId) nobody has worked on into a question draft (questionType, binary by default). A repeat returns the first result. questions:write
create_decision Creates a decision from a title, context, a decideBy date (YYYY-MM-DD) and 2 to 4 options. Queues the first drafts; poll get_decision until generation.status is succeeded or failed. Reuse idempotencyKey with the same payload to retry safely. templateId makes the drafts follow a question template. Counts toward the shared limit of 10 decision model calls a minute. questions:write
create_decisions_from_intake_session Creates the prepared decisions once, each with the constraints, goals and preferences you confirmed. Unconfirmed proposals are left out and counted. An unconfirmed suggested date is refused with a field error. A repeat returns the same decisions with replayed true. questions:write
defer_decision_plan_entries Puts plan entries aside (deferred true) or brings them back (false). Put-aside entries stay out of the price and out of approval. Repeating changes nothing. Author only. questions:write
discard_decision_intake_session Discards a conversation and empties it. Discarding one that is already closed changes nothing. questions:write
dismiss_decision_attention Puts reasons away for you only. Pass reasons copied from an attention item ({reason, key}). Each stays away until it returns with a different key. via opened marks a summary as read. Repeating it changes nothing more. questions:write
edit_decision_link Changes the condition or preset of a conditional link whose question could not be written, and tries again. Pass the link id from get_decision. Other links are refused. Poll get_decision for the result. Counts toward the shared limit of 10 decision model calls a minute. questions:write
edit_decision_note Changes the text or the type of a decision note. Pass the note id from get_decision. The copies on the questions change with it. questions:write
estimate_decision_forecasts Quotes starting forecasts on a decision: pricePerForecast, selectedNodeIds, unfinishedNodeIds, the total, ownTotalCredits (what your balance pays), balanceState and cannotStart. Nothing starts or is charged. Pass pricePerForecast and runMode to start_decision_forecasts, and unfinishedNodeIds as nodeIds to retry only what did not run. forecasts:read
estimate_decision_live Quotes live mode: watcherFeeTotal due now (only questions it would charge), freeNodes with the reason each costs nothing, the monthly fees, the cap, and mostPerMonthCredits. Send runMode and monthlyCapCredits, and questionId to quote one question. Pass watcherFeeTotal to set_decision_live as maxFeeCredits. Nothing is charged. Author only. forecasts:read
generate_decision_questions Asks for another round of question drafts. kind is more (default) or expand with the sourceNodeId of a question to dig into; a shared decision refuses a question colleagues cannot read. Returns a generation id; poll get_decision. One round runs at a time. templateId makes the drafts follow a template. Counts toward the shared limit of 10 decision model calls a minute. questions:write
get_decision Returns a decision's map: state (progress, evidence, monitoring), options, criteria, evidence items, questions with their latest forecast, drafts, the newest generation run, the summary and sharing. A question you cannot read shows only in hiddenNodes. A shared decision's summary uses only questions every member can read. questions:read
get_decision_brief Reads one stored summary as a document: decision, options, criteria, the model's reading and its limits, evidence with dates and units, the recorded choice, next actions, review, version and date. It is fixed once written. audience organization previews what the organization sees. questions:read
get_decision_comparison Reads a decision's criteria, how each option stands against each (assessments), the chance a measured constraint's forecast meets its threshold, what each option still needs, and the payoff what-if. It ranks nothing. A state a model proposed does not count until the author confirms it. The what-if is not a forecast. questions:read
get_decision_evidence Reads one question (kind question, id = its map node id) or evidence item (kind item) behind a claim: full text, the forecast and unit the brief used, the current one if it differs, sources, history and limits. summaryId picks the brief; audience organization previews what the organization sees. questions:read
get_decision_intake_session Returns a conversation, the draft beside it (goal, options, decide-by date, hard constraints, goals, preferences, what is missing), the prepared decisions with your edits, and its version. Only its owner can read it. questions:read
get_decision_ownership Reads who owns a decision, whether you may hand it over (transferAs owner, or admin while the author is suspended or gone) and candidates, the active members it can go to. For a new owner, notice says who handed it over, what moved and what stayed, and which questions they can_rerun, read_only or hidden. questions:read
get_decision_research_plan Returns the ranked work a decision waits on: forecasts beside facts, actions and assumptions. Each entry names what it informs and what result could change the choice. Overlaps are flagged and shared-basis entries are not independent evidence. quote prices the forecasts. Colleagues get an empty plan. questions:read
get_decision_review_updates Lists changes that call for a review of the recorded choice: a confirmed constraint rule crossed, the chosen option's confirmed state changed, a relied-on fact disputed or assumption rejected. Each has old and new evidence and why it matters. incomplete lists refreshes that did not finish. A changed model reading alone is not a change. questions:read
get_decision_summary Returns the newest ready summary of a decision, which weighs each option against the forecasts, and the status of the newest run. summary is null until one is written. summary.freshness says if it still matches the current forecasts (current, new_evidence, updating, update_failed); summary.coverage counts the questions it used and those missing or failed. questions:read
link_decision_questions Links two nodes. type context feeds the source's forecast into the target's next forecast (get_decision says if it was passed). type conditional asks the target again if a condition about the source holds: give condition or preset source_yes/source_no and poll get_decision. A conditional link counts toward the shared limit of 10 decision model calls a minute. questions:write
list_decision_choices Reads every choice the author recorded (oldest first), the current one, the reviews, the review the current choice waits on and your reminder setting. A choice keeps a snapshot of what was known when it was recorded. questions:read
list_decision_comments Lists the comments on a decision, oldest first: on the whole decision, a node or a link, with replies one level deep. Comments on a node or link you cannot read are left out. Comments reach no forecast or summary. questions:read
list_decision_conditions Lists the conditions on a decision with their newest checks. A condition is a statement about the world that Prolepsia checks against the web while live mode is on. Each shows state (armed or met), nodeIds, hiddenNodeCount and its checks. checking says whether live mode is on. questions:read
list_decision_criteria Lists a decision's current criteria in order: goals, hard constraints and preferences, each with kind, text, weight, measure, origin (customer or model) and confirmed. A model's proposal has confirmed false until the author confirms it. questions:read
list_decision_intake_sessions Lists your unfinished conversations that have not become decisions yet, newest change first, each with a label, step and version. They are private to you and deleted 30 days after the last change. questions:read
list_decision_items Lists a decision's facts to check, actions to do and assumptions to confirm, in order, each with kind, text, why, origin, status and the fields of its kind (source, owner, due date, who accepted). Forecast work is not an item: it stays as questions on the map. questions:read
list_decisions Lists the decisions you can read, newest change first, with option, question and open-draft counts. status is active (default), archived or all. Page with limit and offset. questions:read
list_decisions_needing_attention Lists active decisions needing attention, most urgent first: overdue review or action, passed deadline, deadline within 7 days, blocked research, summary to read. Each has reasons (reason, key, why) and one action. A colleague gets fewer reasons. timeZone sets the day. questions:read
prepare_decision_intake_session Asks the model to write the decisions from the conversation and draft into the session, on its review step. Dates it writes have decideByOrigin suggested until you confirm them with save_decision_intake_session. Needs the version you read. questions:write
refresh_decision_summary Queues a fresh summary of a decision from its latest forecasts and returns the summary id; poll get_decision_summary. One summary is written at a time. Counts toward the shared limit of 10 decision model calls a minute. questions:write
remove_decision_link Removes a link. Both questions and any conditional question it wrote stay on the map. Pass the link id from get_decision. questions:write
remove_decision_note Removes a decision note. Its copies leave the questions. Pass the note id from get_decision. questions:write
remove_decision_plan_entries Removes plan entries: a forecast draft is discarded and a proposed item removed. All go or none does. Author only. questions:write
remove_question_from_decision Takes a node off a decision's map. The question and its forecasts stay. Pass the node id from get_decision, not the question id. questions:write
reply_decision_intake_session Asks the model to answer the last message. It updates the draft: what you set stays, its date is only a suggestion, its limits are unconfirmed proposals. Needs the version you read. Answers intake_nothing_to_answer when no message waits. questions:write
review_decision_drafts Keeps or discards question drafts by id; action is keep or discard, and any other value is refused. A kept draft becomes a question on the map within a minute or two. All named drafts change or none does. To edit a draft first, use REST PATCH /decisions/{decisionId}/drafts/{draftId}. Keep counts toward the shared limit of 10 decision model calls a minute. questions:write
review_question_flag Author only. action dismiss leaves the question as it is and it is not flagged again. action convert adds the matching item (kind optional, defaults to the flag's suggestion) and keeps the question on the map. questions:write
save_decision_assessment Author only. action set records a state (hard constraint: satisfied, violated, unknown; goal or preference: supports, conflicts, neutral, unknown) with optional nodeIds, itemIds and a note. confirm accepts a state a model proposed. clear resets it to unknown. A proposal counts only once confirmed. questions:write
save_decision_choice Author only. action record stores the choice: kind option (with optionId), wait, decline_all or gather_evidence, a rationale, and who is responsible. Optional: decidedAt, review (a wait needs one), actions, keepMonitoring (true keeps live mode on, false turns it off). action reopen takes it back with a reason. Record only what the author told you. questions:write
save_decision_condition Author only. Adds a condition (no conditionId), changes or re-arms one (conditionId), or removes one (conditionId and delete true). When an armed condition is found met, its nodes' questions are forecast again (credits, counted toward the monthly cap) and followers are emailed. Checked only while live mode is on. At most 10 per decision. questions:write
save_decision_criterion Author only. Adds a criterion (kind goal, hard_constraint or preference, and text), changes one (criterionId and fields; the answer has the new version's id), confirms a proposal (criterionId, confirmed true), removes one (delete true), or orders them (criterionIds). Weight 1-5 is for preferences; a measure {direction, threshold, unit} for hard constraints. Max 20. questions:write
save_decision_intake_session Saves with the version you read: message, draft, prepared decisions, step, templateId. An older version answers intake_session_stale and saves nothing. A model date has origin suggested and a proposed constraint confirmed false: send origin customer and confirmed true to confirm. questions:write
save_decision_item Author only. Adds an item (kind fact, action or assumption, text), edits one (itemId, fields), corrects its kind (kind alone), keeps a model proposal (confirmed true alone), moves its status (verify a fact with sourceUrl or sourceNote, finish an action with completionNote) or removes it (delete true). An empty string clears an optional field. Max 100. questions:write
save_decision_next_action Author only. action add creates an action linked to the current choice (text, optional why, ownerUserId or ownerName, dueDate, and optionIds or criterionIds for what the action settles). action complete marks the action itemId done with a completionNote, and newFact ({text, why, sourceUrl, sourceNote}) adds a fact it supplied as unverified. questions:write
save_decision_payoff_model Author only. action save replaces the payoffs: a scenarioNodeId (a yes-or-no or multiple-choice question on the map), a unit, an optional lossLimit and payoffs {optionId: {outcome: number}}. They are the author's own values, so ask for them. action remove deletes them. Powers a what-if, not a forecast. questions:write
save_decision_review Author only. action schedule sets a review (dueDate, conditionText or both). action complete closes reviewId with outcome keep, change or defer and a reason; defer needs nextReview, change needs newChoice; keepMonitoring true keeps live mode on, false turns it off. action notes records what happened. action cancel cancels it. questions:write
save_decision_review_trigger Author only. action set confirms a rule on a hard constraint with a measure linked to a question: kind breach_chance_above (review when the chance of breaching is above limitPercent) or breach_chance_rise (it rose by limitPercent points since the baseline). remove deletes it. The limit is the author's own: ask. questions:write
set_decision_follow Follows or unfollows a decision shared with your organization, so you get an email when its summary shifts (the leading option changes or a key forecast moves). Send following true or false. Repeating a request changes nothing. The author always gets these emails and cannot follow. questions:write
set_decision_live Turns live mode on or off for a decision you made. On, it watches each question, reruns those that depend on a moved forecast and emails you when the summary shifts. Send runMode and monthlyCapCredits; pass watcherFeeTotal from estimate_decision_live as maxFeeCredits (else price_changed). Reuse idempotencyKey to retry. Off, stopped says what keeps running. forecasts:write
set_decision_node_monitoring Includes one question of a live decision in live mode, or leaves it out. Include true starts its reruns and charges a month's fee unless paid; quote it with estimate_decision_live and questionId, send the fee as maxFeeCredits (a higher fee answers price_changed). False gives back its reruns; stopped says what stays. Pass the node id. Author only. forecasts:write
set_decision_reminder_emails Switches your own reminder emails for the decision on or off. They tell the author, and the person responsible who can still read it, that a review is due or a next action is overdue. questions:write
start_decision_forecasts Starts paid forecasts for a decision's questions, or nodeIds (up to 25; pass the estimate's unfinishedNodeIds to retry only what did not run). Estimate first; pass its pricePerForecast as expectedPricePerForecast, its runMode, and maxTotalCredits as a ceiling. A moved price answers price_changed and starts nothing. Reuse idempotencyKey to retry. forecasts:write
start_decision_intake_session Starts a conversation about a problem, with your first message if you give one. Asks no model: call reply_decision_intake_session for the answer. Returns the session with its version. questions:write
transfer_decision Hands a decision shared with the organization to an active member from get_decision_ownership candidates. Author only, or an organization admin while the author is suspended or gone. Questions keep their authors; the new owner gains no access to what they could not read. Ask the user first: the old owner can then only read. Reuse idempotencyKey to retry. questions:write
update_decision Changes a decision's title, context, decideBy, options or visibility; only supplied fields change. A list of options replaces the active ones (keep one by its id). visibility 'organization' lets your organization read and comment on it; 'private' takes it back. shareQuestionIds also shares private questions on the map (see sharing in get_decision). Author only. questions:write

Account

Tool What it does Scope
get_credit_balance Returns your organization's credit balance, whether it has unlimited credits, each top-up with its expiry date, the current prices, and its plan with the date the plan renews. forecasts:read