Observation & data
Semantic search over what you ingested
Embeds your question and returns the top-k most similar chunks from the content store, each with its source URL, title and similarity score.
etl_query
What it is
The job: Ask a question of the content you ingested, and get back the passages that answer it.
The read half of the ETL pipeline. Your query is embedded with the same model that embedded the chunks, and the top-k nearest are returned with the source url and title attached — so a citation is always available and you are never handed a passage you cannot trace.
Scope to a `collection` to search one corpus rather than everything you have ever ingested. k defaults to 8 and goes to 50.
It returns chunks, not an answer. Composing them into a response is your model’s job — which is the right split, because it keeps the retrieval step cheap, flat-priced and inspectable.
The call
Call it exactly like this.
Copied from the tool's registration and the route handler — not paraphrased.
// MCP tool call — server "twin-browser"
{
"tool": "etl_query",
"arguments": {
"query": "how do I rotate an API key?",
"collection": "example-docs",
"k": 8
}
}curl -X POST https://twin-browser.com/api/v1/etl/query \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "content-type: application/json" \
-d '{"query":"how do I rotate an API key?","collection":"example-docs","k":8}'| Parameter | Type | What it does |
|---|---|---|
| query* | string | The natural-language query to match against stored content. |
| k | number | Number of chunks to return, 1–50. Default 8. |
| collection | string | Collection namespace to scope the search to. |
Returns
{
"matches": [
{ "content": "…", "url": "https://example.com/docs/keys", "title": "API keys",
"similarity": 0.83, "document_id": "…", "chunk_index": 3 }
],
"credits_charged": 1
}What it costs
1 credit
Flat, regardless of k. Retrieval is an embedding plus a vector search — there is no generation step to meter, which is why the price does not move with the size of the result.
See the full rate cardWhich one
When a different tool is the right call.
The honest answer is often the neighbouring tool. These are the trades.
search_libraryBoth are semantic searches and they search entirely different things: etl_query searches content you ingested, search_library searches the shared corpus of compiled automation skills.
search_librarysearchsearch goes out to the live web. etl_query stays inside your own store. Use search to discover, etl_query to recall.
searchQuestions
etl_query, answered.
- Why does it return chunks instead of an answer?
- Because retrieval and generation are different products and pricing them together hides both. You get the passages, their sources and their similarity scores; your own model composes the answer with whatever prompt and citation policy you already use.