BeliefState

Cited investor theses, risks, catalysts and historical cutoffs. 16 paid research tools via x402 on Base USDC; compatible wallet required, no account or API key.

Hosted MCP Server

npx add-mcp 'https://beliefstate.ai/v1/research/mcp'

Installs into Claude Code, Codex, Cursor and more

Documentation

BeliefState agent quickstart

Choose access

  • Accountless research: use x402 over HTTP or native MCP. Fourteen data tools cost 0.02 USDC per call; built-in comparison costs 0.50 USDC and search costs 1.50 USDC on Base. No BeliefState account, API key or subscription.
  • Account-based research and personal tracking: use your existing funded MCP or REST account.

Try an investor research task

Copy this into an agent that supports x402 and user-approved wallet spending:

Research the company we are discussing with BeliefState. If no company is named, ask which one. Check free ticker coverage first. Prepare one overview with up to five research views for 0.02 USDC on Base and show the quote before signing. After my approval and successful delivery, summarize attributed theses, catalysts, risks, dates, citations and coverage gaps. If the requested company is unavailable, report that gap without substituting another company.

For historical research, add your requested RFC 3339 as_of cutoff. Report unavailable historical coverage. Keep the source observation dates separate from the cutoff.

For an existing account-based MCP connection:

Find investment theses where power scarcity creates pricing power. Compare two supported cases, cite their evidence, and identify what could weaken each. Report missing evidence and coverage.

Pay per call with x402

Use the live research catalog to discover 16 accountless x402 research tools. Fourteen data tools cost 0.02 USDC per call on Base, including full cases, current and historical briefs, risks, catalysts, changes, author track records, entities, relationships, scenarios and stored research visuals. Built-in model comparisons cost 0.50 USDC; model-assisted thesis search costs 1.50 USDC. Agents can buy the underlying cases for 0.02 USDC and use their own models. No BeliefState account, API key or subscription is required. Check free coverage first. The accountless quickstart explains signing, exact-request retry and receipts.

Call POST /v1/research/{tool} with that tool's JSON arguments, or connect an x402-capable MCP client to https://beliefstate.ai/v1/research/mcp. The live quote supplies the current network, token, amount and receiving address. Omit Authorization for x402. Existing account-based MCP at /mcp and authenticated REST retain their access and billing.

  1. Read https://beliefstate.ai/v1/research for current tools and prices, then GET /v1/research/{tool} for its exact input/output schemas and an illustrative example. Read https://beliefstate.ai/v1/tickers without credentials and choose the user's requested ticker. POST JSON arguments to the selected tool. Use actual record IDs from purchased results; illustrative IDs are not released research. GET /v1/brief/{ticker} remains available for an overview with optional as_of and max_results from 1 to 5.
  2. Request the exact URL and JSON body without Authorization. A live offer returns HTTP 402 with base64 JSON in PAYMENT-REQUIRED and the same JSON body. Validate x402Version=2, scheme=exact, Base network=eip155:8453, native USDC asset=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, the intended receiving address, and the approved amount in six-decimal atomic units: 20000 for data tools, 500000 for compare_beliefs, or 1500000 for search_beliefs. The quoted amount is the buyer total; BeliefState absorbs any applicable sales tax.
  3. Use a compatible x402 EIP-3009 wallet/client with native USDC on Base and a user-approved spending limit. Echo the quote's resource and extensions, including bazaar, in the payment payload. Coinbase's buyer guide and client configuration document supported clients and spend controls. Select Base mainnet, not the testnet examples. Never put wallet keys or payment signatures in chat or logs.
  4. Persist the exact method, URL, JSON body and complete signed PAYMENT-SIGNATURE securely before submitting. Retry that identical request with PAYMENT-SIGNATURE and no Authorization. On HTTP 200, decode PAYMENT-RESPONSE and BELIEFSTATE-PAYMENT-RECEIPT, match the settlement, network and buyer total, then inspect the cited data and coverage limits. Preparation failures are not submitted for payment. A 402 quote or wallet signature alone is not delivery proof.
  5. On HTTP 503 with error.code=payment_pending, honor Retry-After and retry the same saved URL and signature using raw HTTP. Preserve the same resource, extensions and nonce. Do not start a fresh payment or regenerate a signature while an outcome is unresolved, even after its authorization expires. A fulfilled retry returns the original response and receipt. HTTP 410 can mean source access changed, a refund is required, or a refund completed; inspect the returned error and retain the purchase until refund status is confirmed. HTTP 410 alone is not refund proof. Other failures retain the saved request for diagnosis before any new purchase.

