Last updated

// 00 — MCP references

MCP references

wspc exposes its agent surface — todo, calendar, email, projects, org — through a single remote MCP server at https://mcp.wspc.ai/mcp. Any host that speaks MCP (Claude Desktop, Hermes, Cursor, a custom orchestrator) can register the URL, complete the OAuth handshake once, and then read and write the same workspace a human would through the web console.

This page is a scanning surface: which tools exist, what each does in one line, what a typical agent call looks like. The live tools/list response is the authoritative schema — fetch it any time the prose here disagrees.


// 01 — Connection

Connection

Point your MCP host at the server below. Step-by-step setup instructions for each client are in QUICKSTART.

FieldValue
Namewspc
URLhttps://mcp.wspc.ai/mcp
TransportStreamable HTTP (over HTTPS)
AuthOAuth 2.1 Remote Flow

The server advertises tools capabilities only. List tools with the standard tools/list request once the host has a valid bearer token.


// 02 — Authentication

Authentication

Every MCP request carries Authorization: Bearer <token>. Tokens come from the OAuth 2.1 remote flow — dynamic client registration, browser-driven authorization, and an email magic code for proof of identity. The MCP host runs the dance on first connect and again whenever the access token expires.

When a request arrives without a token, or with one the server cannot verify, the response is 401 Unauthorized with a WWW-Authenticate header pointing at https://mcp.wspc.ai/.well-known/oauth-protected-resource. MCP hosts that support OAuth discovery use that URL to relaunch the flow automatically.

The single issued scope is wspc:full — root-level access for the authenticated user. Finer-grained scopes are not available yet.


// 03 — Tools

Tools

Seventy-four tools across seven domains. Each one accepts a JSON object input and returns either a structured result or an isError payload with a stable error code. The summaries below are intentionally short — fetch tools/list for full input schemas, required fields, and the exact error codes each tool can return.

Todo

Tasks with hierarchy, status, due dates, optimistic locking, and project-scoped types with custom fields.

ToolSummary
todo_getGet one todo by id.
todo_listList todos. Filter by status, due window, project, parent, user.
todo_createCreate a todo. Parent, due date, status, type, custom fields, optional idempotency_key for safe retries.
todo_updateUpdate a todo. Partial; optional expected_version optimistic lock.
todo_deleteSoft-delete a todo. Optional cascade to descendants.
todo_restoreRestore a soft-deleted todo. Optional cascade.
todo_type_createCreate a todo type with optional custom-field schema.
todo_type_listList todo types in a project.
todo_type_getGet one type with its schema and version.
todo_type_updateUpdate a type’s label, hidden core fields, or custom-field schema.
todo_type_deleteSoft-delete a type. The current default type cannot be deleted.
todo_type_restoreRestore a soft-deleted type.
todo_rule_createCreate a recurring todo rule from an RFC 5545 RRULE. Optional type_id; omit to adopt the project’s default type. The type’s custom-field defaults are copied onto every instance; a required field with no default fails with MISSING_REQUIRED_FIELD.
todo_rule_getGet one recurrence rule with its template todo snapshot (type_id + custom fields) and the count of materialized instances.
todo_rule_listList active recurring rules. Each item includes type_id (derived from the rule’s template).
todo_rule_deleteDelete a recurrence rule. Stops future materialization and soft-deletes the template; already-materialized instances are kept. Optional expected_version optimistic lock. Destructive.
todo_comment_createAdd a comment to a todo. Fields: todo_id, content (max 10 000 chars). Author is the authenticated user.
todo_comment_listList comments on a todo. Fields: todo_id, optional order (asc | desc, default asc), optional include_deleted.
todo_comment_updateEdit a comment’s content. Fields: id, content.
todo_comment_deleteSoft-delete a comment. Fields: id. No restore path.

Calendar

Events with attendees, ISO 8601 datetimes, RFC 5545 iCalendar export, and optimistic locking.

Todo, project, calendar, and email tool calls participate in the same per-database consistency bookmark contract as their HTTP APIs. MCP clients should store and resend each returned bookmark header independently: x-cb-todo for todo/project tools, x-cb-cal for calendar tools, and x-cb-email for email tools. The bookmark values are opaque transport headers; they are not included in MCP tool output bodies.

ToolSummary
calendar_get_eventGet one calendar event by id.
calendar_list_eventsList events. Filter by date range, free-text query, deleted, past.
calendar_get_event_icsReturn RFC 5545 iCalendar text for one event.
calendar_create_eventCreate an event. ISO 8601 times, attendees, all-day, optional idempotency_key for safe retries.
calendar_update_eventUpdate fields of an event. Optional expected_version optimistic lock.
calendar_delete_eventSoft-delete an event. Recoverable.
calendar_restore_eventRestore a soft-deleted event.

Email

Inbound mail under user-controlled aliases, outbound send with attachments, batch read / unread / delete.

