One endpoint per library
Every library is an MCP server. An agent holding a token for it reads what the library’s methods built, traceable to the passages it came from. This page is what you need to build on one.
The endpoint
A library lives at https://vcbettauer--ideoscopic-v2-service-api.modal.run/mcp/<library>. It is stateless JSON-RPC 2.0 over HTTP: three methods, each one POST, no session to keep.
| method | what it answers |
|---|---|
| initialize | The server’s name, the protocol version, and its instructions: how this library wants to be read. Read them. |
| tools/list | The tools this token may call, each with a description and an input schema. |
| tools/call | One tool with its arguments. The result’s first content block is JSON, as text. |
Any MCP client that speaks HTTP works as it is. Without one, a plain HTTP call does: every example below is complete.
Connect
# the tools this library offers
curl -s https://vcbettauer--ideoscopic-v2-service-api.modal.run/mcp/<library> \
-H "Authorization: Bearer ido_…" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# call one: start with overview
curl -s https://vcbettauer--ideoscopic-v2-service-api.modal.run/mcp/<library> \
-H "Authorization: Bearer ido_…" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"overview","arguments":{}}}'Replace <library> with the library’s id and the token with one minted for your app. Each library’s own endpoint page carries these snippets filled in.
Tools follow methods
A library runs methods, and its endpoint offers the union of what they produce. So two libraries may offer different tools, and tools/list is the truth for each. Call overview first; it says what the library holds and which tools matter here.
| when the library | it offers |
|---|---|
| keeps a graph (conversation, talks, readings, portraits, essays, papers) | entities, entity, find_entity, moments, moment, at, speakers, speaker, words, texts, segments, questions, rank, and ingest |
| runs a card that reports indicators | method (its questions, track record, limitations, agreement with the library’s own coders), indicators (with intervals, by outlet, group or period), evidence (the documents behind a number) |
| runs a card that follows subjects through time | reports (first and last states, time bins, persistence, transitions, who stays) |
| grows a codebook | codebook (its questions, how the library answers each, its history, and what waits for review) |
| any library | overview, search, similar, documents, document, read, passages, dimensions, values, record, queries, query |
With several cards, tools that read one take method to name it. Ids are stable: an entity is <kind>:<slug>, a moment carries its work and its seconds, a passage its work and ordinal.
Tokens, scopes, budgets
A token is minted by the library’s owner for one app and sent as Authorization: Bearer ido_…. Only its hash is kept. A token without scopes reads. The measure scope adds three paid tools: draft_dimension turns plain words into a typed question, suggest_dimensions proposes some from a sample, and measure asks one of every passage. Their spend is capped per token per UTC day (IDEOSCOPIC_TOKEN_DAILY_USD, $3 unless the engine says otherwise); past the cap the tool answers that the budget is spent, and nothing else changes.
Every paid call is a row in the library’s ledger, scoped to the token that made it. The owner sees it; the engine never bills you twice for the same question on the same passage, since answers are cached per unit and question.
Reading numbers
A card’s numbers are computed when asked, never stored, and each comes with an interval. Read method before reporting one: it carries the card’s calibration (whose coding standard the thresholds follow), its track record against human coders, its cautions per indicator, and its limitations. Give every number with its interval and the caution beside it. A frame that “runs high” says so in its label; repeat that.
The engine’s reader cannot count, compute or compare dates: every count, share, interval and transition you see was made by code over its answers. Do not recompute them from passages; ask the tool that reports them.
Quoting
Every quote the endpoint returns is a slice of a source: a moment’s quote, a passage’s text, a stretch from read. Present them as what they are, in the source’s own words, with the work and the seconds so a person can listen. Never present a paraphrase as anyone’s words. Where a library holds a writer’s essays, a quotation inside a post is marked as one and is not the writer’s claim.
When you answer a person, log it with record: the question, the answer, and the blockquotes in it. The engine checks each quote against the record and keeps what it could verify, so an owner can see what their library was asked and how faithfully it was quoted.
Live sessions and the log
ingest takes a session an app recorded: a document and its segments, each with text, seconds and, where known, a speaker. With speakers the work is cut into turns; without, into paragraphs. The library’s methods then run over it like any other arrival, and its moments join the graph. queries and query read the log record writes.
Public libraries
Each is an endpoint now. Open one for its tools, its instructions, a playground, and the snippets filled in.