asqend-mcp
v0.3.1
Published
MCP server for Asqend
Maintainers
Readme
Asqend MCP Server
Expose Asqend capabilities, automation authoring, and automation capability discovery to MCP-compatible clients like Claude Code, Cursor, and Windsurf.
Install
Replace <version> with the exact release you want to pin.
Global install:
npm install -g asqend-mcp@<version>Recommended for MCP hosts:
Use a pinned npx invocation in the MCP host config so the host resolves the exact package version on demand.
Configuration
Set the base URL and API key:
ASQEND_URL(example:https://app.asqend.com)ASQEND_API_KEY(starts withna_...)- Back-compat:
NOTION_AGENT_URL/NOTION_AGENT_API_KEYare also accepted.
- Back-compat:
- Pin the exact package version you have validated and point it at an Asqend backend that already has the corresponding capability routes deployed.
Claude Code
Add to ~/.claude/mcp.json:
{
"mcpServers": {
"asqend": {
"type": "stdio",
"command": "npx",
"args": ["-y", "asqend-mcp@<version>"],
"env": {
"ASQEND_URL": "https://app.asqend.com",
"ASQEND_API_KEY": "na_..."
}
}
}
}Cursor
Add a server entry in your Cursor MCP config (path varies by OS). Example:
{
"mcpServers": {
"asqend": {
"type": "stdio",
"command": "npx",
"args": ["-y", "asqend-mcp@<version>"],
"env": {
"ASQEND_URL": "https://app.asqend.com",
"ASQEND_API_KEY": "na_..."
}
}
}
}Windsurf
Add a server entry in your Windsurf MCP config (path varies by OS) using the same stanza as above.
If you prefer a global install, keep the MCP config pinned by upgrading the installed version explicitly and use "command": "asqend-mcp" in the host config.
Write safety
Write tools automatically include X-NA-Write-Confirm: true to satisfy the API confirmation requirement. If the key has unsafe automation enabled, the header is optional.
Tools
Default ListTools shows the default-visibility tool surface. Advanced tools (visibility: advanced) remain callable through CallTool when you already know the tool name.
Preferred entry points
platform_discover: Call first to see available system templates, deployed systems, collection context, and the recommended order to proceed.systems_template_deploy: Use for most "set up a CRM/ticketing/project system" requests; it deploys a ready system and returns the handles you need next.systems_form_submit: Use to create or upsert data through a deployed system's intake surface instead of writing raw records directly.records_upsert: Use for idempotent data operations when you know the match fields and want create, update, or reuse behavior in one call.systems_queue_list_items: Use after deployment or submission when work is exposed as queue-native operational items.
records_upsert merge strategies
replace_fields: Overwrite matched record fields with theupdatepayload.preserve_existing: Only write fields that are currently null or empty on the matched record.noop_on_match: If a match exists, return it unchanged.
records_lookup_exact
Use match as an array of { field, value } pairs. Every pair must match the same record (AND logic).
{
"collectionId": "contacts",
"match": [
{ "field": "email", "value": "[email protected]" },
{ "field": "workspace_id", "value": "ws_123" }
],
"limit": 1
}Default-Visibility Tools By Domain
Systems
systems_apply_patch: Apply a previously planned patch to a deployed system and return the updated handles and URLs.systems_form_get: Resolve a system intake form by handle and return its runtime metadata, collection binding, and submission shape.systems_get: Get the active runtime, spec, automations, handles, and URLs for one deployed operational system.systems_plan_patch: Preview a safe change plan for an existing deployed system before applying it.systems_portal_get: Resolve a requester, approver, or operator portal surface for a deployed system.systems_queue_claim: Claim one work item from a deployed system queue for the authenticated operator.systems_queue_get: Resolve a deployed system queue and return its runtime metadata, collection binding, and queue counts.systems_queue_get_item: Get one projected work item from a deployed system queue.systems_queue_release: Release a previously claimed work item back into the deployed system queue.systems_queue_start_session: Start a single-item or batch handoff session from a deployed system queue using queue order and selection rules.systems_rollback: Roll back a deployed system to a previous version or undo an applied patch.systems_session_action_execute: Execute the next action for a queue-backed systems work session item without using low-level workflow internals.systems_session_close: Close or abandon an active systems work session and release any remaining soft reservations.systems_session_get: Get the current state, selected items, and available actions for a systems work session.systems_templates_get: Get one operational system template, including its collections, queues, forms, portals, and workflow primitives.systems_templates_list: List operational system templates that can be deployed in one call for immediate human use.systems_update: Update system-owned automation schedules or bounded config without dropping into raw trigger editing.
Records
record_attachments_delete: Delete an attachment from a record.record_attachments_upload: Upload a local file attachment to a record.record_checklist_create: Create a checklist item on a record.record_checklist_delete: Delete a checklist item from a record.record_checklist_update: Update a checklist item on a record.record_comments_create: Create a comment on a record.record_comments_delete: Delete a record comment.record_comments_update: Update a record comment.records_create: Create a record in a collection.records_create_batch: Create multiple records in a collection in one call. Returns per-record success or failure in input order.records_delete: Soft-delete a record in a collection.records_get: Get a single record by id within a collection.records_lookup_exact: Find records by exact field equality without building generic filters. Use it when you know the key fields. Key input: match, an array of {field, value} pairs where every pair must match the same record (AND logic).records_update: Update a record in a collection.
email_archive_thread: Archive a Gmail thread by removing it from Inbox (optionally marking it read).email_attachment_get: Download a single email attachment by messageId + attachmentId. When using raw Gmail message IDs from email_search or email_thread_get, pass gmailAccountId.email_compose: Compose and send a new email (not a reply).email_compose_with_attachment: Compose and send a new email with optional file attachments.email_draft_create: Create a Gmail draft email.email_draft_delete: Delete an existing Gmail draft by draft ID.email_draft_send: Send an existing Gmail draft by draft ID.email_forward: Forward a Gmail message to one or more recipients.email_label_create: Create a Gmail label.email_message_get: Get single email content.email_modify: Modify a Gmail message (labels, archive, mark read/unread, trash). Message-level only.email_reply_send: Send a reply to an email.email_reply_with_attachment: Reply to a Gmail message with optional file attachments.
Calendar
calendar_create_event: Create a calendar event with optional attendees.calendar_create_focus_block: Create a focus block event.calendar_delete_event: Delete/cancel a calendar event.calendar_get_event: Get a single calendar event by id.calendar_move_event: Reschedule an event.calendar_update_event: Update an existing calendar event (patch).
Drive
drive_copy: Copy a Google Drive file, optionally renaming or moving into a folder.drive_create: Create/upload a file in Google Drive.drive_create_folder: Create a Google Drive folder.drive_delete: Delete a Google Drive file.drive_move: Move a Google Drive file to a folder.drive_rename: Rename a Google Drive file.drive_share: Share a Drive file with a user/domain/group/anyone.drive_upload: Upload a binary file to Google Drive from base64 content.
Docs
docs_batch_update: Run a Google Docs batchUpdate request (advanced).docs_create_tab: Create a Google Doc tab.docs_insert_text: Insert text at an index in a specific Google Doc tab.docs_replace_text: Replace text in a Google Doc using replaceAllText (batchUpdate).docs_write_tab: Replace the full text content of a specific Google Doc tab.
Sheets
sheets_add_tab: Add a new tab to a spreadsheet.sheets_append_rows: Append rows to a Google Sheet (values.append).sheets_batch_update: Run spreadsheets.batchUpdate requests (tabs, formatting, filters, conditional formatting, and more).sheets_clear_range: Clear values in a Google Sheet range (values.clear).sheets_create_spreadsheet: Create a new Google Spreadsheet.sheets_format_cells: Apply formatting to a cell range, with optional column widths and row heights.sheets_write_values: Write cell values to a Google Sheet (values.update).
Workflows
workflows_run: Create and optionally execute a workflow run.workflows_templates_create: Create a workflow template. Preferred power-user path for building operational workflows directly. Use action_execute steps for side effects like create_record, update_record, send_notification, send_email, create_task, mark_done, or snooze. Quick start: set stepsJson to a review_artifact step plus an action_execute step, and use companionRoutineId to bind the template to its flow or rule.workflows_templates_delete: Delete a workflow template.workflows_templates_update: Update a workflow template.
Handoff Sessions
handoff_sessions_create: Create a handoff session for a human to read, review, edit, or respond to a bounded batch of items. items must be an array of item objects, source is a queue object, and agentBinding/onResponse/completionPolicy are nested objects. Prefer this over raw flows/systems tools for human-in-the-loop work.handoff_sessions_deliver: Deliver a handoff session to one or more channels without changing the session itself. channels must be an array like ["thread"] or ["in_app","email"]. Returned delivery statuses distinguish sent vs skipped vs failed.handoff_sessions_get: Get the current state, items, and human URL for a handoff session.handoff_sessions_wait_for_events: Long-poll up to timeoutMs for handoff-session events after a cursor and return only new events. If cursor is omitted, returns the current event backlog and a nextCursor. Empty events with wait.status=timed_out means the session is still working but nothing new arrived yet.
Automation
automation_create: Create a structured automation and optionally publish it in one call. Accepts a structured flow or rule draft and persists the draft before applying it.
Batch
batch_execute: Execute up to 20 read-only MCP tool calls in one request and return per-operation results.
AI Runs
ai_runs_add_step: Append an AI run step transactionally.ai_runs_update: Update AI run status/timestamps/error fields.
Fields
fields_create: Create a field definition on an object collection.fields_create_batch: Create multiple field definitions on an object collection in one atomic call. Returns { collectionId, items } with created field IDs in input order.
Objects
objects_create: Create a new object collection, optionally from a system template.objects_execute_build_plan: Preview or execute a validated object build plan. Use dryRun=true to return the validated plan, step count, assumptions, and collection keys without writing anything.objects_seed_system: Create or repair the built-in system collections for the authenticated user.objects_update: Update object collection metadata and archive state.
Projects
project_execution_context: Get bounded project execution context including project summary, key tasks, and recent notes.
Relations
relations_attach: Attach one or more target records to a relation field on a source record.relations_create: Create a relation between two object collections.relations_detach: Detach one or more target records from a relation field on a source record.relations_replace: Replace the target records for a relation field on a source record.
Templates
templates_get: Get the full definition for one installable system template.templates_install: Install or repair one system template for the authenticated user. This operation is idempotent.
Threads
threads_push: Push a proactive message into a specific thread (e.g., daily brief, email triage, social content). Use threadKey for reserved threads (general, email, tasks, daily-brief, social) or custom slugs for user-created threads.
Triggers
triggers_create: Create a custom trigger for an object collection. Supported actionConfig examples: create_record: { collectionId: "target-id", data: { title: "{{record.title}}" } } notify: { channel: "app", message: "New ticket: {{record.title}}" }triggers_delete: Delete a custom trigger.triggers_update: Update a custom trigger. Supported actionConfig examples: create_record: { collectionId: "target-id", data: { title: "{{record.title}}" } } notify: { channel: "app", message: "New ticket: {{record.title}}" }
Troubleshooting
- 401 Unauthorized: Check
ASQEND_API_KEYand scope settings. - 403 Forbidden: Missing scopes or read-only key for a write tool.
- 428 Precondition Required: Write confirmation header missing (handled by this client).
- 426 Upgrade Required: The backend now requires a newer
asqend-mcpversion. Update the pinned@<version>in your MCP config. - 429 Too Many Requests: Rate limit exceeded (check
Retry-After).
Backend Version Policy
For hosted or self-managed backend operators:
ASQEND_MCP_ENFORCE_VERSION_HEADER=trueturns on backend rejection for unsupported MCP client versions.ASQEND_MCP_MINIMUM_VERSION=<version>sets the minimum allowed client version.ASQEND_MCP_RECOMMENDED_VERSION=<version>sets the recommended upgrade target shown in manifest responses.ASQEND_SKIP_COMPAT_CHECK=1skips the package's startup manifest check on the client host. This is an emergency/debug-only bypass and does not override backend-side426enforcement.
Benchmarking
Run the synthetic read-flow benchmark harness:
npm run benchmark:read-flowsUseful flags:
npm run benchmark:read-flows -- --iterations 10
npm run benchmark:read-flows -- --batch-concurrency 8 --jsonThis harness is intentionally synthetic. It is for repeatable serial-vs-batch comparisons, payload sizing, and MCP/app fanout visibility. It is not a production latency claim.
Workflow scopes
Workflow tools require API key scopes:
- Read tools:
workflows:read - Mutating tools (
workflows_templates_create,workflows_templates_update,workflows_templates_delete,workflows_run):workflows:write
Common Recipes
1. Create and publish a flow in one call
Use automation_create when you already know the flow structure:
{
"publish": true,
"draft": {
"mode": "flow",
"title": "Weekly Founder Ops",
"summary": "Review the week day by day.",
"envelope": {
"trigger": {
"kind": "schedule",
"triggerType": "schedule",
"triggerTime": "07:00",
"daysOfWeek": [1, 2, 3, 4, 5],
"timezone": "America/Denver"
},
"delivery": { "channel": "in_app" },
"routing": { "destination": "flow_runner" },
"runtime": { "allowRerun": true },
"publication": { "publish": false }
},
"workflow": {
"templateKey": null,
"steps": [
{
"id": "mon",
"blockType": "openclaw_session",
"config": {
"prompt": "Review Monday and draft a compact markdown summary.",
"displayMode": "editable_draft",
"cardTitle": "Mon Review"
}
}
],
"gates": []
}
}
}2. Execute a workflow and generate cards immediately
Use generateCards: true with workflows_run:
{
"templateId": "template_123",
"executeNow": true,
"generateCards": true,
"triggerSource": "mcp_manual"
}3. Inspect run step outputs
Use workflows_run_steps_get after execution:
{
"runId": "run_123"
}4. Push a flow link into a thread
Use threads_push with automation-style metadata so Chat V2 renders a card + CTA:
{
"threadKey": "general",
"threadTitle": "General",
"content": "Weekly Founder Ops is ready.",
"role": "assistant",
"metadata": {
"automation": {
"plainText": "Weekly Founder Ops is ready.",
"previewCard": {
"kind": "existing_flow_recommendation",
"flowId": "flow_123",
"title": "Weekly Founder Ops",
"badges": ["Flow", "Ready"],
"workflowSummary": ["5 cards", "OpenClaw-backed", "Editable drafts"]
},
"deepLink": {
"kind": "flow_run",
"href": "/flows/run/run_123",
"label": "Open Flow"
}
}
}
}5. Choose the right deep link for a flow
Use these canonical href shapes:
- Open a specific run:
/flows/run/<runId>
- Open an existing flow in the builder:
/flows/builder?id=<flowId>
- Open a draft in the builder:
/flows/builder?draftId=<draftId>
Use these matching deepLink.kind values:
flow_runexisting_flowflow_builder
Example:
{
"threadKey": "general",
"content": "Your flow draft is ready.",
"role": "assistant",
"metadata": {
"automation": {
"plainText": "Your flow draft is ready.",
"deepLink": {
"kind": "flow_builder",
"href": "/flows/builder?draftId=draft_123",
"label": "Open Draft"
}
}
}
}Asqend Thread / OpenClaw Model Notes
- Asqend chat threads create a stable
sessionKeyfrom:- user id
- thread id
- thread context version
- That
sessionKeyis what gives OpenClaw continuity across messages in the same thread. - Asqend threads do not choose the OpenClaw model themselves.
- The model comes from the OpenClaw agent handling that session, which is typically the
mainagent for Asqend thread chat. - Flow
openclaw_sessionsteps use workflow-run thread binding and also route through OpenClaw session keys.
Release
See RELEASING.md for the MCP package release checklist.
