MCP
Your datasets, callable by Claude.
Every Quorel dataset ships with a native MCP server. Claude — or any MCP-compatible agent — can list, query, filter, clean, and edit your data without you writing a script. Included on every plan.
How it connects
Quorel uses the MCP SSE transport. Your agent connects to a token-scoped SSE endpoint and receives tool definitions it can call in any order.
# SSE endpoint
https://quorel.vercel.app/mcp/{your_mcp_token}/
# Token in URL (recommended for Claude Desktop)
https://quorel.vercel.app/mcp/abc123def456.../
# Token as Bearer header (for programmatic clients)
GET https://quorel.vercel.app/mcp/{token}/
Authorization: Bearer abc123def456...The token is scoped to your account. All nine tools operate on datasets you own — they cannot access other users' private datasets.
Getting a token
Generate your MCP token from the dashboard under Settings → MCP, or via the API below. Each account has one active token at a time. Generating a new one immediately invalidates the old one.
Generate a new MCP token for the authenticated user. If a token already exists, it is replaced.
Auth: Session cookie (dashboard auth)
{ "ok": true, "token": "abc123...", "created_at": "2026-01-01T00:00:00Z" }Revoke the current MCP token. The SSE connection will reject any further requests using the old token.
Auth: Session cookie (dashboard auth)
{ "ok": true }Check whether a token exists and whether it is active.
Auth: Session cookie (dashboard auth)
{ "has_token": true, "token": "abc123...", "is_active": true, "last_used_at": "...", "created_at": "..." }Connecting Claude Desktop
Add the following to your claude_desktop_config.json. Replace the token with the one from your dashboard.
{
"mcpServers": {
"vexaro": {
"url": "https://quorel.vercel.app/mcp/your_mcp_token/"
}
}
}Restart Claude Desktop after saving. The nine Quorel tools will appear in Claude's tool list automatically.
Tools
Nine tools are exposed. All require a valid MCP token. All are scoped to datasets you own.
list_datasets
List all datasets owned by the authenticated user.
get_dataset_schema
Get the field schema of a dataset. Call this before query_dataset to understand what fields are available for filtering and sorting.
Arguments
The dataset ID to inspect.
query_dataset
Query a dataset with filters, keywords, sorting, and pagination. Supports all output formats. Each entity includes a _idx field (0-based position in the version file) for use with get_entity, update_entity, and delete_entity.
Arguments
The dataset ID to query.
active (default), latest, or v1, v2 etc.
Set true to query the alt version instead of the original.
json (default), jsonl, csv, tsv, xml, parquet.
Comma-separated keywords. Searched across all fields at every depth.
or (default) matches any keyword. and requires all.
One or more exact field matches (AND logic). Comma-separated, dot-notation supported. Example: country:Germany or country:Germany,job_type:Remote.
One or more partial field matches (AND logic). Comma-separated, dot-notation supported. Example: title:engineer or title:engineer,location:berlin.
One or more range filters (AND logic). Comma-separated, format: field:op:value. Ops: gt, gte, lt, lte. Works on numbers and dates. Example: salary:gte:50000 or salary:gte:50000,salary:lte:100000.
Comma-separated fields to keep. Dot-notation supported.
Comma-separated fields to remove. Dot-notation supported.
Sort by top-level field. Format: field:asc or field:desc.
Max number of results to return.
Number of results to skip.
Return N randomly sampled results using cryptographically secure shuffling.
Remove duplicate entities.
Comma-separated fields to use as the dedup key. Only meaningful when dedup is true.
Recursively strip null values and empty strings at all depths.
Flatten nested objects and arrays into top-level dot-notation keys.
Include the _source field. Default true.
Return only the count of matching entities, not the entities themselves.
get_entity
Fetch a single entity by its 0-based index (_idx) within a specific dataset version. The _idx is returned by query_dataset and pull_for_edit and is stable for the lifetime of that version file.
Arguments
The dataset ID.
0-based index of the entity as returned by query_dataset or pull_for_edit.
Version to read from: active (default), latest, or v1, v2 etc.
Set true to read from the alt version.
pull_for_edit
Pull the full unfiltered entity list from a dataset version for AI processing. Each entity includes a _idx field (0-based position in the file) for use with get_entity, update_entity, and delete_entity. Use push_alt_version to save processed results back.
Arguments
The dataset ID to pull from.
active (default), latest, or v1, v2 etc.
Set true to pull the existing alt version instead of the original.
push_alt_version
Push AI-processed entities back as the alt version of a dataset version. Always writes to alt — never overwrites the original. The dataset must not be frozen or currently processing. Any _idx fields in the entities array are stripped before saving.
Arguments
The dataset ID to push to.
The version number to attach the alt to.
A JSON array of processed entities to save as the alt version.
append_alt_version
Append a batch of processed entities to an existing alt version. If no alt exists yet, it is created automatically. Use this for batch processing — e.g. process 20 entities at a time and append each batch. Returns the running total after each call.
Arguments
The dataset ID to append to.
The version number the alt belongs to.
A JSON array of processed entities to append.
update_entity
Patch a single entity in the alt version by its 0-based index (_idx). Only works on alt versions — use pull_for_edit with use_alt:true or query_dataset with use_alt:true to get valid _idx values. Performs a shallow merge: provided fields overwrite existing ones, unmentioned fields are preserved.
Arguments
The dataset ID.
The version number the alt belongs to.
0-based index of the entity to update.
JSON object of fields to merge into the entity. Example: {"status":"reviewed","score":9.5}.
delete_entity
Delete one or more entities from the alt version. Supports three modes: single (idx), multiple (indexes array), or range (idx_from + idx_to). Deletions are processed back-to-front so indexes remain stable within the batch. Out-of-range indexes are skipped and reported. Only works on alt versions. WARNING: after deletion all entities after any removed one shift down — do not reuse _idx values from before this call.
Arguments
The dataset ID.
The version number the alt belongs to.
0-based index of a single entity to delete.
JSON array of 0-based indexes to delete. Example: [2, 5, 11]. Takes priority over idx.
Start of an index range to delete (inclusive). Must be used together with idx_to.
End of an index range to delete (inclusive). Must be used together with idx_from.
Recommended workflow
The nine tools form a natural pipeline. You don't have to use all of them — query_dataset alone covers most use cases.
list_datasets
Start by listing your datasets to find the dataset_id you want to work with.
get_dataset_schema
Inspect the schema to understand which fields are available before writing filters or sort expressions.
query_dataset
Query with keywords, filters, range filters, and sorting to get the slice you need. Use count=true first to check how many entities match before fetching them all. Each result includes a _idx for targeted edits.
get_entity / update_entity / delete_entity
Make targeted changes to individual entities in the alt version using the _idx returned by query_dataset or pull_for_edit. update_entity does a shallow merge. delete_entity supports single (idx), multiple (indexes), or range (idx_from + idx_to) deletion — all processed back-to-front to keep indexes stable within the batch. Indices shift after any deletion, so re-query before reusing _idx values.
pull_for_edit
Pull the full unfiltered entity list when you want Claude to clean, deduplicate, enrich, or restructure the entire dataset in one pass.
push_alt_version / append_alt_version
Push the processed entities back as the alt version. Use push_alt_version to replace the alt wholesale, or append_alt_version to build it up in batches. The original is never touched.
Example session
A Claude session that queries a remote jobs dataset, makes targeted edits, then cleans and publishes an alt version.
> list_datasets()
→ 3 datasets found
id=12 remote-jobs 847 entities v14
id=7 yc-companies 412 entities v6
id=3 arxiv-ai-papers 1,204 entities v22
> get_dataset_schema(dataset_id: 12)
→ fields: title, company, salary, stack, location, type, _source
> query_dataset(
dataset_id: 12,
keywords: "React,TypeScript",
keywords_mode: "and",
filter_range: "salary:gte:80000",
sort: "salary:desc",
limit: 10,
drop_field: "_source"
)
→ 10 entities returned, each with _idx
> get_entity(dataset_id: 12, idx: 4)
→ single entity at position 4
> update_entity(
dataset_id: 12,
version: 14,
idx: 4,
fields: "{"status":"reviewed","score":9.2}"
)
→ entity 4 patched in alt
> delete_entity(dataset_id: 12, version: 14, idx: 7)
→ { "deleted_count": 1, "deleted_indexes": [7], "remaining_entities": 846 }
warning: indices have shifted
> delete_entity(
dataset_id: 12,
version: 14,
indexes: "[3, 9, 21]"
)
→ { "deleted_count": 3, "deleted_indexes": [3, 9, 21], "remaining_entities": 843 }
warning: indices have shifted
> delete_entity(
dataset_id: 12,
version: 14,
idx_from: 20,
idx_to: 35
)
→ { "deleted_count": 16, "deleted_indexes": [20,21,...,35], "remaining_entities": 827 }
warning: indices have shifted
> query_dataset(dataset_id: 12, count: true)
→ { "count": 827 }
> pull_for_edit(dataset_id: 12, version: "active")
→ 827 entities pulled
Claude deduplicates on title+company,
fills missing salary fields from context,
removes 12 listings with no stack specified.
Processes in batches of 50 using append_alt_version.
> append_alt_version(
dataset_id: 12,
version: 14,
entities: "[...batch 1 of 50...]"
)
→ { "ok": true, "appended": 50, "total_entities": 50, "was_created": true }
> append_alt_version(
dataset_id: 12,
version: 14,
entities: "[...batch 2 of 50...]"
)
→ { "ok": true, "appended": 50, "total_entities": 100, "was_created": false }
... repeat until done ...
> push_alt_version(
dataset_id: 12,
version: 14,
entities: "[full final array]"
)
→ { "ok": true, "entity_count": 791, "version": 14 }
live at /api/12/remote-jobs/v14/?alt=trueAlt versions and safety
push_alt_version and append_alt_version never touch the original version. They write a separate file and record it as the alt path for that version in the database. Two things will block a push:
Dataset is frozen
Frozen datasets are permanently locked. Clone the dataset first if you want to push an alt.
Dataset is currently processing
If a refresh is in progress, the push is rejected. Wait for the refresh to complete, then retry.
Once pushed, the alt is accessible via the REST API at ?alt=true or /vN/alt/ and is versioned alongside the original.
Understanding _idx
Every entity returned by query_dataset and pull_for_edit includes a _idx field. This is the 0-based position of the entity in the raw version file — it is injected at read time and never stored. Three things to know:
Stable within a version
_idx is stable for the lifetime of a version file. It does not change between queries as long as no delete_entity call has been made.
Shifts after delete_entity
Deleting entities causes all entities after the removed positions to shift down. Re-query before using _idx values again after any deletion.
Stripped on save
_idx is never written to disk. push_alt_version, append_alt_version, and saveAltFile all strip it before persisting.