Check current coverage without credentials or payment:

curl -fsS 'https://beliefstate.ai/v1/tickers'

Set BELIEFSTATE_TICKER to the released ticker from the user's question, then request an unpaid quote on the indexed ticker path:

curl -i "https://beliefstate.ai/v1/brief/${BELIEFSTATE_TICKER:?Set the requested ticker from current coverage}"

HTTP 402 advertises the price; this command does not pay. The complete overview response contract is X402BriefOverview. Discovery includes a clearly labeled illustrative example; it is not live research.

Research tools and native MCP

Each paid tool has its own POST resource, description, research tags and executable schemas. Bazaar indexes a resource after a successful CDP-facilitated settlement; the live catalog is the authoritative list even while new listings are being indexed. A listing is not evidence of customer demand or guaranteed search placement.

Price per callToolsUse
0.02 USDCget_brief, refresh_market_data, get_beliefs, get_beliefOverview/full/current/historical research, saved cases and market context
0.02 USDCget_belief_risks, get_belief_catalysts, get_belief_changes, get_author_track_recordRisks, catalysts, revisions and publication-based outcomes
0.02 USDCsearch_entities, get_context_assessment, get_belief_relationships, evaluate_belief_scenarioEntities, retained context, supported relationships and scenario assumptions
0.02 USDClist_research_visuals, get_research_visualPermitted stored chart/table descriptions, regions and typed values
0.50 USDCcompare_beliefsBuilt-in model comparison of two released cases
1.50 USDCsearch_beliefsBuilt-in model-assisted thesis/setup search

Native MCP URL: https://beliefstate.ai/v1/research/mcp. It exposes the same 16 paid tools plus free get_tickers and search_companies. It requires an x402-capable wallet client; ordinary OAuth-only MCP clients use /mcp with an account. Personal tracked tickers remain account-only.

MCP quotes return isError=true with the same PaymentRequired object in structuredContent and text. Retry the same tool and arguments with the signed payload in _meta["x402/payment"]. Save that payload before submission. Success includes _meta["x402/payment-response"] and _meta["ai.beliefstate/payment-receipt"]. Pending/error results retain HTTP status and retry seconds in BeliefState metadata. Retry a pending purchase with its saved payload, never a fresh payment. Large full exports that exceed MCP limits fail before settlement and point to the full HTTP export.

For an unsigned inventory quote:

curl -i --request POST 'https://beliefstate.ai/v1/research/get_beliefs' \
  --header 'Content-Type: application/json' \
  --data '{"ticker":"REQUESTED_TICKER","limit":5}'

Choose the requested ticker from live coverage; REQUESTED_TICKER is an input illustration. GET /v1/research/get_beliefs?schema=input and ?schema=output expose standalone JSON schemas. Other tools follow the same pattern.

Overview wallet example with safe retries

This example uses the standard x402 SDKs verified against BeliefState's gateway. Use a dedicated programmatic buyer wallet from your secret store; never export a MetaMask recovery phrase or put keys in chat. Fund it with native USDC on Base. This wallet is the buyer, separate from BeliefState's receiving wallet.

Install the pinned client dependencies:

npm install @x402/core@2.28.0 @x402/evm@2.28.0 viem@2.57.10

Save the following as buy.mjs, set PAYMENT_WALLET_PRIVATE_KEY through your secret store, and run node buy.mjs REQUESTED_TICKER with Node.js 22 or later. An optional third argument supplies the historical RFC 3339 cutoff. The example signs at most one 0.02-USDC purchase. Keep the state file private and reuse it for every retry. Use another state file only for a separately approved purchase after the previous outcome is resolved.

