Connect
The server URL is:Settings → Connectors has this URL along with copy-paste configuration for Claude, Cursor, and VS Code. Use that page if you would rather not hand-write the config.
Authorisation is OAuth 2.1 with PKCE, so a client never holds your password and you can withdraw its access at any time from Settings → Connectors. If a client cannot do OAuth, it can send a Valendata API key instead (
Authorization: Bearer vd_sk_…). The key brings its own scopes: a key with only skills:read can list and describe skills but not run them. Step-by-step setup for Claude, ChatGPT, Meta Muse, and Cursor is in Connect your AI assistant.https://api.valendata.com/mcp. Use /mcp/sse only for clients that support SSE alone. Both serve the same tools.
Permissions
You grant scopes at the consent screen, and each tool checks the one it needs. Grant only what the assistant actually has to do.
The two
invoke scopes are the ones that cost money. Everything they run is billed to your account exactly as if you had pressed Run yourself.
Tools
Workflows
no arguments
Your published workflows, with the id each one is invoked by. Needs
workflows:read.workflow_id, inputs?
Starts a workflow and returns a
run_id straight away rather than waiting. A workflow can take anywhere from seconds to minutes, so the assistant polls get_run_status for the outcome. Needs workflows:invoke.run_id
Status, per-step output, errors and timings for one run. Needs
workflows:read.limit?
The most recent runs across all your workflows, newest first. Defaults to 10, maximum 50. Needs
workflows:read.Skills
no arguments
Your active skills, public and private, with the id each one is run by. Needs
skills:read.skill_id, params?, max_results?
Runs a skill and returns the extracted rows directly. Pass the skill’s inputs as key/value pairs in
params. max_results is 0–500 (0 returns the whole list); leave it out to use the skill’s saved default. Needs skills:invoke.the skill's own inputs, max_results?, version?
One tool per skill you own or that is shared into your workspace, with the skill’s typed input and output schema and a short track record in its description. Prefer these over
invoke_skill. Listing them needs skills:read; calling them needs skills:invoke.task, start_url, name?, inputs?, output_fields?, idempotency_key?
Records the task in a cloud browser and publishes it as a private skill. Returns a
creation_id at once. Needs skills:invoke and spends credits.creation_id
Status of a
create_skill request: queued, recording, validating, ready, or failed. Needs skills:invoke.skill, mode?, feedback, fields?, example_input?, idempotency_key?
Changes one of your skills.
mode is fix (default: a plain-English hint about where missing data is, “the phone is on the details page — click the place name…”), add_fields (capture new fields you describe, “also capture the star rating and review count”), or relearn_details (rebuild how it opens each result, when the site changed; feedback optional). A cloud browser relearns it and a short check run tests the new version; it goes live only if it is better, otherwise it is kept as a candidate. Returns an improvement_id at once. Owner or workspace editor only. Needs skills:invoke and spends credits.improvement_id
Status of an
improve_skill request: queued, working, validating, done, or failed, with its mode, result, each target field’s rows before → after, and any added, merged, or unclear fields in details. Needs skills:invoke.Knowledge base
tags?
Facts from your knowledge base, optionally filtered by tag. Needs
knowledge:read.key, value, tags?
Saves or updates one fact under
key. value is any JSON object. Needs knowledge:write.Resources
Each published workflow is also exposed as an MCP resource, so a client can read its most recent results without running anything:workflows:read.
A typical exchange
Asking Claude for fresh data from a workflow you already built usually goes like this:1
It finds the workflow
list_workflows returns your published workflows and their ids.2
It starts a run
invoke_workflow returns a run_id immediately. Credits are consumed at this point.3
It waits for the result
get_run_status is polled until the run reaches a terminal status, then the rows come back as JSON.latest resource skips the run and the cost entirely.