ToolSummary
email_listList received emails. Cursor pagination (default 20, max 100).
email_getGet one email by id. Text body by default; pass include_html for HTML source.
email_mark_readMark one or more emails as read.
email_mark_unreadMark one or more emails as unread.
email_deleteBatch soft-delete emails (move to trash).
email_restoreBatch restore soft-deleted emails.
email_attachment_getDownload an attachment by index. Returns base64; max 5 MB.
email_sendSend a plain-text email from a user alias. Verified custom-domain aliases route through their active provider (Resend for new domains; pete-mail for existing Pete bindings). New, reply, or re-attach inbound files.

Email aliases

Up to 10 active aliases per account. Alias identifiers are full email addresses under @wspc.app or a fully verified organization custom domain. Custom-domain alias creation returns ALIAS_DOMAIN_NOT_FOUND when the domain is not registered to the caller’s organization and ALIAS_DOMAIN_NOT_READY when sending or receiving verification is incomplete. Deletion stops new mail; history is preserved.

ToolSummary
email_alias_createCreate an alias under @wspc.app or a fully verified organization custom domain. Up to 10 active aliases per account.
email_alias_listList the user’s aliases. Active only by default.
email_alias_deleteSoft-delete an alias. Stops accepting new mail; existing emails preserved.
email_alias_restoreRe-enable a deleted alias. Counts toward the 10-alias limit.

Email domains

Register organization custom domains, manage DNS verification records, and delete unused domains. New domains use Resend for sending and receiving; existing Pete bindings remain on pete-mail. Custom domains can be used for aliases once status, sending_status, and receiving_status are all verified. Inbound delivery is handled by an operator-managed provider webhook; there is no MCP tool for webhook registration. DNS records may include a purpose hint such as identity_verification, dkim, mail_from, receiving_mx, or dmarc so operators know why each record is required.

ToolInputSummary
email_domain_create{ domain }Register a domain and return the DNS records the organization must set.
email_domain_list{}List registered domains for the caller’s organization.
email_domain_get{ domain }Get one registered domain, including cached DNS records and status.
email_domain_verify{ domain }Ask the provider to verify current DNS records and return the result.
email_domain_delete{ domain }Delete a domain when no active aliases use it.

Drive

Organization-scoped file libraries: store, edit, move, version, and search text files and images.

ToolSummary
drive_library_listList drive libraries in the caller’s organization (cursor-paginated).
drive_library_getGet one drive library by id.
drive_library_createCreate a drive library (an org-scoped file container).
drive_library_updateRename a drive library.
drive_library_deleteDelete a drive library. The library must be empty; the server rejects deletion of a non-empty library.
drive_file_listList files in a drive library. Use path_prefix to scope to a folder. Returns paths, sizes, and versions, not contents.
drive_file_readRead a file’s current (or a specific historical) version. Text files return UTF-8 text; images return an image; other binaries return metadata only.
drive_file_writeCreate or overwrite a whole text file. Blind last-write-wins by default; prior versions are retained and restorable.
drive_file_editEdit a text file by replacing old_string with new_string. old_string must match exactly and uniquely; set replace_all to replace every occurrence. Fails (EDIT_NO_MATCH) if the text isn’t found — re-read the file and retry.
drive_file_moveMove or rename a file within a library. Content and version history follow the file; fails with PATH_CONFLICT if the target path is occupied.
drive_file_deleteDelete (tombstone) a file. Version history is retained.
drive_file_historyList the version history of a file, newest first.
drive_file_restoreRestore a previous version of a file as a new current version.
drive_searchFull-text search file contents within a library (text files only). Returns matching paths with snippets; read a file for full content.

Projects

Org-scoped containers for todos. Each project defines a default todo type for new work.

ToolSummary
todo_project_getGet one project by id.
todo_project_listList projects in the caller’s organization.
todo_project_createCreate a project in the caller’s organization.
todo_project_updateUpdate project attributes (name, default todo type).
todo_project_deleteSoft-delete a project.
todo_project_restoreRestore a soft-deleted project.

Org

Organization metadata. In v1 every user belongs to a single personal organization.

ToolSummary
auth_meGet the authenticated user’s own identity (user_id, email, display_name).
auth_org_getGet metadata for the authenticated user’s organization.
auth_org_members_listList organization members (paginated). v1 returns just the caller.
auth_org_renameRename the authenticated user’s organization.
auth_org_invite_createInvite an email to your organization (sends an invite email).
auth_org_invites_listList invites issued by your organization.
auth_org_invite_revokeRevoke a pending invite.
auth_invites_listList invites addressed to your email.
auth_invite_acceptAccept an invite (switches your organization; previous-org data becomes invisible).
auth_invite_rejectReject an invite.
auth_org_member_removeRemove a member from the organization (or leave).

Member removal tool details

  • Tool Name: auth_org_member_remove
  • Description: Remove a member from the authenticated user’s organization, or leave the organization (self-removal).
  • Input Parameters:
    • id (string, required): The ID of the user to be removed (e.g. usr_01KT4FF78A1F9CT5SWN5HK392F).
  • Usage & Safety Warning:
    • Revert Behavior: Removing a member reverts their active organization back to their previous organization (previous_org_id).
    • Self-Removal (Leave): Any user (except the creator of the organization) can remove themselves, which is semantically equivalent to leaving the organization.
    • Creator Protection: The creator of the organization (created_by_user_id) cannot be removed.
    • Revert Constraint: A user cannot be removed if their previous_org_id is null, protecting against “homeless” states.