import assert from "node:assert/strict";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { x402Client } from "@x402/core/client";
import { encodePaymentSignatureHeader } from "@x402/core/http";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const ticker = (process.argv[2] || "").trim().toUpperCase();
assert(/^[A-Z0-9][A-Z0-9.-]{0,14}$/.test(ticker), "Supply the requested ticker");
const asOf = process.argv[3];
if (asOf) {
  assert(/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,9})?(?:Z|[+-]\d{2}:\d{2})$/.test(asOf), "Use an RFC 3339 cutoff with an explicit timezone");
  const day = new Date(asOf.slice(0, 10) + "T00:00:00Z");
  assert(Number.isFinite(day.getTime()) && day.toISOString().slice(0, 10) === asOf.slice(0, 10), "Use a valid calendar date");
  assert(Number.isFinite(Date.parse(asOf)) && Date.parse(asOf) <= Date.now(), "Use a past RFC 3339 cutoff");
}
const cutoff = asOf ? new Date(asOf).toISOString() : null;
const target = new URL("https://beliefstate.ai/v1/brief/" + encodeURIComponent(ticker));
if (cutoff) target.searchParams.set("as_of", cutoff);
const url = target.href;
const legacy = new URL("https://beliefstate.ai/v1/brief");
legacy.search = new URLSearchParams({ ticker, detail: "overview" }).toString();
if (cutoff) legacy.searchParams.set("as_of", cutoff);
const stateFile = process.env.PAYMENT_STATE_FILE || "beliefstate-x402-payment.json";
let saved;
if (existsSync(stateFile)) {
  saved = JSON.parse(readFileSync(stateFile, "utf8"));
  assert(saved.url === url || saved.url === legacy.href, "Reuse the saved request's exact ticker and cutoff");
} else {
  const response = await fetch(url, { redirect: "error" });
  assert.equal(response.status, 402, "Expected a live payment quote");
  const quote = await response.json();
  assert.equal(quote.x402Version, 2);
  assert.equal(quote.resource.url, url);
  assert.equal(quote.accepts.length, 1);
  const offer = quote.accepts[0];
  assert.equal(offer.scheme, "exact");
  assert.equal(offer.network, "eip155:8453");
  assert.equal(offer.asset.toLowerCase(), "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913");
  assert.equal(offer.payTo.toLowerCase(), "0xd346b16f2c013d8219350d32e511023d16db9aee");
  assert.equal(offer.amount, "20000");
  assert(offer.maxTimeoutSeconds > 0 && offer.maxTimeoutSeconds <= 300);
  const signer = privateKeyToAccount(process.env.PAYMENT_WALLET_PRIVATE_KEY);
  const client = new x402Client()
    .setSpendControls({ maxAmountPerPayment: "$0.02" })
    .register("eip155:8453", new ExactEvmScheme(signer));
  const payload = await client.createPaymentPayload(quote);
  saved = { url, paymentSignature: encodePaymentSignatureHeader(payload) };
  writeFileSync(stateFile, JSON.stringify(saved), { flag: "wx", mode: 0o600 });
}
const response = await fetch(saved.url, {
  redirect: "error",
  headers: { "PAYMENT-SIGNATURE": saved.paymentSignature },
});
console.log({
  status: response.status,
  retryAfter: response.headers.get("Retry-After"),
  paymentResponse: response.headers.get("PAYMENT-RESPONSE"),
  receipt: response.headers.get("BELIEFSTATE-PAYMENT-RECEIPT"),
});
console.log(await response.text());

Decode receipt headers as base64 JSON and verify the settlement before treating the result as purchased. On payment_pending or a transport error, rerun the same command with the same state file; no signing key is needed for a saved retry. Do not replace the file or use an automatic fresh-payment wrapper to resolve an ambiguous purchase.

Buy another research tool

Use the same pinned dependencies above. Save this as buy-research.mjs. Run, for example, node buy-research.mjs get_beliefs '{"ticker":"REQUESTED_TICKER","limit":5}' after checking coverage. Select the tool and approve its listed price before running. Use a distinct private PAYMENT_STATE_FILE for each separately approved purchase; keep it unchanged for retries.

import assert from "node:assert/strict";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { x402Client } from "@x402/core/client";
import { encodePaymentSignatureHeader } from "@x402/core/http";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const dataTools = ["get_brief", "refresh_market_data", "get_belief_risks", "get_belief_catalysts", "get_author_track_record", "get_belief", "get_beliefs", "search_entities", "get_belief_changes", "get_context_assessment", "list_research_visuals", "get_research_visual", "get_belief_relationships", "evaluate_belief_scenario"];
const tool = process.argv[2];
const cents = tool === "compare_beliefs" ? 50 : tool === "search_beliefs" ? 150 : dataTools.includes(tool) ? 2 : null;
assert(cents !== null, "Choose a tool from the current research catalog");
const args = JSON.parse(process.argv[3] || "{}");
assert(args && typeof args === "object" && !Array.isArray(args), "Arguments must be a JSON object");
const body = JSON.stringify(args);
const url = "https://beliefstate.ai/v1/research/" + encodeURIComponent(tool);
const stateFile = process.env.PAYMENT_STATE_FILE || "beliefstate-research-payment.json";
let saved;
if (existsSync(stateFile)) {
  saved = JSON.parse(readFileSync(stateFile, "utf8"));
  assert(saved.method === "POST" && saved.url === url && saved.body === body, "Retry the saved method, URL and arguments exactly");
} else {
  const response = await fetch(url, { method: "POST", redirect: "error", headers: { "Content-Type": "application/json" }, body });
  assert.equal(response.status, 402, "Expected a live payment quote");
  const quote = await response.json();
  assert.equal(quote.x402Version, 2);
  assert.equal(quote.resource.url, url);
  assert.equal(quote.accepts.length, 1);
  const offer = quote.accepts[0];
  assert.equal(offer.scheme, "exact");
  assert.equal(offer.network, "eip155:8453");
  assert.equal(offer.asset.toLowerCase(), "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913");
  assert.equal(offer.payTo.toLowerCase(), "0xd346b16f2c013d8219350d32e511023d16db9aee");
  assert.equal(offer.amount, String(cents * 10000));
  assert(offer.maxTimeoutSeconds > 0 && offer.maxTimeoutSeconds <= 300);
  const client = new x402Client()
    .setSpendControls({ maxAmountPerPayment: "$" + (cents / 100).toFixed(2) })
    .register("eip155:8453", new ExactEvmScheme(privateKeyToAccount(process.env.PAYMENT_WALLET_PRIVATE_KEY)));
  const payload = await client.createPaymentPayload(quote);
  saved = { method: "POST", url, body, paymentSignature: encodePaymentSignatureHeader(payload) };
  writeFileSync(stateFile, JSON.stringify(saved), { flag: "wx", mode: 0o600 });
}
const response = await fetch(saved.url, {
  method: saved.method,
  redirect: "error",
  headers: { "Content-Type": "application/json", "PAYMENT-SIGNATURE": saved.paymentSignature },
  body: saved.body,
});
console.log({ status: response.status, retryAfter: response.headers.get("Retry-After"), paymentResponse: response.headers.get("PAYMENT-RESPONSE"), receipt: response.headers.get("BELIEFSTATE-PAYMENT-RECEIPT") });
console.log(await response.text());

The first quote does not charge. The signed request can charge the exact approved price. Resolve pending or uncertain outcomes using the saved request and authorization before creating another purchase. Full cases, inventories and changes let agents perform their own comparisons or search with their own model budget.

For account-based access, connect a supported MCP-capable AI agent to BeliefState as a remote, read-only server. No BeliefState SDK is required.

Reach the first useful result with an account

  1. Reuse an existing admitted MCP connection or securely stored developer key. Read /llms.txt and /openapi.json for the current interfaces; do not create duplicate credentials.
  2. If access is missing, follow the supported authorization path below. The person completes sign-in and consent. A trusted local agent can run the device flow from /auth.md without asking the person to copy a key.
  3. Fetch /v1/tickers without credentials and match the company in the person's question. For an explicit connection test without a company, choose a returned ticker and label the result as a test. Empty or unavailable coverage is a blocked data step, not a reason to guess a company or buy credit.
  4. Discover the client's actual tools and invoke get_brief with the selected ticker. A trusted developer agent with REST access can call /v1/brief directly; it does not need to install another client first. This is a metered read under the existing account's allowance or credit.
  5. Check data_status, warnings, attributed theses, and citations, then answer the original question. Complete these checks yourself before reporting success. A configured server, HTTP 200, or preview-only response is not proof of a useful live result.