Guide

ToolSummary
guide_startReturn the guided-tour script; call it when the user asks to start the wspc tour.

// 04 — Examples

Examples

Three sketches of what an agent does when a human asks it something natural. The shape — utterance, tool call, a note — repeats. The tool names and field names track real MCP inputs; the exact JSON the host sends is what tools/list describes.

Schedule a lunch

“Book lunch with Alice tomorrow at 12:30, one hour, at Taipei HQ. Her email is alice@example.com.”

calendar_create_event({
  title:      "Lunch with Alice",
  start:      "2026-05-27T12:30:00+08:00",
  end:        "2026-05-27T13:30:00+08:00",
  location:   "Taipei HQ",
  attendees:  [{ email: "alice@example.com", display_name: "Alice" }],
  idempotency_key: "lunch-alice-20260527-1230"
})

start and end are ISO 8601 datetimes with offset. The agent resolves the user’s “tomorrow” against the local timezone before constructing the call; the server itself only accepts ISO. An iCalendar invite is dispatched to the attendee on creation. For create retries, send a stable idempotency_key; the same key with the same payload returns the existing event, while a changed payload returns IDEMPOTENCY_KEY_REUSED.

Triage the open backlog

“What todos do I still have open this week?”

todo_list({
  status:     ["open", "in_progress"],
  due_after:  "2026-05-26",
  due_before: "2026-06-02"
})

The agent maps “this week” to a half-open [due_after, due_before) window and filters by the two active statuses. Both bounds are date-only ISO strings; due_after is inclusive, due_before is exclusive.

Clear the unread queue

“Mark all my unread emails as read.”

email_list({ unread_only: true })
// → [{ id: "em_abc123", ... }, { id: "em_def456", ... }]

email_mark_read({ ids: ["em_abc123", "em_def456"] })

email_list returns unread items in cursor-paginated batches (default 20, max 100). email_mark_read takes a batch of ids in one call. If the inbox has more than limit unread emails, the agent re-calls email_list with the returned next_cursor until exhausted.

Recurring task with a checklist

“Every morning I do a standup: write notes, then post the summary. Set that up as a daily task.”

todo_rule_create({
  title:    "Daily standup",
  rrule:    "FREQ=DAILY",
  dtstart:  "2026-06-10",
  project_id: "prj_abc"
})
// → { rule: { id: "tdr_xyz" }, template_todo_id: "tod_tmpl", ... }

todo_create({ title: "Write notes",   parent_id: "tod_tmpl", project_id: "prj_abc" })
todo_create({ title: "Post summary",  parent_id: "tod_tmpl", project_id: "prj_abc" })

A rule owns a hidden template todo. To make the same subtasks appear on every occurrence, the agent attaches them to the template — not to one day’s instance. The template id comes back as template_todo_id from todo_rule_create (or as template.id from todo_rule_get). Adding a child under the template re-materializes future occurrences so each daily todo carries the checklist. Subtasks are one level deep; attaching to a specific day’s instance would only affect that day.


// 05 — Reference

Reference

  • Live tools/listPOST https://mcp.wspc.ai/mcp with a tools/list JSON-RPC body. Returns the canonical name, description, and JSON Schema input for every registered tool. Treat the response as the source of truth whenever this page disagrees.
  • HTTP equivalents — every MCP tool here maps to one or more REST endpoints documented in API REFERENCES.
  • CLI equivalents — the same surface from a terminal lives in CLI REFERENCE.
  • Setup walkthrough — Setup steps for each client are in QUICKSTART.

// 06 — Troubleshooting

Troubleshooting

  • 401 Unauthorized on every call — the request carries no bearer token, an expired one, or a token issued for a different resource. The response includes a WWW-Authenticate header pointing at https://mcp.wspc.ai/.well-known/oauth-protected-resource; OAuth-aware hosts use it to relaunch the flow. If your host does not auto-reconnect, remove and re-add the server to redo the handshake.
  • Authorization never completes — the flow finishes in the browser with an email magic code. Make sure pop-ups are allowed for your host and that you can receive mail at the address you entered; enter the code to finish. Tokens expire, so an idle connection eventually re-prompts.
  • 405 Method Not Allowed on GET /mcp — expected. The server is stateless and exposes no server-to-client SSE stream, so it answers GET with 405. Use POST for JSON-RPC; compliant clients do this automatically.
  • A tool returns isError — tools return a structured payload with a stable code (for example VERSION_CONFLICT, INVALID_INPUT, NOT_FOUND) instead of throwing. Read the code to decide how to retry; for VERSION_CONFLICT, re-read the item and retry without a stale expected_version.
  • A tool or field looks different from this page — the live tools/list response is authoritative. Fetch it and trust it over the prose here.

Still stuck? Email contact@wspc.ai.