Choose the connection path

ChatGPT guided beta can check current client availability at https://beliefstate.ai/connect. Claude and previously unknown OAuth clients must wait until that page shows open client onboarding available:

  • Name: BeliefState
  • Remote MCP URL: https://beliefstate.ai/mcp
  • Transport: Streamable HTTP
  • Authentication: OAuth or browser sign-in

The user completes BeliefState sign-in and consent. The AI must never ask for the user's password, session, OAuth token, or API key. The architecture is provider-neutral: admitted compatible providers use the same MCP URL and receive the same read-only tools. Client admission and live compatibility still require separate proof.

Use the API-key path below only for a trusted technical integration that cannot complete OAuth. It is separate from retail chat setup.

Endpoints

For developer API-key integrations, send the key on every REST or MCP request:

Authorization: Bearer <BELIEFSTATE_API_KEY>

Keep the key server-side. Never expose it in browser code, logs, commits, or chat.

For paid REST operations, send a stable bounded X-Request-ID and reuse it only when retrying the same logical request. BeliefState uses that ID for exactly-once reservation and finalization. MCP clients receive equivalent request scoping from the transport session.

1. Configure the MCP client

OAuth-capable chat and agent clients

Use only a pre-registered guided-beta client. Before adding Claude or another client, confirm https://beliefstate.ai/connect shows open client onboarding available. The shared MCP URL is not proof that an unknown OAuth client can register.

Developer clients using API keys

Use these values only in a trusted client that cannot complete OAuth:

Store the key in the client's secret store or process environment. Do not put the key itself in a committed configuration file.

Codex

Check whether a beliefstate server already exists:

codex mcp get beliefstate

If it does not exist, add it:

codex mcp add beliefstate --url https://beliefstate.ai/mcp \
  --bearer-token-env-var BELIEFSTATE_API_KEY

This stores the environment-variable name, not the API key. If an existing beliefstate entry has a different URL or authentication setting, explain the mismatch and ask before replacing it.

Codex CLI, the IDE extension, and the desktop app share MCP configuration on the same computer. The command writes the global configuration at ~/.codex/config.toml. For project-only setup, add this definition to a trusted project's .codex/config.toml instead:

[mcp_servers.beliefstate]
url = "https://beliefstate.ai/mcp"
bearer_token_env_var = "BELIEFSTATE_API_KEY"

Make BELIEFSTATE_API_KEY available to the environment that launches Codex, then start a new Codex session.

Other developer MCP clients

Add https://beliefstate.ai/mcp as a remote Streamable HTTP server. Supply Authorization: Bearer <BELIEFSTATE_API_KEY> through the client's secure header or secret configuration. If the client cannot connect to remote HTTP MCP servers, use the REST examples below.

Claude Code

Run in your project. Claude Code saves the variable name in .mcp.json and reads the key from its environment.

claude mcp add --transport http --scope project beliefstate \
  https://beliefstate.ai/mcp \
  --header 'Authorization: Bearer ${BELIEFSTATE_API_KEY}'

Cursor

Add to .cursor/mcp.json. Keep existing servers in the same mcpServers object.

{
  "mcpServers": {
    "beliefstate": {
      "url": "https://beliefstate.ai/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BELIEFSTATE_API_KEY}"
      }
    }
  }
}

OpenCode

Add to opencode.json. Keep existing servers in the same mcp object.

{
  "mcp": {
    "beliefstate": {
      "type": "remote",
      "url": "https://beliefstate.ai/mcp",
      "enabled": true,
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {env:BELIEFSTATE_API_KEY}"
      }
    }
  }
}

2. Verify access

Confirm that the client lists the beliefstate server. Codex users can run codex mcp list.

Then verify the key and workspace over REST:

curl --fail-with-body \
  --header "Authorization: Bearer $BELIEFSTATE_API_KEY" \
  "https://beliefstate.ai/v1/status"

A successful response includes the authenticated workspace, access state, and current usage. A valid key can exist before the workspace has paid access; intelligence queries require either an active subscription or positive prepaid credit.

Finally, make a real tool call using the person's question:

Verify BeliefState using the company from my question. Check released coverage, discover available tools, and call get_brief with that company's ticker. If this is only a connection test and no company was requested, select a ticker from current coverage and label it as a test. Return the actual ticker, data_status.mode, warnings, citations, and explicit unknowns. Report missing coverage or access without substituting another company or claiming setup succeeded.

Verify the returned ticker, data mode, coverage warnings, and citations before reporting a useful result. Missing coverage is a data gap, not a successful answer to the person's question. A server shown in a client is configured, not yet proven authenticated.

3. Research a ticker over REST

Set BELIEFSTATE_REQUEST_ID to a new UUID for this request; retain it only for retries of the same endpoint and arguments. Call GET https://beliefstate.ai/v1/brief?ticker= with the Authorization header. The brief includes attributed theses, evidence, recent changes, consensus, risks, invalidations, measured market paths and explicit coverage limits.

curl --fail-with-body --get \
  --header "Authorization: Bearer $BELIEFSTATE_API_KEY" \
  --data-urlencode "ticker=${BELIEFSTATE_TICKER:?Set the requested ticker from current coverage}" \
  --header "X-Request-ID: ${BELIEFSTATE_REQUEST_ID:?Set a new UUID for this request; keep it for retries}" \
  "https://beliefstate.ai/v1/brief"

4. Inspect the underlying beliefs

Use a new BELIEFSTATE_REQUEST_ID for this query and for each new page. Call GET https://beliefstate.ai/v1/beliefs?ticker= for compact records. Use changed_since for revised records and person_id for an analyst's recorded history. Follow the returned cursor without adding new filters.

curl --fail-with-body --get \
  --header "Authorization: Bearer $BELIEFSTATE_API_KEY" \
  --data-urlencode "ticker=${BELIEFSTATE_TICKER:?Set the requested ticker from current coverage}" \
  --header "X-Request-ID: ${BELIEFSTATE_REQUEST_ID:?Set a new UUID for this request; keep it for retries}" \
  --data-urlencode "limit=10" \
  "https://beliefstate.ai/v1/beliefs"

Call the same endpoint with belief_id= for full claims, evidence, revisions, condition states, outcomes and provenance. Only as_of may accompany belief_id. This is recorded public belief history, not a private portfolio or calibrated skill ranking.

5. Discover coverage and sources

GET https://beliefstate.ai/v1/tickers is free coverage discovery. GET https://beliefstate.ai/v1/sources accepts q, domain, ticker and source_id filters under the existing workspace API key. Indexed sources do not imply permission to ingest or redistribute their contents.

Prefer a thin server-side adapter that reads BELIEFSTATE_API_KEY at request time, sets the Authorization header, preserves the full response metadata, and surfaces non-2xx response bodies. Do not discard citations, warnings, data_status, as_of, or methodology_versions.

For MCP clients, use get_tickers for coverage, get_brief for ticker research, and get_beliefs for filtered records or full detail by belief_id. Retail clients use OAuth; trusted API-key clients keep their Bearer credential in secure client configuration.

Builder preview mode

Before live corpus coverage is ready, BeliefState builders can enable the fixture-only preview path on a local or isolated preview deployment:

BELIEFSTATE_API_PREVIEW_ENABLED=true
BELIEFSTATE_PREVIEW_API_KEY=<random secret with at least 32 characters>
BELIEFSTATE_API_KEY=<same secret, for the smoke client>
BELIEFSTATE_APP_URL=http://localhost:3000

Use the documentation playground to inspect the preview response. Brief and belief lists return explicit empty preview data; full belief detail requires live access. Run the offline contract tests with bun run check. Never enable this path with a reusable production credential. The live parity smoke operator requires a selected ticker and authorized live access.

Security and lifecycle