{
  "schemaVersion": "1.0",
  "item": {
    "slug": "fast-io",
    "name": "Fast.io",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/dbalve/fast-io",
    "canonicalUrl": "https://clawhub.ai/dbalve/fast-io",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/fast-io",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=fast-io",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "references/REFERENCE.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/fast-io"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/fast-io",
    "agentPageUrl": "https://openagent3.xyz/skills/fast-io/agent",
    "manifestUrl": "https://openagent3.xyz/skills/fast-io/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/fast-io/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Fast.io MCP Server -- AI Agent Guide",
        "body": "Version: 1.123\nLast Updated: 2026-03-16\n\nThe definitive guide for AI agents using the Fast.io MCP server. Covers why and how to use the platform: product capabilities, the free agent plan, authentication, core concepts (workspaces, shares, intelligence, previews, comments, URL import, metadata, workflow, ownership transfer), 12 end-to-end workflows, interactive MCP App widgets, and all 19 consolidated tools with action-based routing.\n\nVersioned guide. This guide is versioned and updated with each server release. The version number at the top of this document tracks tool parameters, ID formats, and API behavior changes. If you encounter unexpected errors, the guide version may have changed since you last read it.\n\nPlatform reference. For a comprehensive overview of Fast.io's capabilities, the agent plan, key workflows, and upgrade paths, see references/REFERENCE.md."
      },
      {
        "title": "1. Overview",
        "body": "Workspaces for Agentic Teams. Collaborate, share, and query with AI -- all through one API, free.\n\nFast.io provides workspaces for agentic teams -- where agents collaborate with other agents and with humans. Upload outputs, create branded shares, ask questions about documents using built-in AI, and hand everything off to a human when the job is done. No infrastructure to manage, no subscriptions to set up, no credit card required."
      },
      {
        "title": "The Problem Fast.io Solves",
        "body": "Agentic teams -- groups of agents working together and with humans -- need a shared place to work. Today, agents cobble together S3 buckets, presigned URLs, email attachments, and custom download pages. Every agent reinvents collaboration, and there is no shared workspace where agents and humans can see the same files, track activity, and hand off work.\n\nWhen agents need to understand documents -- not just store them -- they have to download files, parse dozens of formats, build search indexes, and manage their own RAG pipeline. That is a lot of infrastructure for what should be a simple question: \"What does this document say?\"\n\nProblemFast.io SolutionNo shared workspace for agentic teamsWorkspaces where agents and humans collaborate with file preview, versioning, and AIAgent-to-agent coordination lacks structureShared workspaces with activity feeds, comments, and real-time sync across team membersSharing outputs with humans is awkwardPurpose-built shares (Send, Receive, Exchange) with link sharing, passwords, expirationCollecting files from humans is harderReceive shares let humans upload directly to your workspace -- no email attachmentsUnderstanding document contentsBuilt-in AI reads, summarizes, and answers questions about your filesBuilding a RAG pipeline from scratchEnable intelligence on a workspace and documents are automatically indexed, summarized, and queryableFinding the right file in a large collectionSemantic search finds documents by meaning, not just filenameHanding a project off to a humanOne-click ownership transfer -- human gets the org, agent keeps admin accessTracking what happenedFull audit trail with AI-powered activity summariesCostFree. 50 GB storage, 5,000 monthly credits, no credit card"
      },
      {
        "title": "MCP Server",
        "body": "This MCP server exposes 19 consolidated tools that cover the full Fast.io REST API surface. Every authenticated API endpoint has a corresponding tool action, and the server handles session management automatically.\n\nOnce a user authenticates, the auth token is stored in the server session and automatically attached to all subsequent API calls. There is no need to pass tokens between tool invocations."
      },
      {
        "title": "Server Endpoints",
        "body": "Production: mcp.fast.io\nDevelopment: mcp.fastdev1.com\n\nTwo transports are available on each:\n\nStreamable HTTP at /mcp -- the preferred transport for new integrations.\nSSE at /sse -- a legacy transport maintained for backward compatibility."
      },
      {
        "title": "MCP Resources",
        "body": "The server exposes static MCP resources, widget resources, and file download resource templates. Clients can read them via resources/list and resources/read:\n\nURINameDescriptionMIME Typeskill://guideskill-guideFull agent guide (this document) with all 19 tools, workflows, and platform documentationtext/markdownsession://statussession-statusCurrent authentication state: authenticated boolean, user_id, user_email, token_expires_at (Unix epoch), token_expires_at_iso (ISO 8601), scopes (raw scope string or null), scopes_detail (array of hydrated scope objects with entity names/domains/parents, or null), agent_name (string or null)application/jsonwidget://*Widget HTMLInteractive HTML5 widgets (6 total) -- use the apps tool to discover and launchtext/html\n\nFile download resource templates -- read file content directly through MCP without needing external HTTP access:\n\nURI TemplateNameAuthDynamic ListingDescriptiondownload://workspace/{workspace_id}/{node_id}download-workspace-fileSession tokenYesDownload a file from a workspacedownload://share/{share_id}/{node_id}download-share-fileSession tokenYesDownload a file from a sharedownload://quickshare/{quickshare_id}download-quickshare-fileNone (public)NoDownload a quickshare file\n\nFiles up to 50 MB are returned inline as base64-encoded blob content. Larger files return a text fallback with a URL to the HTTP pass-through endpoint (see below). The download tool responses include a resource_uri field with the appropriate URI for each file.\n\nDynamic resource listing: When authenticated, workspace and share file resources are dynamically listed via resources/list. MCP clients (such as Claude Desktop's @ mention picker) can discover available files without any tool calls. Up to 10 workspaces and 10 shares are enumerated, with up to 25 most recently updated root-level files from each. Resources appear as \"WorkspaceName / filename.ext\" or \"ShareTitle / filename.ext\". Results are cached for 1 minute per session. Only root-level files are listed -- subdirectories are not recursively enumerated. Use the storage tool with action list to browse deeper. The quickshare template remains template-only and is not dynamically enumerable."
      },
      {
        "title": "MCP Prompts",
        "body": "The server registers MCP prompts that appear in the client's \"Add From\" / \"+\" menu as user-clickable app launchers. These are primarily for desktop MCP clients (e.g., Claude Desktop); code-mode clients (Claude Code, Cursor) do not surface prompts.\n\nPrompt NameDescriptionApp: Choose Workspace or OrgLaunch the Workspace Picker to browse orgs, select workspaces, and manage sharesApp: Pick a FileLaunch the File Picker with built-in workspace navigator for browsing, searching, and selecting filesApp: Open WorkflowLaunch the Workflow Manager (auto-selects workspace if only one, otherwise opens Workspace Picker first)App: Upload FilesLaunch the Uploader to upload files with drag-and-drop, progress tracking, and text file creationApp: Available AppsList all available MCP App widgets with descriptions and launch instructions"
      },
      {
        "title": "HTTP File Pass-Through",
        "body": "For files larger than 50 MB or when raw binary streaming is needed, the server provides an HTTP pass-through endpoint that streams file content directly from the API:\n\nEndpointAuthDescriptionGET /file/workspace/{workspace_id}/{node_id}Mcp-Session-Id headerStream a workspace fileGET /file/share/{share_id}/{node_id}Mcp-Session-Id headerStream a share fileGET /file/quickshare/{quickshare_id}None (public)Stream a quickshare file\n\nThe response includes proper Content-Type, Content-Length, and Content-Disposition headers from the upstream API. Errors are returned as HTML pages. The Mcp-Session-Id header is the same session identifier used for MCP protocol communication."
      },
      {
        "title": "Workflow Overview",
        "body": "The server includes workflow features for project tracking: tasks (structured work items with priorities and assignees), worklogs (append-only activity logs), approvals (formal sign-off requests), and todos (simple checklists). Enable workflow on a workspace with workspace action enable-workflow before using these tools. See the Full Agent Workflow recipe in section 6 for the complete pattern.\n\nBest practice (IMPORTANT): After state-changing actions (uploading files, creating shares, changing task status, member changes, file moves/deletes), append a worklog entry describing what you did and why. Without worklog entries, agent work is invisible to humans reviewing the workspace. For multiple related actions (e.g., uploading several files), you may log once after the batch completes rather than after each individual action. Worklog entries are append-only and permanent."
      },
      {
        "title": "Additional References",
        "body": "Agent guide (this file): /skill.md on the MCP server -- tool documentation, workflows, and constraints.\nREST API reference: https://api.fast.io/llms.txt -- endpoint documentation for the underlying Fast.io API.\nPlatform guide: references/REFERENCE.md -- capabilities, agent plan details, key workflows, and upgrade paths."
      },
      {
        "title": "2. Authentication (Critical First Step)",
        "body": "Authentication is required before calling any tool except these unauthenticated tools:\n\nauth with actions: signin, signup, set-api-key, pkce-login, email-check, password-reset-request, password-reset\ndownload with action: quickshare-details"
      },
      {
        "title": "Choosing the Right Approach",
        "body": "There are three ways to use Fast.io as an agent, depending on whether you are operating autonomously or assisting an existing human user.\n\nOption 1: Autonomous Agent -- Create an Agent Account\n\nIf you are operating independently (storing files, running workflows, building workspaces for users), create your own agent account with auth action signup. Agent accounts get the free agent plan (50 GB, 5,000 monthly credits) and can transfer orgs to humans when ready. This is the recommended path for autonomous agents. See Agent Account Creation below for steps.\n\nOption 2: Assisting a Human -- Use Their API Key\n\nIf a human already has a Fast.io account and wants your help managing their files, workspaces, or shares, they can create an API key for you to use. No separate agent account is needed -- you operate as the human user. The human creates a key at Settings -> Devices & Agents -> API Keys (direct link: https://go.fast.io/settings/api-keys). Call auth with action set-api-key and the key to authenticate -- the key is validated and stored in the session automatically. API keys work as Bearer tokens and by default have the same permissions as the account owner. Keys can optionally be scoped to specific organizations, workspaces, or shares (using the same scope system as OAuth tokens), tagged with an agent_name for tracking, and given an expiration date. Unscoped keys do not expire unless revoked. Agents can also manage API keys programmatically with auth actions api-key-create, api-key-update, api-key-list, api-key-get, and api-key-delete.\n\nOption 3: Agent Account Invited to a Human's Org\n\nIf you want your own agent identity but need to work within a human's existing organization, create an agent account with auth action signup, then have the human invite you to their org with member action add (entity_type org) or to a workspace with member action add (entity_type workspace). Alternatively the human can invite via the UI: Settings -> Your Organization -> Manage People. This gives you access to their workspaces and shares while keeping your own account separate. After accepting invitations with user action accept-all-invitations, use auth action signin to authenticate normally. Note: If the human only invites you to a workspace (not the org), the org will appear as external -- see Internal vs External Orgs in the Organizations section.\n\nOption 4: Browser Login (PKCE)\n\nIf you prefer not to send a password through the agent, use browser-based PKCE login. Call auth action pkce-login (optionally with an email hint) to get a login URL. The user opens the URL in a browser, signs in (email/password or SSO like Google/Microsoft), and approves access. The browser displays an authorization code which the user copies back to the agent. Call auth action pkce-complete with the code to finish signing in. This is the most secure option -- no credentials pass through the agent.\n\nPKCE login supports optional scoped access via the scope_type parameter. By default, scope_type is \"user\" (full account access). Other scope types restrict the token to specific entity types:\n\nscope_typeAccess granteduserFull account access (default)orgUser selects specific organizationsworkspaceUser selects specific workspacesall_orgsAll organizations the user belongs toall_workspacesAll workspaces the user has access toall_sharesAll shares the user is a member of (share:*:<mode>)\n\nScope inheritance: Broader scopes include access to child entities automatically:\n\nall_orgs includes all orgs + all workspaces + all shares within those orgs\nall_workspaces includes all workspaces + all shares within those workspaces\norg scope on a specific org includes access to all workspaces and shares within that org\nworkspace scope on a specific workspace includes access to shares within that workspace\nall_shares grants direct access to all shares the user has membership in, bypassing workspace/org inheritance\n\nThe agent_name parameter controls what the user sees on the approval screen -- the screen displays \"[agent_name] will act on your behalf\". If omitted, only the client name is shown. Use a descriptive name so the user knows which agent is requesting access.\n\nApproval flow by scope_type:\n\nuser (default): Full account access. The user sees a simple approve/decline prompt with no entity picker.\norg, workspace: The user sees an entity selection screen listing their accessible entities with checkboxes, plus a read-only / read-write toggle. The user picks which entities to grant, then approves or declines.\nall_orgs, all_workspaces, all_shares: The user sees a summary of the wildcard access being requested (no entity picker), then approves or declines.\n\nThe MCP server defaults to scope_type=\"user\" for backward compatibility.\n\nScenarioRecommended ApproachOperating autonomously, storing files, building for usersCreate an agent account with your own org (Option 1)Helping a human manage their existing accountAsk the human to create an API key for you (Option 2)Working within a human's org with your own identityCreate an agent account, have the human invite you (Option 3)Building something to hand off to a humanCreate an agent account, build it, then transfer the org (Option 1)Signing in without sending a password through the agentBrowser-based PKCE login (Option 4)\n\nCredit limits by account type: Agent accounts (Options 1, 3) can transfer orgs to humans when credits run out -- see Ownership Transfer in section 3. Human accounts (Option 2) cannot use the transfer/claim API; direct the human to upgrade their plan at https://go.fast.io/settings/billing or via org action billing-create."
      },
      {
        "title": "Standard Sign-In Flow",
        "body": "Call auth with action signin, email and password.\nThe server returns a JWT auth_token and stores it in the session automatically.\nAll subsequent tool calls use this token without any manual passing."
      },
      {
        "title": "Agent Account Creation",
        "body": "When creating a new account (Options 1 and 3 above), agents MUST use auth action signup which automatically registers with agent=true. Never sign up as a human account. Agent accounts provide:\n\naccount_type set to \"agent\"\nFree agent plan assigned automatically\nTransfer/claim workflow enabled for handing orgs off to humans\n\nSteps:\n\nOptionally call auth action email-check with the desired email to verify it is available for registration before attempting signup.\nCall auth action signup with first_name, last_name, email, and password. The agent=true flag is sent automatically by the MCP server.\nThe account is created and a session is established automatically -- the agent is signed in immediately.\nVerify your email (required before using most endpoints): Call auth action email-verify with email to send a verification code, then call auth action email-verify again with email and email_token to validate the code.\nNo credit card is required. No trial period. No expiration. The account persists indefinitely."
      },
      {
        "title": "Two-Factor Authentication Flow",
        "body": "Call auth action signin with email and password.\nIf the response includes two_factor_required: true, the returned token has limited scope.\nCall auth action 2fa-verify with the 2FA code (TOTP, SMS, or WhatsApp).\nThe server replaces the limited-scope token with a full-scope token automatically."
      },
      {
        "title": "Inline 2FA for Sensitive Operations",
        "body": "Some API endpoints require per-request 2FA verification when the account has 2FA enabled. These operations require a valid 2FA token parameter (6-digit TOTP or SMS/call/WhatsApp code) in addition to normal authentication:\n\napi-key-create — creating a new API key\napi-key-delete — revoking an API key\n\nIf the account does not have 2FA enabled, these operations work normally without a token. If 2FA is enabled and the token is missing or invalid, the request fails.\n\nWorkflow:\n\nCheck 2FA status: auth action 2fa-status — if state is \"enabled\", inline 2FA is required.\nPrompt the user for a TOTP code from their authenticator app, or send a code via auth action 2fa-send.\nPass the code as the token parameter to api-key-create or api-key-delete.\n\nTip: API key authentication (auth action set-api-key) bypasses inline 2FA checks entirely. If the agent is already authenticated via API key, no token is needed for these operations."
      },
      {
        "title": "Browser Login (PKCE) Flow",
        "body": "Call auth action pkce-login (optionally with email to pre-fill the sign-in form, scope_type to request scoped access, and agent_name to identify the agent).\nThe tool returns a login_url -- present it to the user to open in a browser.\nThe user signs in (email/password or SSO).\nThe user sees the approval screen showing the agent_name (or client name if not provided). Depending on scope_type: for user they simply approve; for org/workspace they select specific entities and read-only/read-write access; for all_orgs/all_workspaces/all_shares they review the wildcard access summary.\nThe user clicks Approve. The browser displays an authorization code. The user copies it.\nCall auth action pkce-complete with the code to exchange it for an access token.\nThe session is established automatically -- all subsequent tool calls are authenticated. If scoped access was granted, scopes and agent_name are included in the response and stored in the session."
      },
      {
        "title": "Checking Session Status",
        "body": "auth action status -- checks the local Durable Object session. No API call is made. Returns authentication state, user ID, email, token expiry, scopes, and agent_name.\nauth action check -- validates the token against the Fast.io API. Returns the user ID if the token is still valid."
      },
      {
        "title": "Session Expiry",
        "body": "JWT tokens last 1 hour. API keys do not expire by default, but can optionally have an expiration set via api-key-create or api-key-update with the key_expires parameter. When a JWT session expires or a time-limited API key expires, tool calls return a clear error indicating that re-authentication is needed. Call auth action signin again to establish a new session. The MCP server does not auto-refresh tokens.\n\nTip: For long-running sessions, use auth action status to check remaining token lifetime before starting a multi-step workflow. If the token is close to expiring, re-authenticate first to avoid mid-workflow interruptions."
      },
      {
        "title": "Signing Out",
        "body": "Call auth action signout to clear the stored session from the Durable Object."
      },
      {
        "title": "Organizations",
        "body": "Organizations are top-level containers that collect workspaces. An organization can represent a company, a business unit, a team, or simply your own personal collection. Every user belongs to one or more organizations. Organizations have:\n\nWorkspaces — the file storage containers that belong to the organization.\nMembers with roles: owner, admin, member, guest, view.\nBilling and subscriptions managed through Stripe integration.\nPlan limits that govern storage, transfer, AI tokens, and member counts.\n\nOrganizations are identified by a 19-digit numeric profile ID or a domain string.\n\nIMPORTANT: When creating orgs, agents MUST use org action create which automatically assigns billing_plan: \"agent\". This ensures the org gets the free agent plan (50 GB, 5,000 credits/month). Do not use any other billing plan for agent-created organizations.\n\nOrg Discovery (IMPORTANT)\n\nTo discover all available orgs, agents must call both actions:\n\norg action list -- returns internal orgs where you are a direct member (member: true)\norg action discover-external -- returns external orgs you access via workspace membership only (member: false)\n\nAn agent that only checks org action list will miss external orgs entirely and won't discover the workspaces it's been invited to. External orgs are the most common pattern when a human invites an agent to help with a specific project -- they add the agent to a workspace but not to the org itself.\n\nInternal vs External Orgs\n\nInternal orgs (member: true) -- orgs you created or were invited to join as a member. You have org-level access: you can see all workspaces (subject to permissions), manage settings if you're an admin, and appear in the org's member list.\n\nExternal orgs (member: false) -- orgs you can access only through workspace membership. You can see the org's name and basic public info, but you cannot manage org settings, see other workspaces, or add members at the org level. Your access is limited to the specific workspaces you were explicitly invited to.\n\nExample: A human invites your agent to their \"Q4 Reports\" workspace. You can upload files, run AI queries, and collaborate in that workspace. But you cannot create new workspaces in their org, view their billing, or access their other workspaces. The org shows up via org action discover-external -- not org action list. If the human later invites you to the org itself, the org moves from external to internal."
      },
      {
        "title": "Workspaces",
        "body": "Workspaces are file storage containers within organizations. Each workspace has:\n\nIts own set of members with roles (owner, admin, member, guest).\nA storage tree of files and folders (storage nodes).\nOptional AI features for RAG-powered chat.\nShares that can be created within the workspace.\nArchive/unarchive lifecycle management.\n50 GB included storage on the free agent plan, with files up to 1 GB per upload.\nFile versioning -- every edit creates a new version, old versions are recoverable.\nFull-text and semantic search -- find files by name or content, and documents by meaning.\n\nWorkspaces are identified by a 19-digit numeric profile ID.\n\nIntelligence: On or Off\n\nWorkspaces have an intelligence toggle that controls whether AI features are active.\n\n⚠️ COST WARNING: Intelligence incurs significant ingestion costs (10 credits per page for every uploaded document). For a workspace with hundreds or thousands of pages, this adds up quickly. Do NOT enable intelligence unless the user specifically needs RAG queries across many documents or AI-powered semantic search. Most workflows (file storage, sharing, collaboration, one-off file analysis) work perfectly without it.\n\nIntelligence OFF (recommended default) -- the workspace is pure file storage. You can still attach files directly to an AI chat conversation (up to 20 files, 200 MB total) and ask questions about them -- no ingestion cost. This is the right choice for most use cases: file storage, sharing, collaboration, project coordination, and analyzing a small number of specific files.\n\nIntelligence ON (only when needed) -- the workspace becomes an AI-powered knowledge base. Every document and code file uploaded is automatically ingested, summarized, and indexed. Only enable this when the user needs one of these two capabilities:\n\nRAG queries across many documents -- scope AI chat to entire folders or the full workspace and ask questions across all indexed content. The AI retrieves relevant passages and answers with citations. This is useful when you have a large volume of documents and need to search across all of them.\nAI-powered semantic search -- find files by meaning, not just keywords. \"Show me contracts with indemnity clauses\" works even if those exact words do not appear in the filename.\n\nIntelligence also enables auto-summarization and automatic metadata extraction, but these alone do not justify the ingestion cost.\n\nComing soon: RAG indexing support for images, video, and audio files. Currently only documents and code are indexed.\n\nDefault behavior: Intelligence defaults to ON for workspaces created via the API by agent accounts. You should explicitly set intelligence to \"false\" when creating workspaces unless the user has asked for RAG or AI search capabilities. Do not enable it speculatively \"just in case\" -- it can always be enabled later, but ingestion costs are incurred immediately and are non-refundable.\n\nAgent use case: Create a workspace per project or client. Keep intelligence OFF for storage and collaboration. Only enable it when users need to query across a large document set. Upload reports, datasets, and deliverables. Invite other agents and human stakeholders. Everything is organized, searchable, and versioned.\n\nFor full details on AI chat types, file context modes, AI state, and how intelligence affects them, see the AI Chat section below."
      },
      {
        "title": "Shares",
        "body": "Shares are purpose-built spaces for exchanging files with people outside your workspace. They can exist within workspaces and have three types:\n\nModeWhat It DoesAgent Use CaseSendRecipients can download filesDeliver reports, exports, generated contentReceiveRecipients can upload filesCollect documents, datasets, user submissionsExchangeBoth upload and downloadCollaborative workflows, review cycles\n\nPortals\n\nA Portal is a Send share created from a workspace folder (storage_mode=workspace_folder). Portals are always Send-only -- recipients can view and download files but cannot upload. The portal displays the live contents of the linked workspace folder, so any changes to the folder are immediately reflected. Portals are ideal for publishing a folder's contents externally (e.g., a client deliverables folder) without duplicating files. To create a portal: use share action create with share_type: \"send\", storage_mode: \"workspace_folder\", and folder_node_id (or create_folder: true).\n\nShare Features\n\nPassword protection -- require a password for link access\nExpiration dates -- shares auto-expire after a set period\nDownload controls -- enable or disable file downloads\nAccess levels -- Members Only, Org Members, Registered Users, or Public (anyone with the link)\nCustom branding -- background images, gradient colors, accent colors, logos\nPost-download messaging -- show custom messages and links after download\nUp to 3 custom links per share for context or calls-to-action\nGuest chat -- let share recipients ask questions in real-time\nAI-powered auto-titling -- shares automatically generate smart titles from their contents\nActivity notifications -- get notified when files are sent or received\nComment controls -- configure who can see and post comments (owners, guests, or both)\n\nTwo Storage Modes\n\nWhen creating a share with share action create, the storage_mode parameter determines how files are stored:\n\nindependent (independent storage, default) -- The share has its own isolated storage. Files are added directly to the share and are independent of any workspace. This creates a self-contained share -- changes to workspace files do not affect the share, and vice versa. Use for final deliverables, compliance packages, archived reports, or any scenario where you want an immutable snapshot.\n\n\nworkspace_folder (workspace-backed) -- The share is backed by a specific folder in a workspace. The share displays the live contents of that folder -- any files added, updated, or removed in the workspace folder are immediately reflected in the share. No file duplication, so no extra storage cost. To create a workspace folder share, pass storage_mode=workspace_folder and folder_node_id={folder_opaque_id} when creating the share. Note: Expiration dates are not allowed on workspace folder shares since the content is live.\n\nBoth modes look the same to share recipients -- a branded share with file preview, download controls, and all share features. The difference is whether the content is a snapshot (independent) or a live view (workspace folder).\n\nResponse fields: API responses include both storage_mode (independent or workspace_folder) and share_category (portal or shared_folder). Use storage_mode when creating shares; share_category is a read-only classification in responses.\n\nShares are identified by a 19-digit numeric profile ID.\n\nAgent use case: Generate a quarterly report, create a Send share with your client's branding, set a 30-day expiration, and share the link. The client sees a professional, branded page with instant file preview -- not a raw download link."
      },
      {
        "title": "Storage Nodes",
        "body": "Files and folders are represented as storage nodes. Each node has an opaque ID (a 30-character alphanumeric string, displayed with hyphens, e.g. f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4). The special value root refers to the root folder of a workspace or share, and trash refers to the trash folder.\n\nKey operations on storage nodes: list, create-folder, move, copy, rename, delete (moves to trash), purge (permanently deletes), restore (recovers from trash), search, add-file (link an upload), and add-link (create a share reference).\n\nNodes have versions. Each file modification creates a new version. Version history can be listed and files can be restored to previous versions.\n\nConflict resolution (REPLACE by default): When a file operation encounters an existing file with the same name in the target folder, the default behavior is to replace (overwrite) the existing file:\n\nUpload (addfile) -- silently overwrites the existing file. The previous content is preserved as a version entry, recoverable via storage action version-list / version-restore.\nMove / Copy -- trashes the existing conflicting file, then completes the operation. The old file is recoverable from trash.\nRestore from trash -- trashes the existing conflicting file, then restores.\nFolder conflicts and type mismatches (file vs folder) still fall back to rename (e.g. folder (2)).\n\nThis means uploading a file with the same name as an existing file will overwrite it, not create a renamed copy like report (2).pdf. If you need multiple files with the same name to coexist, rename them before uploading."
      },
      {
        "title": "Notes",
        "body": "Notes are a storage node type (alongside files and folders) that store markdown content directly on the server. They live in the same folder hierarchy as files, are versioned like any other node, and appear in storage listings with type: \"note\".\n\nCreating and Updating Notes\n\nCreate notes with workspace action create-note, read with workspace action read-note, and update with workspace action update-note.\n\nCreating: Provide workspace_id, parent_id (folder opaque ID or \"root\"), name (must end in .md, max 100 characters), and content (markdown text, max 100 KB).\n\nReading: Provide workspace_id and node_id. Returns the note's markdown content and metadata.\n\nUpdating: Provide workspace_id, node_id, and at least one of name (must end in .md) or content (max 100 KB).\n\nConstraintLimitContent encodingValid UTF-8 (UTF8MB4). Invalid byte sequences and control characters (\\p{C} except \\t, \\n, \\r) are stripped.Content size100 KB maxFilename1-100 characters, must end in .mdMarkdown validationCode blocks and emphasis markers must be balancedRate limit2 per 10s, 5 per 60s\n\nNotes as Long-Term Knowledge Grounding\n\nIn an intelligent workspace, notes are automatically ingested and indexed just like uploaded documents. This makes notes a way to bank knowledge over time -- any facts, context, or decisions stored in notes become grounding material for future AI queries.\n\nWhen an AI chat uses folder scope (or defaults to the entire workspace), notes within that scope are searched alongside files. The AI retrieves relevant passages from notes and cites them in answers.\n\nKey behaviors:\n\nNotes are ingested for RAG when workspace intelligence is enabled\nNotes within a folder scope are included in scoped queries\nNotes with ai_state: ready are searchable via RAG\nNotes can also be attached directly to a chat via files_attach (check ai.attach is true in storage details)\n\nUse cases:\n\nStore project context, decisions, and rationale. Months later, ask \"Why did we choose vendor X?\" and the AI retrieves the note.\nSave research findings in a note. Future AI chats automatically use those findings as grounding.\nCreate reference documents (style guides, naming conventions) that inform all future AI queries in the workspace.\n\nOther Note Operations\n\nNotes support the same storage operations as files and folders: move (via storage action move), copy (storage action copy), delete/trash (storage action delete), restore (storage action restore), version history (storage action version-list), and details (storage action details).\n\nLinking Users to Notes\n\nNote in workspace context (opens workspace with note panel): https://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}\nNote preview (standalone view): https://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}"
      },
      {
        "title": "AI Chat",
        "body": "AI chat lets agents ask questions about files stored in workspaces and shares. Two chat types are available, each with different file context options.\n\nAI chat is read-only. It can read, analyze, search, and answer questions about file contents, but it cannot modify files, change workspace settings, manage members, or access events. Any action beyond reading file content — uploading, deleting, moving files, changing settings, managing shares, reading events — must be done through the MCP tools directly. Do not attempt to use AI chat as a general-purpose tool for workspace management.\n\nTwo Chat Types\n\nchat — Basic AI conversation with no file context from the workspace index. Use for general questions only.\nchat_with_files — AI grounded in your files. Two mutually exclusive modes for providing file context:\n\nFolder/file scope (RAG) — limits the retrieval search space. Requires intelligence enabled; files must be in ready AI state.\nFile attachments — files read directly by the AI. No intelligence required; files must have ai.attach: true in storage details (the file must be a supported type for AI analysis). Max 20 files, 200 MB total.\n\nAuto-promotion: If you create a chat with type=chat but include files_scope, folders_scope, or files_attach, the system automatically promotes the type to chat_with_files. You don't need to worry about setting the type exactly right — the intent is unambiguous when file parameters are present.\n\nBoth types augment answers with web knowledge when relevant.\n\nFile Context: Scope vs Attachments\n\nFor chat_with_files, choose one of these mutually exclusive approaches:\n\nFeatureFolder/File Scope (RAG)File AttachmentsHow it worksLimits RAG search spaceFiles read directly by AIRequires intelligenceYesNoFile readiness requirementai_state: readyai.attach: trueBest forMany files, knowledge retrievalSpecific files, direct analysisMax references100 folder refs (subfolder tree expansion) or 100 file refs20 files / 200 MBDefault (no scope given)Entire workspaceN/A\n\nScope parameters (REQUIRES intelligence — will error if intelligence is off):\n\nfolders_scope — comma-separated nodeId:depth pairs (depth 1-10, max 100 subfolder refs). Defines a search boundary — the RAG backend finds documents within scoped folders automatically. Just pass folder IDs with depth; do not enumerate individual files. A folder with thousands of files and few subfolders works fine.\nfiles_scope — comma-separated nodeId:versionId pairs (max 100). Limits RAG to specific indexed files. nodeId is required; versionId is required in the pair format but will be auto-resolved to the node's current version if left empty (e.g., nodeId: with nothing after the colon). Get versionId from the file's version field in storage action list or details responses.\nIf neither is specified, the default scope is the entire workspace (all indexed documents). This is the recommended default — omit scope parameters unless you specifically need to narrow the search.\n\nAttachment parameter (no intelligence required):\n\nfiles_attach — comma-separated nodeId:versionId pairs (max 20, 200 MB total). nodeId is required; versionId will be auto-resolved to the current version if left empty. Files are read directly, not via RAG. FILES ONLY: passing a folder nodeId returns a 406 error. To include folder contents in AI context, use folders_scope instead (requires intelligence). Only files with ai.attach: true in storage details can be attached — check before using.\n\nDo not list folder contents and pass individual file IDs as files_scope when you mean to search a folder — use folders_scope with the folder's nodeId instead. files_scope is only for targeting specific known file versions.\n\nScope vs attach: files_scope and folders_scope narrow the RAG search boundary and require workspace intelligence to be enabled — they will error on non-intelligent workspaces. files_attach sends files directly to the AI without indexing and works regardless of intelligence setting, but accepts only file nodeIds (not folders).\n\nfiles_scope/folders_scope and files_attach are mutually exclusive — sending both will error.\n\nIntelligence and AI State\n\nThe workspace intelligence toggle (see Workspaces above) controls whether uploaded documents and code files are auto-ingested, summarized, and indexed for RAG. When intelligence is enabled, each file has an ai_state indicating its readiness:\n\nStateMeaningdisabledAI processing disabled for this filependingQueued for processingin_progressCurrently being ingested and indexedreadyComplete — available for folder/file scope queriesfailedProcessing failed\n\nOnly files with ai_state: ready are included in folder/file scope searches. Check file state via storage action details with context_type: \"workspace\".\n\nAttachability — the ai.attach Flag\n\nFile nodes in storage list/details responses include an ai object with three fields:\n\nFieldTypeMeaningai.statestringAI indexing state (disabled, pending, inprogress, ready, failed)ai.attachbooleanWhether the file can be used with files_attachai.summarybooleanWhether the file already has an AI-generated summary\n\nBefore using files_attach, check that ai.attach is true. A file is attachable when its type supports AI analysis (documents, code, images, PDFs, spreadsheets, etc.) or when it already has a summary from prior processing. Files with ai.attach: false (unsupported formats, corrupt files, or files still processing) will be rejected by the API.\n\nThis flag is independent of the workspace intelligence setting — a file can have ai.attach: true even when intelligence is off.\n\nWhen to enable intelligence: You need RAG queries across many documents (scoped to folders or the full workspace) or AI-powered semantic search. Do NOT enable just for auto-summarization or metadata extraction alone -- the ingestion cost (10 credits/page) is significant.\n\nWhen to disable intelligence (recommended default): The workspace is for storage, sharing, collaboration, or you only need to analyze specific files via attachments. This covers most use cases. Saves significant credits. Intelligence can always be enabled later if needed.\n\nEven with intelligence off, chat_with_files with file attachments still works for files with ai.attach: true.\n\nHow to Phrase Questions\n\nWith folder/file scope (RAG): Write questions likely to match content in indexed files. The AI searches the scope, retrieves passages, and cites them.\n\nGood: \"What are the payment terms in the vendor contracts?\"\nGood: \"Summarize the key findings from the Q3 analysis reports\"\nBad: \"Tell me about these files\" — too vague, no specific content to match\nBad: \"What's in this workspace?\" — cannot meaningfully search for \"everything\"\n\nWith file attachments: Be direct — the AI reads the full file content. No retrieval step.\n\n\"Describe this image in detail\"\n\"Extract all dates and amounts from this invoice\"\n\"Convert this CSV data into a summary table\"\n\nPersonality: The personality parameter controls the tone and length of AI responses. Pass it when creating a chat or sending a message:\n\nconcise — short, brief answers\ndetailed — comprehensive answers with context and evidence (default)\n\nUse concise when you need a quick fact, a yes/no answer, or a brief summary. Use detailed (or omit the parameter) when you need thorough analysis with supporting evidence and citations. The personality can also be overridden per follow-up message.\n\nControlling verbosity in questions: You can also guide verbosity through how you phrase the question itself:\n\n\"In one sentence, what is the main conclusion of this report?\"\n\"List only the file names that mention GDPR compliance, no explanations\"\n\"Give me a brief summary — 2-3 bullet points max\"\n\nCombining personality: \"concise\" with a direct question produces the shortest answers and uses the fewest AI credits.\n\nChat Parameters\n\nCreate a chat with ai action chat-create (with context_type: \"workspace\") or ai action chat-create (with context_type: \"share\"):\n\ntype (required) — chat or chat_with_files\nquery_text (required for workspace, optional for share) — initial message, 2-12,768 characters\npersonality (optional) — concise or detailed (default: detailed)\nprivacy (optional) — private or public (default: public)\nfiles_scope (optional) — nodeId:versionId,... (max 100, requires chat_with_files + intelligence). nodeId required; versionId auto-resolved if empty. Omit to search all indexed documents (recommended default).\nfolders_scope (optional) — nodeId:depth,... (depth 1-10, max 100 subfolder refs, requires chat_with_files + intelligence). Folder scope = search boundary, not file enumeration. Omit to search all indexed documents (recommended default).\nfiles_attach (optional) — nodeId:versionId,... (max 20 / 200 MB, nodeId required, versionId auto-resolved if empty, mutually exclusive with scope params)\n\nFollow-up Messages\n\nSend follow-ups with ai action message-send (with context_type: \"workspace\" or \"share\"). The chat type is inherited from the parent chat. Each follow-up can update the scope, attachment, and personality parameters.\n\nWaiting for AI Responses\n\nAfter creating a chat or sending a message, the AI response is asynchronous. Message states progress: ready → in_progress → complete (or errored).\n\nRecommended: Call ai action message-read (with context_type: \"workspace\" or \"share\") with the returned message_id. The tool polls automatically (up to 15 attempts, 2-second intervals, ~30 seconds). If the response is still processing after that window, use event action activity-poll with the workspace/share ID instead of calling the read action in a loop — see Activity Polling in section 7.\n\nResponse Citations\n\nCompleted AI responses include citations pointing to source files:\n\nnodeId — storage node opaque ID\nversionId — file version opaque ID\nentries[].page — page number\nentries[].snippet — text excerpt\nentries[].timestamp — audio/video timestamp\n\nLinking Users to AI Chats\n\nAppend ?chat={chat_opaque_id} to the workspace storage URL:\n\nhttps://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}\n\nShare AI Chats\n\nShares support AI chat with identical capabilities. All workspace AI endpoints have share equivalents accessible via ai actions with context_type: \"share\"."
      },
      {
        "title": "AI Share / Export",
        "body": "Generate temporary markdown-formatted download URLs for files that can be pasted into external AI tools (ChatGPT, Claude, etc.). Use ai action share-generate (with context_type: \"workspace\" or \"share\"). URLs expire after 5 minutes. Limits: 25 files maximum, 50 MB per file, 100 MB total."
      },
      {
        "title": "Profile IDs",
        "body": "Organizations, workspaces, and shares are all identified by 19-digit numeric profile IDs. These appear throughout the tool parameters as workspace_id, share_id, org_id, profile_id, and member_id.\n\nMost endpoints also accept custom names as identifiers:\n\nProfile TypeNumeric IDCustom NameWorkspace19-digit IDFolder name (e.g., my-project)Share19-digit IDURL name (e.g., q4-financials)Organization19-digit IDDomain name (e.g., acme)User19-digit IDEmail address (e.g., user@example.com)"
      },
      {
        "title": "QuickShares",
        "body": "QuickShares are temporary public download links for individual files in workspaces (not available for shares). They can be accessed without authentication. Expires in seconds from creation (default 10,800 = 3 hours, max 604,800 = 7 days) or as an ISO 8601 datetime via expires_at. Max file size: 1 GB. Each quickshare has an opaque identifier used to retrieve metadata and download the file."
      },
      {
        "title": "File Preview",
        "body": "Files uploaded to Fast.io get automatic preview generation. When humans open a share or workspace, they see the content immediately -- no \"download and open in another app\" friction.\n\nSupported preview formats:\n\nImages -- full-resolution with auto-rotation and zoom\nVideo -- HLS adaptive streaming (50--60% faster load than raw video)\nAudio -- interactive waveform visualization\nPDF -- page navigation, zoom, text selection\nSpreadsheets -- grid navigation with multi-sheet support\nCode and text -- syntax highlighting, markdown rendering\n\nUse storage action preview-url (with context_type: \"workspace\" or \"share\") to generate preview URLs. Use storage action preview-transform (with context_type: \"workspace\" or \"share\") for image resize, crop, and format conversion.\n\nAgent use case: Your generated PDF report does not just appear as a download link. The human sees it rendered inline, can flip through pages, zoom in, and comment on specific sections -- all without leaving the browser."
      },
      {
        "title": "Comments and Annotations",
        "body": "Humans and agents can leave feedback directly on files, anchored to specific content using the reference parameter:\n\nImage comments -- anchored to spatial regions (normalized x/y/width/height coordinates)\nVideo comments -- anchored to timestamps with spatial region selection\nAudio comments -- anchored to timestamps or time ranges\nPDF comments -- anchored to specific pages with optional text snippet selection\nText-anchored comments -- anchored to selected text in markdown/notes using exact, prefix, suffix, start_offset, and end_offset fields (use type: \"document\" or type: \"text\")\nThreaded replies -- single-level threading only; replies to replies are auto-flattened to the parent\nEmoji reactions -- one reaction per user per comment; adding a new reaction replaces the previous one\nMention tags -- reference users and files inline using bracket syntax: @[profile:id], @[user:opaqueId:Display Name], @[file:fileId:filename.ext]. Get IDs from member lists, user details, or storage listings. The display name segment is optional for profile tags but recommended for user and file tags\n\nComments use JSON request bodies (Content-Type: application/json), unlike most other endpoints which use form-encoded data.\n\nListing comments: Use comment action list for per-file comments and comment action list-all for all comments across a workspace or share. Both support sort, limit (2-200), offset, include_deleted, reference_type filter, and include_total.\n\nAdding comments: Use comment action add with profile_type, profile_id, node_id, and text. Optionally include parent_comment_id for replies and reference to anchor to a specific position. Supports mention tags in the body. Two character limits apply: total body including tags max 8,192 chars, display text (body with @[...] tags stripped) max 2,048 chars. Optionally include linked_entity_type and linked_entity_id to link the comment to a task or approval at creation time.\n\nDeleting comments: comment action delete is recursive -- deleting a parent also removes all replies. comment action bulk-delete is NOT recursive -- replies to deleted comments are preserved.\n\nComment Linking: Comments can be linked to workflow entities (tasks or approvals). Each comment supports one link at a time (nullable). Use comment action link to associate an existing comment with a task or approval, comment action unlink to remove the association, and comment action linked to reverse-lookup all comments linked to a given entity. You can also link at creation time by passing linked_entity_type and linked_entity_id to the add action. Comment responses include linked_entity_type and linked_entity_id fields (null when unlinked).\n\nLinking users to comments: The preview URL opens the comments sidebar automatically. Deep link query parameters let you target a specific comment or position:\n\nParameterFormatPurpose?comment={id}Comment opaque IDScrolls to and highlights a specific comment for 2 seconds?t={seconds}e.g. ?t=45.5Seeks to timestamp for audio/video comments?p={pageNum}e.g. ?p=3Navigates to page for PDF comments\n\nWorkspace: https://{org.domain}.fast.io/workspace/{folder_name}/preview/{file_opaque_id}?comment={comment_id}\n\nShare: https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{file_opaque_id}?comment={comment_id}\n\nParameters can be combined -- e.g. ?comment={id}&t=45.5 to deep link to a video comment at a specific timestamp. In shares, the comments sidebar only opens if the share has comments enabled.\n\nAgent use case: You generate a design mockup. The human comments \"Change the header color\" on a specific region of the image. You read the comment, see exactly what region they are referring to via the reference.region coordinates, and regenerate.\n\nText-anchored comments (markdown/notes): To anchor a comment to specific text in a markdown or notes file, use the reference parameter with type: \"document\" (or \"text\", which is an alias) and the text selection fields:\n\nexact (string, max 500 chars) -- the selected text verbatim\nprefix (string, max 100 chars) -- ~30-50 characters of context before the selection for disambiguation\nsuffix (string, max 100 chars) -- ~30-50 characters of context after the selection for disambiguation\nstart_offset (integer) -- character offset from document start (hint for resolving ambiguous matches)\nend_offset (integer) -- character offset for end of selection (hint for resolving ambiguous matches)\n\nAt minimum, provide exact. The prefix/suffix fields help locate the selection when the same text appears multiple times. The start_offset/end_offset fields are optional hints that may not survive document edits.\n\nExample -- text-anchored comment on a markdown file:\n\n{\n  \"action\": \"add\",\n  \"profile_type\": \"workspace\",\n  \"profile_id\": \"1234567890123456789\",\n  \"node_id\": \"abc123-def456-ghi789\",\n  \"text\": \"This section needs a citation\",\n  \"reference\": {\n    \"type\": \"document\",\n    \"exact\": \"Studies show a 40% improvement\",\n    \"prefix\": \"In the results section, \",\n    \"suffix\": \" compared to the baseline.\",\n    \"start_offset\": 1250,\n    \"end_offset\": 1280\n  }\n}"
      },
      {
        "title": "URL Import",
        "body": "Agents can import files directly from URLs without downloading them locally first. Fast.io's server fetches the file, processes it, and adds it to your workspace or share.\n\nSupports any HTTP/HTTPS URL\nSupports OAuth-protected sources: Google Drive, OneDrive, Dropbox\nFiles go through the same processing pipeline (preview generation, AI indexing if intelligence is enabled, virus scanning)\n\nUse upload action web-import with the source URL, target profile, and parent node ID. Use upload action web-status to check progress and upload action web-list to list active import jobs.\n\nAgent use case: A user says \"Add this Google Doc to the project.\" You call upload action web-import with the URL. Fast.io downloads it server-side, generates previews, indexes it for AI, and it appears in the workspace. No local I/O."
      },
      {
        "title": "Metadata",
        "body": "Metadata enables structured data annotation on files within workspaces. The system uses a template-based approach: administrators create templates that define the fields (name, type, constraints), then assign a template to the workspace. Files can then have metadata values set against the template fields.\n\nKey points:\n\nOne template per workspace -- each workspace supports at most one assigned metadata template at a time.\nTemplate categories -- legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr.\nField types -- string, int, float, bool, json, url, datetime -- each with optional constraints (min, max, default, fixed_list, can_be_null).\nTwo metadata types -- template metadata conforms to template field definitions; custom metadata is freeform key-value pairs not tied to any template.\nSystem templates -- pre-built templates that are automatically cloned when assigned to a workspace, so customizations do not affect the global definition.\nAI extraction -- the extract action uses AI to analyze file content and automatically populate metadata fields. Extracted values are flagged with is_auto: true. Consumes AI credits.\nVersion history -- metadata changes are tracked with version snapshots, accessible via the versions action.\nRequires billing feature -- the organization must have the metadata billing feature enabled.\nTemplate IDs are alphanumeric strings prefixed with mt_ (e.g. mt_abc123def456)."
      },
      {
        "title": "Ownership Transfer",
        "body": "The primary way agents deliver value: build something, then give it to a human. Also the recommended action when the agent plan runs out of credits and API calls start returning 402 Payment Required -- transfer the org to a human who can upgrade to a paid plan.\n\nIMPORTANT: Account type restriction. The transfer/claim workflow (org actions transfer-token-create, transfer-token-list, transfer-token-delete, transfer-claim) is only available when the agent created an agent account (via auth action signup) and that agent account owns the org. If the agent is signed in with a human account (via auth action signin), the transfer/claim API cannot be used. Human-owned orgs must be upgraded directly by the human through the Fast.io dashboard.\n\nThe flow:\n\nAgent creates an agent account with auth action signup and an org with org action create, sets up workspaces with org action create-workspace, uploads files, configures shares\nAgent generates a transfer token (valid 72 hours) with org action transfer-token-create\nAgent sends the claim URL to the human: https://go.fast.io/claim?token=<token>\nHuman clicks the link and claims the org with their account\n\nWhen to transfer:\n\nThe org is ready for human use (workspaces configured, files uploaded, shares set up)\nThe agent plan runs out of credits (402 Payment Required) -- transfer so the human can upgrade\nThe human explicitly asks to take over the org\n\nManaging transfer tokens:\n\norg action transfer-token-list -- check for existing pending tokens before creating new ones\norg action transfer-token-delete -- revoke a token if the transfer is no longer needed\norg action transfer-claim -- claim an org using a token (used by the receiving human's agent)\n\nWhat happens after transfer:\n\nHuman becomes the owner of the org and all workspaces\nAgent retains admin access (can still manage files and shares)\nHuman gets a free plan (credit-based, no trial period)\nHuman can upgrade to Pro or Business at any time\n\nAgent use case: A user says \"Set up a project workspace for my team.\" You create the org, build out the workspace structure, upload templates, configure shares for client deliverables, invite team members -- then transfer ownership. The human walks into a fully configured platform. You stay on as admin to keep managing things.\n\n402 Payment Required use case (agent account): While working, the agent hits credit limits. Call org action transfer-token-create, send the claim URL to the human, and explain they can upgrade to continue. The agent keeps admin access and resumes work once the human upgrades.\n\n402 Payment Required use case (human account): The agent cannot transfer the org. Instead, inform the user that their org has run out of credits and they need to upgrade their billing plan. Direct them to the Fast.io dashboard or use org action billing-create to update to a paid plan."
      },
      {
        "title": "Workflow (Tasks, Worklogs, Approvals, Todos)",
        "body": "Workspaces and shares support an optional workflow layer that adds structured task management, activity logging, approval gates, and simple checklists. Workflow features are controlled by a toggle -- they must be explicitly enabled before use. On shares, workflow access requires admin or named member role -- guests and view-only users cannot access workflow features.\n\nEnabling Workflow\n\nWorkspaces: workspace action enable-workflow with workspace_id\nShares: share action enable-workflow with share_id\n\nCheck whether workflow is enabled via workspace action details or share action details -- look for workflow: true in the response.\n\nDisabling workflow (workspace action disable-workflow or share action disable-workflow) makes all workflow data inaccessible but preserves it. Re-enabling restores access.\n\nTask Lists and Tasks\n\nTasks are organized into lists. Each workspace or share can have multiple task lists, and each list contains individual tasks.\n\nTask lists have a name and optional description. Create with task action create-list, list with task action list-lists.\nTasks have a title, description, status, priority, assignee, dependencies, and optional node link. Create with task action create-task, list with task action list-tasks.\nStatuses: pending, in_progress, complete, blocked\nPriorities: 0 = none, 1 = low, 2 = medium, 3 = high, 4 = critical\nAssignees are profile IDs (workspace or share members). Use task action assign-task to assign or unassign.\nBulk operations: task action bulk-status changes status on up to 100 tasks at once.\nMoving tasks: task action move-task moves a task from one list to another within the same profile. Requires the source list_id, task_id, and target_task_list_id. Optionally set sort_order to control position in the target list (default: 0).\nReordering: task action reorder-tasks sets the display order of tasks within a list. task action reorder-lists sets the display order of task lists within a profile. Pass arrays of IDs in the desired order; the server converts them to {id, sort_order} objects for the API.\nCreator tracking: Tasks and task lists include a created_by field (profile ID of the creator).\nMarkdown output: Pass format: \"md\" to get human-readable markdown instead of JSON.\n\nWorklogs\n\nWorklogs are append-only chronological activity logs scoped to tasks, task lists, storage nodes, or profiles. Entries cannot be edited or deleted after creation.\n\nEntries: Regular log entries appended with worklog action append. Use for progress updates, decisions, reasoning, and status changes.\nInterjections: Priority corrections created with worklog action interject. Interjections are always urgent and require acknowledgement from other participants.\nAcknowledgement: worklog action acknowledge marks an interjection as seen. worklog action unacknowledged lists interjections that still need acknowledgement. Entries include an acknowledgable boolean -- when true, the entry is an unacknowledged interjection that can be acknowledged.\nResponse fields: Entries include acknowledged (boolean), acknowledgable (boolean), updated (ISO 8601 timestamp), and created (ISO 8601 timestamp).\nMarkdown output: Pass format: \"md\" for human-readable output.\n\nApprovals\n\nFormal approval requests scoped to tasks, storage nodes, or worklog entries. Use when a decision requires explicit sign-off.\n\nCreate: approval action create with profile_id, description (1-5000 chars), entity_type (\"task\", \"node\", or \"worklog_entry\"), and optionally approver_id (a single profile ID, must be an entity member).\nResolve: approval action resolve with resolve_action: \"approve\" or \"reject\" and an optional comment. Only designated approvers can resolve.\nStatuses: pending, approved, rejected\nMarkdown output: Pass format: \"md\" for human-readable output.\n\nTodos\n\nSimple flat checklists scoped to workspaces and shares. No nesting -- just a list of items that can be checked off.\n\nCreate: todo action create with a title.\nToggle: todo action toggle flips the done state of a single todo. todo action bulk-toggle sets done state on up to 100 todos at once.\nUpdate/Delete: todo action update changes title. todo action delete soft-deletes a todo.\nCreator tracking: Todos include a created_by field (profile ID of the creator).\nMarkdown output: Pass format: \"md\" for human-readable output.\n\nNotes as Agent Knowledge Layer\n\nNotes (type: \"note\") are markdown files stored in workspace storage (see Notes above). When combined with workflow features, notes become a knowledge layer:\n\nAutomatic AI indexing: When workspace intelligence is enabled, notes are ingested and indexed for RAG just like uploaded files.\nLink tasks to notes: Tasks can reference storage nodes, including notes. Create context notes for project background, requirements, or reference material, then create tasks that link to those notes for full context.\nWorklogs for reasoning: Use worklog entries to record decisions, progress, and reasoning over time. The chronological log builds a narrative that complements the structured task list.\nAI can search all context: With intelligence enabled, AI chat can search across notes, worklogs, task descriptions, and uploaded files -- giving comprehensive answers grounded in the project's full history.\n\nRecommended pattern: Create notes for project context and requirements. Create task lists for work phases. Link tasks to relevant notes. Log progress with worklogs. Request approvals for decisions. The AI can then answer questions like \"Why did we choose this approach?\" by searching across all of these artifacts."
      },
      {
        "title": "Permission Parameter Values",
        "body": "Several tools use permission parameters with specific allowed values. Use these exact strings when calling the tools.\n\nOrganization Creation (org action create)\n\nParameterAllowed ValuesDefaultperm_member_manageOwner only, Admin or above, Member or aboveMember or aboveindustryunspecified, technology, healthcare, financial, education, manufacturing, construction, professional, media, retail, real_estate, logistics, energy, automotive, agriculture, pharmaceutical, legal, government, non_profit, insurance, telecommunications, research, entertainment, architecture, consulting, marketingunspecifiedbackground_modestretched, fixedstretched\n\nWorkspace Creation (org action create-workspace) and Update (workspace action update)\n\nParameterAllowed ValuesDefaultperm_joinOnly Org Owners, Admin or above, Member or aboveMember or aboveperm_member_manageAdmin or above, Member or aboveMember or above\n\nShare Creation (share action create)\n\nParameterAllowed ValuesDefaulttypesend, receive, exchangeexchangestorage_modeindependent, workspace_folderindependentaccess_optionsOnly members of the Share or Workspace, Members of the Share, Workspace or Org, Anyone with a registered account, Anyone with the linkOnly members of the Share or Workspaceinviteowners, guestsownersnotifynever, notify_on_file_received, notify_on_file_sent_or_receivedneverdisplay_typelist, gridgridintelligencetrue, falsefalsecomments_enabledtrue, falsetruedownload_enabledtrue, falsetrueguest_chat_enabledtrue, falsefalseworkspace_styletrue, falsetruebackground_image0-1280\n\nShare constraints:\n\nReceive and Exchange shares cannot use Anyone with the link access -- this option is only available for Send shares.\nPassword protection (password parameter) is only allowed when access_options is Anyone with the link.\nExpiration (expires parameter in MySQL format YYYY-MM-DD HH:MM:SS) is not allowed on workspace_folder shares.\nField length and format constraints for custom_name, title, and description are documented in the Profile Field Constraints table below.\nColor parameters (accent_color, background_color1, background_color2) accept JSON strings.\ncreate_folder creates a new workspace folder for the share when used with storage_mode='workspace_folder'."
      },
      {
        "title": "Profile Field Constraints",
        "body": "All profile fields are validated server-side. Requests that violate these constraints are rejected with a 400 error.\n\nEntityFieldAPI KeyMinMaxPatternRequiredNullableOrgdomaindomain263^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$Yes (create)NoOrgnamename3100No control charsYesNoOrgdescriptiondescription101000No control charsNoYesWorkspacefolder_namefolder_name480^[\\p{L}\\p{N}-]+$ (letters, digits, hyphens)Yes (create)NoWorkspacenamename2100No control charsYesNoWorkspacedescriptiondescription101000No control charsNoYesSharecustom_namecustom_name480^[\\p{L}\\p{N}]+$ (letters, digits only)Yes (create)NoSharecustom_urlcustom_url10100—YesYesSharetitletitle280No control charsYesYesSharedescriptiondescription10500No control charsNoYes\n\n\"No control chars\" = rejects Unicode control characters (\\p{C})\nOrg domain: lowercase ASCII alphanumeric + hyphens; cannot start/end with hyphen\nWorkspace folder_name: Unicode letters, digits, and hyphens. Globally unique -- not scoped to an org. Recommend {org_id}-{name} convention to avoid collisions (auto-applied by create-workspace when name is taken)\nShare custom_name: Unicode letters and digits only (no hyphens or special chars)\nShare description max is 500 (org/workspace is 1000)"
      },
      {
        "title": "4. Agent Plan -- Free Tier",
        "body": "The agent plan is a free tier designed for AI agents. No credit card, no trial period, no expiration. Enough resources to build and demonstrate value, with room to grow when the org transfers to a human on a paid plan."
      },
      {
        "title": "Resource Limits",
        "body": "ResourceIncludedPrice$0 -- no credit card, no trial period, no expirationStorage50 GBMax file size1 GBMonthly credits5,000 (resets every 30 days)Workspaces5Shares50Members per workspace5Share invitations10 per shareAccount auto-deletionNever"
      },
      {
        "title": "Credit Costs",
        "body": "All platform activity consumes credits from the monthly 5,000 allowance:\n\nResourceCostStorage100 credits/GBBandwidth212 credits/GBAI chat tokens1 credit per 100 tokensDocument pages ingested10 credits/pageVideo ingested5 credits/secondAudio ingested0.5 credits/secondImages ingested5 credits/imageFile conversions25 credits/conversion\n\nWhen credits run out, the org enters a reduced-capability state and API calls return 402 Payment Required. The org is never deleted. Use org action limits to check current credit usage and remaining balance.\n\nWhen you hit 402 or run low on credits:\n\nAgent account (created via auth action signup): Transfer the org to the human. Call org action transfer-token-create to generate a transfer token, then send the human the claim URL: https://go.fast.io/claim?token=<token>. Once they claim the org they can upgrade to a paid plan with unlimited credits. You retain admin access and can resume work immediately after the upgrade. This is the expected workflow -- agents build on the free plan, then hand off to humans who pay when they are ready.\nHuman account (signed in via auth action signin): You cannot use the transfer/claim API. Tell the user they need to upgrade the org's billing plan directly. They can do this from the Fast.io dashboard or by calling org action billing-create to update their subscription to a paid plan."
      },
      {
        "title": "After Transfer -- Human Plan Options",
        "body": "Once an agent transfers an org to a human, the human gets a free plan (credit-based, no trial period) and can upgrade:\n\nFeatureAgent (Free)Free (Human)ProBusinessMonthly credits5,0005,000UnlimitedUnlimitedStorage50 GB50 GB1 TB5 TBMax file size1 GB1 GB25 GB50 GBWorkspaces55101,000Shares50501,00050,000\n\nThe transfer flow is the primary way agents deliver value: set everything up on the free agent plan, then hand it off. The human upgrades when they are ready, and the agent retains admin access to keep managing things."
      },
      {
        "title": "5. Tool Categories",
        "body": "The 19 tools use action-based routing. Each tool covers a specific area of the Fast.io platform and exposes multiple actions."
      },
      {
        "title": "auth",
        "body": "Authentication, sign-in/sign-up, two-factor authentication, API key management, and OAuth session management. This is always the starting point for any agent interaction.\n\nActions: signin, signout, signup, check, session, status, set-api-key, email-check, email-verify, password-reset-request, password-reset, 2fa-verify, 2fa-status, 2fa-enable, 2fa-disable, 2fa-send, 2fa-verify-setup, pkce-login, pkce-complete, api-key-create, api-key-update, api-key-list, api-key-get, api-key-delete, oauth-list, oauth-details, oauth-revoke, oauth-revoke-all"
      },
      {
        "title": "user",
        "body": "Retrieve and update the current user profile, search for other users, manage invitations, upload and delete user assets (profile photos), check account eligibility, and list shares the user belongs to.\n\nActions: me, update, search, close, details-by-id, profiles, allowed, org-limits, list-shares, invitation-list, invitation-details, accept-all-invitations, asset-upload, asset-delete, asset-types, asset-list"
      },
      {
        "title": "org",
        "body": "Organization CRUD, member management, billing and subscription operations, workspace creation, invitation workflows, asset management (upload, delete), organization discovery, and ownership transfer.\n\nActions: list, details, create, update, close, public-details, limits, list-workspaces, list-shares, create-workspace, billing-plans, billing-create, billing-cancel, billing-details, billing-activate, billing-reset, billing-members, billing-meters, members, invite-member, remove-member, update-member-role, member-details, leave, transfer-ownership, join, invitations-list, invitation-update, invitation-delete, transfer-token-create, transfer-token-list, transfer-token-delete, transfer-claim, discover-all, discover-available, discover-check-domain, discover-external, asset-upload, asset-delete, asset-types, asset-list"
      },
      {
        "title": "workspace",
        "body": "Workspace-level settings, lifecycle operations (update, delete, archive, unarchive), listing and importing shares, managing workspace assets, workspace discovery, notes (create, read, update), quickshare management, metadata operations (template CRUD, assignment, file metadata get/set/delete, AI extraction), and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).\n\nActions: list, details, update, delete, archive, unarchive, members, list-shares, import-share, available, check-name, create-note, read-note, update-note, quickshare-get, quickshare-delete, quickshares-list, metadata-template-create, metadata-template-delete, metadata-template-list, metadata-template-details, metadata-template-update, metadata-template-clone, metadata-template-assign, metadata-template-unassign, metadata-template-resolve, metadata-template-assignments, metadata-get, metadata-set, metadata-delete, metadata-extract, metadata-list-files, metadata-list-templates-in-use, metadata-versions, enable-workflow, disable-workflow"
      },
      {
        "title": "share",
        "body": "Share CRUD, public details, archiving, password authentication, asset management, share name availability checks, and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).\n\nActions: list, details, create, update, delete, public-details, archive, unarchive, password-auth, members, available, check-name, quickshare-create, enable-workflow, disable-workflow"
      },
      {
        "title": "storage",
        "body": "File and folder operations within workspaces and shares. List, list recently modified files across all folders, create folders, move, copy, delete, rename, purge, restore, search, add files from uploads, add share links, transfer nodes, manage trash, version operations, file locking, and preview/transform URL generation. Requires context_type parameter (workspace or share).\n\nActions: list, recent, details, search, trash-list, create-folder, copy, move, delete, rename, purge, restore, add-file, add-link, transfer, version-list, version-restore, lock-acquire, lock-status, lock-release, preview-url, preview-transform"
      },
      {
        "title": "upload",
        "body": "File upload operations. Single-step text file upload, chunked upload lifecycle (create session, stage binary blobs, upload chunks as plain text / base64 / blob reference, finalize, check status, cancel), web imports from external URLs, upload limits and file extension restrictions, and session management.\n\nActions: create-session, chunk, finalize, status, cancel, list-sessions, cancel-all, chunk-status, chunk-delete, stage-blob, text-file, web-import, web-list, web-cancel, web-status, limits, extensions"
      },
      {
        "title": "download",
        "body": "Generate download URLs and ZIP archive URLs for workspace files, share files, and quickshare links. MCP tools cannot stream binary data -- these actions return URLs that can be opened in a browser or passed to download utilities. Requires context_type parameter (workspace or share) for file-url and zip-url actions. Responses include a resource_uri field (e.g. download://workspace/{id}/{node_id}) that MCP clients can use to read file content directly via MCP resources. Direct download URLs include ?error=html so errors render as human-readable HTML in browsers.\n\nActions: file-url, zip-url, quickshare-details"
      },
      {
        "title": "ai",
        "body": "AI-powered chat with RAG, semantic search, and document analysis in workspaces and shares. Create chats, send messages, read AI responses (with polling), list and manage chats, search indexed documents and code by meaning with relevance scores, publish private chats, generate AI share markdown, track AI token usage, and auto-title generation. Requires context_type parameter (workspace or share).\n\nActions: chat-create, chat-list, chat-details, chat-update, chat-delete, chat-publish, message-send, message-list, message-details, message-read, search, share-generate, transactions, autotitle"
      },
      {
        "title": "comment",
        "body": "Comments are scoped to {entity_type}/{parent_id}/{node_id} where entity_type is workspace or share, parent_id is the 19-digit profile ID, and node_id is the storage node opaque ID. List comments on files (per-node and profile-wide with sort/limit/offset/filter params), add comments with optional reference anchoring (image regions, video/audio timestamps, PDF pages with text selection, text selections in markdown/notes), single-level threaded replies, recursive single delete, non-recursive bulk delete, get comment details, emoji reactions (one per user per comment), and workflow linking (link/unlink comments to tasks or approvals, reverse lookup). Comments use JSON request bodies.\n\nActions: list, list-all, add, delete, bulk-delete, details, reaction-add, reaction-remove, link, unlink, linked"
      },
      {
        "title": "event",
        "body": "Search the audit/event log with rich filtering by category, subcategory, and event name (see Event Filtering Reference in section 7 for the full taxonomy). Get AI-powered summaries of activity, retrieve full details for individual events, list recent activity, and long-poll for activity changes.\n\nActions: search, summarize, details, activity-list, activity-poll"
      },
      {
        "title": "member",
        "body": "Member management for organizations, workspaces, and shares. Add, remove, update roles, transfer ownership, leave, join, and join via invitation. Requires entity_type parameter (workspace or share).\n\nActions: add, remove, details, update, transfer-ownership, leave, join, join-invitation"
      },
      {
        "title": "invitation",
        "body": "Invitation management for organizations, workspaces, and shares. List invitations, list by state, update, and delete. Requires entity_type parameter (workspace or share).\n\nActions: list, list-by-state, update, delete"
      },
      {
        "title": "asset",
        "body": "Asset management (upload, delete, list, read) for organizations, workspaces, shares, and users. Requires entity_type parameter (org, workspace, share, or user).\n\nActions: upload, delete, types, list, read"
      },
      {
        "title": "task",
        "body": "Task list and task management for workspaces and shares. Create and manage task lists, then create tasks within them with statuses, priorities, assignees, and dependencies. Supports bulk status changes, reordering, and markdown output. Tasks and lists include created_by (creator profile ID). Requires workflow to be enabled on the target entity.\n\nActions: list-lists, create-list, list-details, update-list, delete-list, list-tasks, create-task, task-details, update-task, delete-task, change-status, assign-task, bulk-status, move-task, reorder-tasks, reorder-lists"
      },
      {
        "title": "worklog",
        "body": "Activity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. Also create urgent interjections that require acknowledgement. Entries are append-only and permanent. Requires workflow to be enabled on the target entity.\n\nActions: append, list, interject, details, acknowledge, unacknowledged"
      },
      {
        "title": "approval",
        "body": "Formal approval requests scoped to tasks, storage nodes, or worklog entries. Create approval requests with designated approvers, then resolve them with approve or reject decisions. Requires workflow to be enabled on the target entity.\n\nActions: list, create, details, resolve"
      },
      {
        "title": "todo",
        "body": "Simple flat checklists scoped to workspaces and shares. Create, update, delete, toggle todos individually or in bulk. Todos include created_by (creator profile ID). No nesting. Requires workflow to be enabled on the target entity.\n\nActions: list, create, details, update, delete, toggle, bulk-toggle"
      },
      {
        "title": "apps",
        "body": "Interactive MCP App widget discovery and launching. List available widgets, get details for a specific widget, launch a widget with workspace or share context, and find widgets associated with a specific tool domain.\n\nActions: list, details, launch, get-tool-apps"
      },
      {
        "title": "1. Create an Account and Sign In",
        "body": "See Choosing the Right Approach in section 2 for which option fits your scenario.\n\nOption 1 -- Autonomous agent (new account):\n\nOptionally call auth action email-check with the desired email to verify availability.\nauth action signup with first_name, last_name, email, and password -- registers as an agent account (agent=true is sent automatically) and signs in immediately.\nauth action email-verify with email -- sends a verification code. Then auth action email-verify with email and email_token -- validates the code. Required before using most endpoints.\norg action create to create a new org on the agent plan, or org action list to check existing orgs.\n\nOption 2 -- Assisting a human (API key):\n\nThe human creates an API key at https://go.fast.io/settings/api-keys and provides it to the agent.\nCall auth action set-api-key with the API key. The key is validated against the API and stored in the session -- all subsequent tool calls are authenticated automatically. No account creation needed.\norg action list and org action discover-external to discover all available organizations (see Org Discovery).\n\nOption 3 -- Agent invited to a human's org:\n\nCreate an agent account with auth action signup (same as Option 1).\nHave the human invite you via org action invite-member or member action add (with entity_type: \"workspace\").\nAccept invitations with user action accept-all-invitations.\norg action list and org action discover-external to discover all available orgs (see Org Discovery). If the human only invited you to a workspace (not the org), it will only appear via discover-external.\n\nReturning users:\n\nauth action signin with email and password.\nIf two_factor_required: true, call auth action 2fa-verify with the 2FA code.\norg action list and org action discover-external to discover all available organizations (see Org Discovery)."
      },
      {
        "title": "2. Browse and Download a File",
        "body": "org action list and org action discover-external -- discover all available organizations (see Org Discovery). Note the org_id values.\norg action list-workspaces with org_id -- get workspaces in the organization. Note the workspace_id values.\nstorage action list with context_type: \"workspace\", context_id (workspace ID), and node_id: \"root\" -- browse the root folder. Note the node_id values for files and subfolders.\nstorage action details with context_type: \"workspace\", context_id, and node_id -- get full details for a specific file (name, size, type, versions).\ndownload action file-url with context_type: \"workspace\", context_id, and node_id -- get a temporary download URL with an embedded token. The response also includes a resource_uri (e.g. download://workspace/{id}/{node_id}) that MCP clients can use to read file content directly. Return the download URL to the user, or use the resource URI to read the file through MCP."
      },
      {
        "title": "3. Upload a File to a Workspace",
        "body": "Text files (recommended): Use upload action text-file with profile_type: \"workspace\", profile_id, parent_node_id, filename, and content (plain text). This single action uploads the file and returns new_file_id on success. Internally it uses the Fast.io single-request upload pattern (one multipart POST with the file data), so there is no separate chunking, finalization, or polling step. Use this for code, markdown, CSV, JSON, config files, and any other text content.\n\nBinary files (choose the right approach):\n\nUnderstanding upload constraints. The Fast.io API requires each chunk to be ≥ 1 MB (except the last chunk of a session, which may be smaller). MCP tool calls have a practical transport limit of ~64 KB of raw binary per call (~96 KB base64). This means multi-chunk binary uploads through MCP tool calls alone will fail for files larger than ~64 KB — each MCP-sized chunk is far below the 1 MB API minimum. Use upload action limits to check your plan's exact chunk size and file size limits.\n\nOption A: web-import (preferred for URL-accessible files)\nIf the file has a URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use upload action web-import. Single call, no chunking, no base64. See Workflow 4 below.\n\nOption B: Single-chunk upload for small binary files (≤ ~64 KB)\nSmall files that fit in one MCP tool call can be uploaded as a single chunk:\n\nupload action create-session with profile_type, profile_id, parent_node_id, filename, and filesize in bytes.\nupload action chunk with upload_id, chunk_number: 1, and data (base64-encoded file, ≤96 KB base64 / ~64 KB binary). Since this is the only chunk, the API's \"1 small chunk allowed\" rule permits it.\nupload action finalize with upload_id.\n\nOption C: POST /blob sidecar endpoint for larger binary files\nFor files > ~64 KB, use the HTTP blob endpoint to bypass MCP transport limits. The POST /blob endpoint accepts raw binary via HTTP (no base64, no size splitting within MCP). Stage blobs of ≥ 1 MB each (except the last), then reference them in chunk calls:\n\nupload action create-session with profile_type, profile_id, parent_node_id, filename, and filesize.\nFor each chunk: POST /blob with raw binary (≥ 1 MB, ≤ 100 MB). Returns blob_id.\nupload action chunk with upload_id, chunk_number, and blob_ref: \"<blob_id>\".\nupload action finalize with upload_id.\n\nOption D: External upload tooling\nFor reliable binary uploads of any size, use an external HTTP client (Python requests, curl, etc.) to call the Fast.io REST API upload endpoints directly, bypassing MCP transport constraints entirely. Use MCP for control-plane tasks (session creation, finalization, status) and the external client for the data plane (chunk uploads).\n\nThree options for passing chunk data (provide exactly one):\n\ncontent — for text (strings, code, JSON, etc.). Do NOT use data for text.\ndata — base64-encoded binary. Limited by MCP transport to ~96 KB base64 (~64 KB binary) per call. Only practical for single-chunk small files.\nblob_ref — blob ID from upload action stage-blob or POST /blob. The POST /blob approach is recommended for larger files since it bypasses MCP transport limits.\n\nupload action finalize with upload_id triggers file assembly and polls until stored. Returns the final session state with status: \"stored\" or \"complete\" on success (including new_file_id), or throws on failure. Terminal failure states: assembly_failed (chunks could not be assembled) and store_failed (assembled file could not be stored — check status_message for details). The file is automatically added to the target workspace and folder specified during session creation -- no separate add-file call is needed.\n\nUpload status states:\n\nStatusMeaningTerminal?readySession created, awaiting chunksNouploadingChunks being receivedNoassemblingAssembly in progressNocompleteAssembled, awaiting storage importNostoringBeing imported to storageNostoredDone — file is in storage, new_file_id availableYes (success)assembly_failedAssembly errorYes (failure)store_failedStorage import failedYes (failure)\n\nNote: storage action add-file is only needed if you want to link the upload to a different location than the one specified during session creation.\n\nSame-name uploads: If a file with the same name already exists in the target folder, the upload replaces (overwrites) it. The previous content is preserved as a version. To keep both files, rename before uploading."
      },
      {
        "title": "4. Import a File from URL",
        "body": "Use this when you have a file URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox) and want to add it to a workspace without downloading locally.\n\nupload action web-import with url (the source URL), profile_type: \"workspace\", profile_id (the workspace ID), and parent_node_id (target folder or \"root\"). Returns an upload_id.\nupload action web-status with upload_id -- check import progress. The server downloads the file, scans it, generates previews, and indexes it for AI (if intelligence is enabled).\nThe file appears in the workspace storage tree once the job completes."
      },
      {
        "title": "5. Deliver Files to a Client",
        "body": "Create a branded, professional share for outbound file delivery. This replaces raw download links, email attachments, and S3 presigned URLs.\n\nUpload files to the workspace (see workflow 3 or 4).\nshare action create with workspace_id, name, and type: \"send\" -- creates a Send share. Returns a share_id.\nshare action update with share_id to configure:\n\npassword -- require a password for access\nexpiry_date -- auto-expire the share after a set period\naccess_level -- Members Only, Org Members, Registered Users, or Public\nallow_downloads -- enable or disable file downloads\nBranding options: background_color, accent_color, gradient_color\npost_download_message and post_download_url -- show a message after download\n\n\nmember action add with entity_type: \"share\", entity_id (share ID), and email_or_user_id -- adds the recipient. An invitation is sent if they do not have a Fast.io account.\nasset action upload with entity_type: \"share\" and entity_id (share ID) to add a logo or background image for branding.\nThe recipient sees a branded page with instant file preview, not a raw download link."
      },
      {
        "title": "6. Collect Documents from a User",
        "body": "Create a Receive share so humans can upload files directly to you -- no email attachments, no cloud drive links.\n\nshare action create with workspace_id, name (e.g., \"Upload your tax documents here\"), and type: \"receive\". Returns a share_id.\nshare action update with share_id to set access level, expiration, and branding as needed.\nmember action add with entity_type: \"share\", entity_id (share ID), and email_or_user_id to invite the uploader.\nThe human uploads files through a clean, branded interface.\nFiles appear in your workspace. If intelligence is enabled, they are auto-indexed by AI.\nUse ai action chat-create with context_type: \"share\" scoped to the receive share's folder to ask questions like \"Are all required forms present?\""
      },
      {
        "title": "7. Build a Knowledge Base",
        "body": "Create an intelligent workspace that auto-indexes all content for RAG queries.\n\norg action create-workspace with org_id, name, and intelligence: \"true\" (this workflow specifically requires intelligence for RAG).\nUpload reference documents (see workflow 3 or 4). AI auto-indexes and summarizes everything on upload.\nai action chat-create with context_type: \"workspace\", context_id (workspace ID), query_text, type: \"chat_with_files\", and folders_scope (comma-separated nodeId:depth pairs) to query across folders or the entire workspace.\nai action message-read with context_type: \"workspace\", context_id, chat_id, and message_id -- polls until the AI response is complete. Returns response_text and citations pointing to specific files, pages, and snippets.\nstorage action search with context_type: \"workspace\", context_id, and a query string for semantic search -- find files by meaning, not just filename.\nAnswers include citations to specific pages and files. Pass these back to the user with source references."
      },
      {
        "title": "8. Ask AI About Files",
        "body": "Two modes depending on whether intelligence is enabled on the workspace.\n\nWith intelligence (persistent index):\n\nai action chat-create with context_type: \"workspace\", context_id (workspace ID), query_text, type: \"chat_with_files\", and either files_scope (comma-separated nodeId:versionId pairs) or folders_scope (comma-separated nodeId:depth pairs, depth range 1-10). Important: files_scope and files_attach are mutually exclusive — sending both will error. Returns chat_id and message_id.\nai action message-read with context_type: \"workspace\", context_id, chat_id, and message_id -- polls the API up to 15 times (2-second intervals, approximately 30 seconds) until the AI response is complete. Returns response_text and citations. Tip: If the built-in polling window expires, use event action activity-poll with the workspace ID instead of calling message-read in a loop — see the Activity Polling section above.\nai action message-send with context_type: \"workspace\", context_id, chat_id, and query_text for follow-up questions. Returns a new message_id.\nai action message-read again with the new message_id to get the follow-up response.\n\nWithout intelligence (file attachments):\n\nai action chat-create with context_type: \"workspace\", context_id, query_text, type: \"chat_with_files\", and files_attach pointing to specific files (comma-separated nodeId:versionId, max 20 files / 200 MB). Files must have ai.attach: true (check via storage action details). The AI reads attached files directly without persistent indexing.\nai action message-read to get the response. No ingestion credit cost -- only chat token credits are consumed."
      },
      {
        "title": "9. Set Up a Project for a Human",
        "body": "The full agent-to-human handoff workflow. This is the primary way agents deliver value on Fast.io.\n\norg action create -- creates a new org on the agent billing plan. The agent becomes owner. An agent-plan subscription (free, 50 GB, 5,000 credits/month) is created automatically.\norg action create-workspace with org_id and name -- create workspaces for each project area.\nstorage action create-folder with context_type: \"workspace\" to build out folder structure (templates, deliverables, reference docs, etc.).\nUpload files to each workspace (see workflow 3 or 4).\nshare action create with type: \"send\" for client deliverables, type: \"receive\" for intake/collection.\nshare action update to configure branding, passwords, expiration, and access levels on each share.\norg action invite-member or member action add with entity_type: \"workspace\" to invite team members.\norg action transfer-token-create with org_id -- generates a transfer token valid for 72 hours. Send the claim URL (https://go.fast.io/claim?token=<token>) to the human.\nHuman clicks the link and claims the org. They become owner, agent retains admin access. Human gets a free plan."
      },
      {
        "title": "10. Manage Organization Billing",
        "body": "org action billing-plans -- list all available billing plans with pricing and features.\norg action billing-create with org_id and optionally billing_plan -- create or update a subscription. For new subscriptions, this creates a Stripe Setup Intent.\norg action billing-details with org_id -- check the current subscription status, Stripe customer info, and payment details.\norg action limits with org_id -- check credit usage against plan limits, including storage, transfer, AI tokens, and billing period info."
      },
      {
        "title": "11. Manage Tasks in a Workspace",
        "body": "Track work with structured task lists and tasks.\n\nworkspace action enable-workflow with workspace_id -- enable workflow features (required before using task, worklog, approval, or todo tools).\ntask action create-list with profile_type: \"workspace\", profile_id (workspace ID), and name -- create a task list. Returns list_id.\ntask action create-task with list_id, title, and optionally description, priority (0-4), assignee_id, dependencies, node_id, and status -- add tasks to the list.\ntask action list-tasks with list_id -- view all tasks, optionally filtered by status or assignee.\ntask action change-status with list_id, task_id, and status -- update task progress (pending → in_progress → complete).\ntask action assign-task with list_id, task_id, and assignee_id -- assign work to team members.\ntask action bulk-status with list_id, task_ids, and status -- batch-update up to 100 tasks at once."
      },
      {
        "title": "12. Full Agent Workflow (Tasks + Worklogs + Approvals)",
        "body": "The complete agentic workflow pattern: plan work, execute with logging, and gate decisions with approvals.\n\nworkspace action enable-workflow with workspace_id -- enable workflow features on the workspace.\nworkspace action create-note -- create context notes with project background, requirements, and reference material.\ntask action create-list -- create task lists for each work phase (e.g., \"Research\", \"Implementation\", \"Review\").\ntask action create-task -- add tasks linked to context. Include descriptive titles and reference note node_ids in descriptions.\ntask action change-status with status: \"in_progress\" -- mark a task as started.\nworklog action append with entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type \"profile\"), and content -- log progress, decisions, and reasoning as you work. Build a chronological narrative.\nIf a priority correction is needed: worklog action interject -- creates an urgent entry that requires acknowledgement from other participants.\nworklog action unacknowledged -- check for unacknowledged interjections before proceeding.\nworklog action acknowledge -- mark interjections as seen.\nWhen a decision needs sign-off: approval action create with profile_id, description, entity_type (\"task\", \"node\", or \"worklog_entry\"), and optionally approver_id -- request formal approval.\napproval action resolve with resolve_action: \"approve\" or \"reject\" and optional comment -- approvers resolve the request.\ntask action change-status with status: \"complete\" -- mark completed tasks.\ntodo action create -- track simple checklist items alongside the main task flow.\nWith intelligence enabled, ai action chat-create -- the AI can search across notes, task descriptions, and worklogs to answer questions about the project."
      },
      {
        "title": "ID Format",
        "body": "Profile IDs (org, workspace, share, user) are 19-digit numeric strings. Most endpoints also accept custom names as identifiers -- workspace folder names, share URL names, org domain names, or user email addresses. Both formats are interchangeable in URL path parameters.\n\nAll other IDs (node IDs, upload IDs, chat IDs, comment IDs, invitation IDs, etc.) are 30-character alphanumeric opaque IDs (displayed with hyphens). Do not apply numeric validation to these."
      },
      {
        "title": "Pagination",
        "body": "Two pagination styles are used depending on the endpoint:\n\nCursor-based (storage list endpoints): sort_by, sort_dir, page_size, and cursor. The response includes a next_cursor value when more results are available. Pass this cursor in the next call to retrieve the next page. Page sizes are typically 100, 250, or 500. Used by: storage action list (with context_type: \"workspace\" or \"share\").\n\nLimit/offset (all other list endpoints): limit (1-500, default 100) and offset (default 0). Used by: org actions list, members, list-workspaces, list-shares, billing-members, discover-all, discover-external; share actions list, members; workspace actions list, members, list-shares; user action list-shares; storage action search."
      },
      {
        "title": "Binary Downloads",
        "body": "MCP tools return download URLs -- they never stream binary content directly. download action file-url (with context_type: \"workspace\" or \"share\") and download action quickshare-details call the /requestread/ endpoint to obtain a temporary token, then construct a full download URL. The agent should return these URLs to the user or pass them to a download utility.\n\ndownload actions zip-url (workspace and share) return the URL along with the required Authorization header value."
      },
      {
        "title": "Binary Uploads",
        "body": "Three approaches for uploading binary data as chunks, each suited to different situations.\n\nPrefer web-import for URL-accessible files. If the binary file is accessible via any URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use upload action web-import instead of chunked upload. It's a single tool call — no chunking, no base64, no session management. Only use chunked upload when you have local binary data with no URL available.\n\nChunk size limit for MCP agents. MCP tool parameters pass through the AI model's output, which limits how much data you can include in a single tool call. Keep each chunk's base64 data under 32 KB (~24 KB of binary). For example, a 145 KB PDF needs at least 6 chunks, and even a 17 KB file should be split into 1-2 chunks rather than assumed to fit in one call. The create-session response includes a recommended_mcp_chunk_bytes hint (default 24576) — use it to calculate the number of chunks: ceil(filesize / recommended_mcp_chunk_bytes). Always split files into multiple chunks when using data or stage-blob through MCP tool calls.\n\nCommon pitfall: do NOT pre-process binary data into intermediate formats. Pass base64 data directly in the data parameter of chunk or stage-blob tool calls. Do NOT read binary files into Python/JSON variables, pickle them, or save to temp files hoping to reference them later — the MCP tool can only receive data through its own parameters. If you have local binary files, base64-encode them in ≤32 KB segments and pass each segment directly as the data parameter in sequential stage-blob → chunk calls. Create upload sessions immediately before uploading — sessions expire, so do not debug between creating a session and uploading chunks.\n\n1. data parameter (base64) — simplest for MCP agents\n\nPass base64-encoded binary directly in the data parameter of upload action chunk. No extra steps required. Works with any MCP client. Adds ~33% size overhead from base64 encoding. Split files into chunks of ≤24 KB binary (≤32 KB base64) to stay within MCP client parameter limits.\n\n2. stage-blob action — MCP tool-based blob staging\n\nUse upload action stage-blob with data (base64) to pre-stage binary data as a blob. Returns a blob_id that you pass as blob_ref in the chunk call. Useful when you want to decouple staging from uploading, or when preparing multiple chunks in advance. The same 32 KB base64 limit per call applies — stage one chunk-sized piece at a time.\n\nFlow:\n\nupload action stage-blob with data (base64-encoded binary, ≤32 KB). Returns { \"blob_id\": \"<uuid>\", \"size\": <bytes> }.\nupload action chunk with blob_ref: \"<blob_id>\". The server retrieves the staged bytes and uploads them.\n\n3. POST /blob endpoint — HTTP blob staging for non-MCP clients\n\nA sidecar HTTP endpoint that accepts raw binary data outside the JSON-RPC pipe. This avoids base64 encoding entirely — useful for clients that can make direct HTTP requests alongside MCP tool calls. No chunk size splitting needed with this approach.\n\nFlow:\n\nPOST /blob with headers Mcp-Session-Id: <session_id> and Content-Type: application/octet-stream. Send raw binary bytes as the request body. Returns { \"blob_id\": \"<uuid>\", \"size\": <bytes> } (HTTP 201).\nupload action chunk with blob_ref: \"<blob_id>\".\n\nBlob constraints (apply to both staging methods):\n\nBlobs expire after 5 minutes. Stage and consume them promptly.\nEach blob is consumed (deleted) on first use — it cannot be reused.\nMaximum blob size: 100 MB.\nSSE transport clients must add ?transport=sse to the /blob URL."
      },
      {
        "title": "Event Filtering Reference",
        "body": "The event tool's search and summarize actions accept category, subcategory, and event parameters to narrow results. Use these to target specific activity instead of scanning all events.\n\nEvent Categories\n\nCategoryWhat It CoversuserAccount creation, updates, deletion, avatar changesorgOrganization lifecycle, settings, transfersworkspaceWorkspace creation, updates, archival, file operationsshareShare lifecycle, settings, file operationsnodeFile and folder operations (cross-profile)aiAI chat, summaries, RAG indexinginvitationMember invitations sent, accepted, declinedbillingSubscriptions, trials, credit usagedomainCustom domain configurationappsApplication integrationsmetadataMetadata extraction, templates, key-value updates\n\nEvent Subcategories\n\nSubcategoryWhat It CoversstorageFile/folder add, move, copy, delete, restore, downloadcommentsComment created, updated, deleted, mentioned, replied, reactionmembersMember added/removed from org, workspace, or sharelifecycleProfile created, updated, deleted, archivedsettingsConfiguration and preference changessecuritySecurity-related events (2FA, password)authenticationLogin, SSO, session eventsaiAI processing, chat, indexinginvitationsInvitation managementbillingSubscription and payment eventsassetsAvatar/asset updatesuploadUpload session managementtransferCross-profile file transfersquickshareQuick share operationsmetadataMetadata operations\n\nCommon Event Names\n\nFile operations (workspace): workspace_storage_file_added, workspace_storage_file_deleted, workspace_storage_file_moved, workspace_storage_file_copied, workspace_storage_file_updated, workspace_storage_file_restored, workspace_storage_folder_created, workspace_storage_folder_deleted, workspace_storage_folder_moved, workspace_storage_download_token_created, workspace_storage_zip_downloaded, workspace_storage_file_version_restored, workspace_storage_link_added\n\nFile operations (share): share_storage_file_added, share_storage_file_deleted, share_storage_file_moved, share_storage_file_copied, share_storage_file_updated, share_storage_file_restored, share_storage_folder_created, share_storage_folder_deleted, share_storage_folder_moved, share_storage_download_token_created, share_storage_zip_downloaded\n\nComments: comment_created, comment_updated, comment_deleted, comment_mentioned, comment_replied, comment_reaction\n\nMembership: added_member_to_org, added_member_to_workspace, added_member_to_share, removed_member_from_org, removed_member_from_workspace, removed_member_from_share, membership_updated\n\nWorkspace lifecycle: workspace_created, workspace_updated, workspace_deleted, workspace_archived, workspace_unarchived\n\nShare lifecycle: share_created, share_updated, share_deleted, share_archived, share_unarchived, share_imported_to_workspace\n\nAI: ai_chat_created, ai_chat_new_message, ai_chat_updated, ai_chat_deleted, ai_chat_published, node_ai_summary_created, workspace_ai_share_created\n\nMetadata: metadata_kv_update, metadata_kv_delete, metadata_kv_extract, metadata_template_update, metadata_template_delete, metadata_template_settings_update, metadata_view_update, metadata_view_delete, metadata_template_select\n\nQuick shares: workspace_quickshare_created, workspace_quickshare_updated, workspace_quickshare_deleted, workspace_quickshare_file_downloaded, workspace_quickshare_file_previewed\n\nInvitations: invitation_email_sent, invitation_accepted, invitation_declined\n\nUser: user_created, user_updated, user_deleted, user_email_reset, user_asset_updated\n\nOrg: org_created, org_updated, org_closed, org_transfer_token_created, org_transfer_completed\n\nBilling: subscription_created, subscription_cancelled, billing_free_trial_ended\n\nExample Queries\n\nRecent comments in a workspace: event action search with workspace_id and subcategory: \"comments\"\nFiles uploaded to a share: event action search with share_id and event: \"share_storage_file_added\"\nAll membership changes across an org: event action search with org_id and subcategory: \"members\"\nAI activity in a workspace: event action search with workspace_id and category: \"ai\"\nWho downloaded files from a share: event action search with share_id and event: \"share_storage_download_token_created\""
      },
      {
        "title": "Activity Polling",
        "body": "Three mechanisms for detecting changes, listed from most to least preferred:\n\nevent action activity-poll — The server holds the connection for up to 95 seconds and returns immediately when something changes. Returns activity keys (e.g. ai_chat:{chatId}, storage, members) and a lastactivity timestamp for the next poll. Use this for any \"wait for something to happen\" scenario, including AI chat completion.\nWebSocket — For real-time push events. Best for live UIs.\nevent action activity-list — Retrieves recent activity events on demand. Use when you need a one-time snapshot rather than continuous monitoring.\n\nWhy this matters: Do not poll detail endpoints (like ai action message-read) in tight loops. Instead, use event action activity-poll to detect when something has changed, then fetch the details once.\n\nAI Message Completion\n\nai action message-read (with context_type: \"workspace\" or \"share\") implements built-in polling (up to 15 attempts, 2-second intervals). If the response is still processing after that window, use event action activity-poll with the workspace or share ID instead of calling the read action in a loop:\n\nCall event action activity-poll with entity_id set to the workspace/share ID.\nWhen the response includes an ai_chat:{chatId} key matching your chat, call ai action message-read once to get the completed response.\n\nActivity Poll Workflow\n\nMake an API call (e.g. ai action chat-create) and note the server_date field in the response.\nCall event action activity-poll with entity_id (workspace or share ID) and lastactivity set to the server_date value.\nThe server holds the connection. When something changes (or the wait period expires), it returns activity keys.\nInspect the keys to determine what changed, then fetch the relevant detail (e.g. ai action message-read, storage action list).\nUse the new lastactivity value from the poll response (or the latest server_date) for the next poll call. Repeat as needed."
      },
      {
        "title": "Trash, Delete, and Purge",
        "body": "storage action delete (with context_type: \"workspace\" or \"share\") moves items to the trash. They are recoverable.\nstorage action restore recovers items from the trash.\nstorage action purge permanently and irreversibly deletes items from the trash.\n\nAlways confirm with the user before calling purge operations."
      },
      {
        "title": "Node Types",
        "body": "Storage nodes can be files, folders, notes, or links. The type is indicated in the storage details response. Notes are markdown files created with workspace action create-note, read with workspace action read-note, and updated with workspace action update-note. Links are share reference nodes created with storage action add-link."
      },
      {
        "title": "Text Content and Newlines",
        "body": "All text content (notes, comments, worklogs, file uploads, descriptions) must use Unix-style line feeds (\\n, U+000A) for newlines. The frontend normalizes all line endings to \\n before saving -- Windows-style \\r\\n (CRLF) and legacy Mac \\r (CR) are converted automatically. Agents should use \\n exclusively to avoid mismatches in content comparison and display.\n\nEncoding rules:\n\nNewlines: Use \\n (U+000A). Never send \\r\\n or \\r alone.\nAllowed control characters: Only \\t (U+0009), \\n (U+000A), and \\r (U+000D) survive server-side sanitization. All other Unicode control characters (\\p{C}) are stripped.\nEmpty lines in markdown: Use two consecutive \\n characters (\\n\\n) for paragraph breaks. Do not use non-breaking spaces (U+00A0) or other whitespace characters as line placeholders.\nTrailing newlines: Content may or may not end with a trailing \\n. Do not assume either convention -- both are valid.\n\nThis applies to: workspace actions create-note and update-note, upload action text-file, comment action add, worklog actions append and interject, and any other tool that accepts free-text or markdown content."
      },
      {
        "title": "Error Pattern",
        "body": "Failed API calls throw errors with two fields: code (unique numeric error ID) and text (human-readable description). Tools surface these as error text in the MCP response. Common HTTP status codes include 401 (unauthorized), 403 (forbidden), 404 (not found), and 429 (rate limited)."
      },
      {
        "title": "Session State",
        "body": "The auth token, user ID, email, and token expiry are persisted in the server session. There is no need to pass tokens between tool calls. The session survives across multiple tool invocations within the same MCP connection."
      },
      {
        "title": "Human-Facing URLs",
        "body": "MCP tools manage data via the API, but humans access Fast.io through a web browser. Always use the web_url field from tool responses -- it is a ready-to-use, clickable URL for the resource. Include it in your responses whenever you create or reference a workspace, share, file, note, or transfer. The human cannot see API responses directly -- the URL you provide is how they get to their content. Fall back to the URL patterns below only when web_url is absent (e.g., share-context storage operations):\n\nAutomatic web_url field. All entity-returning tool responses include a web_url field — a ready-to-use, human-friendly URL for the resource. NEVER construct URLs manually — always use the web_url field from tool responses. It appears on: org list/details/create/update/public-details/discover-*, org list-workspaces/list-shares, workspace list/details/update/available/list-shares, share list/details/create/update/public-details/available, storage list/details/search/trash-list/copy/move/rename/restore/add-file/create-folder/version-list/version-restore/preview-url/preview-transform, quickshare create/get/list, upload text-file/finalize, download file-url/quickshare-details, AI chat-create/chat-details/chat-list, transfer-token create/list, and notes create/update. Fall back to the URL patterns below only when web_url is absent (e.g., share context storage operations).\n\nOrganization domain values become subdomains: \"acme\" → https://acme.fast.io/. The base domain go.fast.io handles public routes that do not require org context.\n\nAuthenticated Links (require login)\n\nWhat the human needsURL patternWorkspace roothttps://{domain}.fast.io/workspace/{folder_name}/storage/rootSpecific folderhttps://{domain}.fast.io/workspace/{folder_name}/storage/{node_id}File previewhttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}File with specific commenthttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?comment={comment_id}File at video/audio timehttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?t={seconds}File at PDF pagehttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?p={page_num}AI chat in workspacehttps://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}Note in workspacehttps://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}Note previewhttps://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}Browse workspaceshttps://{domain}.fast.io/browse-workspacesEdit share settingshttps://{domain}.fast.io/workspace/{folder_name}/share/{custom_name}Org settingshttps://{domain}.fast.io/settingsBillinghttps://{domain}.fast.io/settings/billing\n\nPublic Links (no login required)\n\nWhat the human needsURL patternPublic sharehttps://go.fast.io/shared/{custom_name}/{title-slug}Org-branded sharehttps://{domain}.fast.io/shared/{custom_name}/{title-slug}File in sharehttps://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}File in share with commenthttps://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}?comment={comment_id}QuickSharehttps://go.fast.io/quickshare/{quickshare_id}Claim org transferhttps://go.fast.io/claim?token={transfer_token}Onboardinghttps://go.fast.io/onboarding or https://go.fast.io/onboarding?orgId={org_id}&orgDomain={domain}\n\nWhere the values come from\n\nValueAPI sourcedomainorg action create or details responsefolder_nameorg action create-workspace or workspace action details responsenode_idstorage action list, create-folder, or add-file responsecustom_nameshare action create or details response (the {title-slug} is cosmetic -- the share resolves on custom_name alone)quickshare_idworkspace action quickshare-create responsetransfer_tokenorg action transfer-token-create responsechat_idai action chat-create or chat-list responsenote_idworkspace action create-note or storage action list response (node opaque ID)comment_idcomment action add or list responseorg_idorg action create or list response\n\nAlways provide URLs to the human in these situations:\n\nCreated a workspace? Include the workspace URL in your response. Example: https://acme.fast.io/workspace/q4-reports/storage/root\nCreated or configured a share? Include the share URL. Example: https://go.fast.io/shared/q4-financials/Q4-Financial-Report -- this is the branded page the human (or their recipients) will open.\nGenerated a transfer token? Include the claim URL. Example: https://go.fast.io/claim?token=abc123 -- this is the only way the human can claim ownership.\nUploaded files or created folders? Include the workspace URL pointing to the relevant folder so the human can see what you built.\nHuman asks \"where can I see this?\" Construct the URL from API response data you already have and provide it.\n\nImportant: The domain is the org's domain string (e.g. acme), not the numeric org ID. The folder_name is the workspace's folder name string (e.g. q4-reports), not the numeric workspace ID. Both are returned by their respective API tools."
      },
      {
        "title": "Response Hints (_next, _warnings, and _recovery)",
        "body": "Workflow-critical tool responses include a _next field -- a short array of suggested next actions using exact tool and action names. Use these hints to guide your workflow instead of guessing what to do next. Example:\n\n{\n  \"workspace_id\": \"...\",\n  \"web_url\": \"https://acme.fast.io/workspace/q4-reports/storage/root\",\n  \"_next\": [\n    \"Upload files: upload action text-file or web-import\",\n    \"Create a share: share action create\",\n    \"Query with AI: ai action chat-create\"\n  ]\n}\n\n_warnings appear on destructive, irreversible, or potentially problematic actions. Always read warnings before proceeding -- they flag permanent consequences or important caveats. Actions with _warnings: storage purge, storage bulk copy/move/delete/restore (partial failures), workspace details (intelligence=false), workspace update (intelligence=false), workspace archive/delete, org close, org billing-create, share delete, share archive, share update (type change), ai chat-delete, download file-url (token expiry), download zip-url (auth required), upload stage-blob (5-min expiry), org transfer-token-create.\n\n_recovery hints appear on error responses (when isError: true). They provide recovery actions based on HTTP status codes AND error message pattern matching. Error messages also include action context (e.g., \"during: org create\") to help pinpoint the failing operation.\n\nHTTP StatusRecovery400Check required parameters and ID formats401Re-authenticate: auth action signin or pkce-login402Credits exhausted -- check balance: org action limits403Permission denied -- check role: org action details404Resource not found -- verify the ID, use list actions to discover valid IDs409Conflict -- resource may already exist413Request too large -- reduce file/chunk size422Validation error -- check field formats and constraints429Rate limited -- wait 2-4s and retry with exponential backoff500/503Server error -- retry after 2-5 seconds\n\nPattern-based recovery: error messages are also matched against common patterns (e.g., \"email not verified\", \"workspace not found\", \"intelligence disabled\") to provide specific recovery steps even when the HTTP status is generic.\n\nai_capabilities is included in workspace details responses. It shows which AI modes are available based on the workspace intelligence setting:\n\nIntelligence ON: files_scope, folders_scope, files_attach (full RAG with indexed document search)\nIntelligence OFF: files_attach only (max 20 files, 200 MB, no RAG indexing)\n\n_ai_state_legend is included in storage list and search responses when files have AI indexing state. States: ready (indexed, queryable), pending (queued), inprogress (indexing), disabled (intelligence off), failed (re-upload needed). Also includes _attach_field explaining the ai.attach boolean — check this flag before using files_attach.\n\n_context provides contextual metadata on specific responses. Currently used by comment add when anchoring is involved, providing anchor_formats with the expected format for image regions, video/audio timestamps, and PDF pages.\n\nAll tool actions now include _next hints. Every successful tool response includes contextual next-step suggestions. Key workflow transitions: auth → org list/create, org create → workspace create, workspace create → upload/share/AI, upload → AI chat/comment/download, share create → add files/members, AI chat create → message read. The hints include the exact tool name, action, and relevant IDs from the current response.\n\nTool annotations: Tools include MCP annotation hints -- readOnlyHint, destructiveHint, idempotentHint (download, event), and openWorldHint (org, user, workspace, share, storage) -- to help clients understand tool behavior without documentation.\n\nResource completion and listing: The workspace and share download resource templates support both dynamic listing (resources/list) and tab-completion (completion/complete). Dynamic listing shows root-level files across workspaces and shares in the client's resource picker. Tab-completion suggests valid workspace and share IDs as you type."
      },
      {
        "title": "Unauthenticated Tools",
        "body": "The following actions work without a session: auth actions signin, signup, set-api-key, pkce-login, email-check, password-reset-request, password-reset; and download action quickshare-details."
      },
      {
        "title": "8. MCP Apps (Interactive UI Widgets)",
        "body": "Fast.io MCP Server includes interactive HTML5 widgets that render rich UIs directly in agent conversations. Widgets communicate with the MCP server through tool calls and display file browsers, dashboards, workflow managers, and more."
      },
      {
        "title": "Available Widgets",
        "body": "WidgetResource URIDescriptionFile Pickerwidget://file-pickerBrowse and pick files to attach to your conversation — navigate folders, search, preview, select files for the agent. Also supports file management (upload, move, copy, delete) in workspace and share contextsWorkspace Pickerwidget://workspace-pickerOrg/workspace/share selection with search, 4-step workspace creation wizard, 5-step share creation wizardFile Viewerwidget://file-viewerUnified file preview (image, PDF, video, audio, code, spreadsheet) with info panel (details, versions, AI summary, metadata)Workflow Managerwidget://workflowTask board, task detail, approvals panel, todos checklist, worklog viewerComments Panelwidget://commentsThreaded comments, reactions, anchored comments (image regions, timestamps)Uploaderwidget://uploaderUpload files to a workspace or share with drag-and-drop, chunked binary uploads, single-step text file creation, and web URL imports with real-time progress tracking"
      },
      {
        "title": "Uploader Widget",
        "body": "The Uploader widget provides a 4-step file upload flow:\n\nChoose destination -- select an organization, then a workspace or share, then optionally navigate to a subfolder\nSelect files -- drag-and-drop files onto the widget or use the file picker button to browse local files\nUpload with progress -- files upload automatically with real-time progress bars. Binary files use chunked uploads (create-session, stage-blob, chunk, finalize). Text files use single-step text-file upload. Web URLs use web-import\nReference in chat -- after upload completes, click \"Reference in Chat\" to attach the uploaded files to the agent conversation for further discussion or AI analysis\n\nThe widget uses the upload tool (actions: create-session, chunk, finalize, stage-blob, text-file, web-import, status, cancel, limits, extensions) and the storage tool (action: list) via the MCP bridge.\n\nLaunch via prompt: Use the App: Upload Files prompt in desktop MCP clients.\n\nLaunch via tool:\n\napps action launch app_id uploader context_type workspace context_id <workspace_id>"
      },
      {
        "title": "Using the Apps Tool",
        "body": "The apps tool provides widget discovery and launching:\n\nList apps: apps action list -- returns all available widgets with metadata\nApp details: apps action details with app_id -- full metadata for a specific widget\nLaunch app: apps action launch with app_id, context_type, context_id -- opens widget with context\nFind apps for a tool: apps action get-tool-apps with tool_name -- maps tools to their widgets"
      },
      {
        "title": "Widget Context",
        "body": "All widgets accept workspace or share context:\n\ncontext_type: \"workspace\" + context_id: \"<workspace_id>\"\ncontext_type: \"share\" + context_id: \"<share_id>\""
      },
      {
        "title": "Design System",
        "body": "Widgets use a shared design system matching the Fast.io frontend:\n\nLight and dark mode support (follows system preference or explicit data-theme attribute)\nConsistent typography, spacing, colors, and icons derived from the frontend theme\nResponsive layout (desktop, tablet, mobile breakpoints)"
      },
      {
        "title": "Example: Launch File Picker",
        "body": "apps action launch app_id file-picker context_type workspace context_id <workspace_id>"
      },
      {
        "title": "Example: Find Widgets for Storage Operations",
        "body": "apps action get-tool-apps tool_name storage"
      },
      {
        "title": "9. Complete Tool Reference",
        "body": "All 19 tools with their actions organized by functional area. Each entry shows the action name and its description. Workflow tools (task, worklog, approval, todo) require workflow to be enabled on the target workspace or share."
      },
      {
        "title": "auth",
        "body": "signin -- Sign in to Fast.io with email and password. Returns a JWT auth token. If the account has 2FA enabled the token will have limited scope until 2fa-verify is called. The token is stored in the session automatically.\n\nset-api-key -- Authenticate using a Fast.io API key. API keys work as Bearer tokens and by default have the same permissions as the account owner. Scoped keys restrict access to specific entities (same scope system as OAuth tokens). The key is validated against the API and stored in the session. All subsequent tool calls are authenticated automatically. Unscoped API keys do not expire unless revoked; scoped keys may have an optional expiration.\n\nsignup -- Create a new Fast.io agent account (agent=true), then automatically sign in. Sets account_type to \"agent\" and assigns the free agent plan. Email verification is required after signup -- call email-verify to send a code, then call it again with the code to verify. Most endpoints require a verified email. No authentication required for signup itself.\n\ncheck -- Check whether the current session token is still valid. Returns the user ID associated with the token.\n\nsession -- Get current session information for the authenticated user, including profile details such as name, email, and account flags.\n\nsignout -- Sign out by clearing the stored session. If currently authenticated the token is verified first.\n\n2fa-verify -- Complete two-factor authentication by submitting a 2FA code. Call this after signin returns two_factor_required: true. The new full-scope token is stored automatically.\n\nemail-check -- Check if an email address is available for registration. No authentication required.\n\npassword-reset-request -- Request a password reset email. Always returns success for security (does not reveal whether the email exists). No authentication required.\n\npassword-reset -- Set a new password using a reset code received by email. No authentication required.\n\nemail-verify -- Send or validate an email verification code. When email_token is omitted a new code is sent. When provided the code is validated and the email marked as verified.\n\nstatus -- Check local session status. No API call is made. Returns whether the user is authenticated, and if so their user_id, email, token expiry, scopes (raw string), scopes_detail (hydrated array with entity names, domains, and parent hierarchy -- or null if not yet fetched), and agent_name (if set).\n\npkce-login -- Start a browser-based PKCE login flow. Returns a URL for the user to open in their browser. After signing in and approving access, the browser displays an authorization code. The user copies the code and provides it to pkce-complete to finish signing in. No password is sent through the agent. Optional params: scope_type (default \"user\" for full access; use \"org\", \"workspace\", \"all_orgs\", \"all_workspaces\", or \"all_shares\" for scoped access), agent_name (displayed in the approval screen and audit logs; defaults to MCP client name).\n\npkce-complete -- Complete a PKCE login flow by exchanging the authorization code for an access token. Call this after the user has approved access in the browser and copied the code from the screen. The token is stored in the session automatically. If scoped access was granted, the response includes scopes (JSON array of granted scope strings like \"org:123:rw\") and agent_name.\n\napi-key-create -- Create a new persistent API key. The full key value is only returned once at creation time -- store it securely. Optional parameters: name (memo/label), scopes (JSON array of scope strings like [\"org:123:rw\", \"workspace:456:r\"] for restricted access -- omit for full access), agent_name (agent/application name, max 128 chars), key_expires (ISO 8601 expiration datetime -- omit for no expiration), token (2FA code -- required when account has 2FA enabled, not needed with API key auth). Scoped keys use the same scope system as v2.0 JWT tokens.\n\napi-key-update -- Update an existing API key's metadata. Requires key_id. Optional parameters: name (memo/label), scopes (JSON scope array -- send empty string to clear and restore full access), agent_name (send empty string to clear), key_expires (send empty string to clear expiration). Only specified fields are updated.\n\napi-key-list -- List all API keys for the authenticated user. Key values are masked (only last 4 characters visible). Responses include scopes, agent_name, and expires fields for each key.\n\napi-key-get -- Get details of a specific API key. The key value is masked. Response includes scopes, agent_name, and expires fields.\n\napi-key-delete -- Revoke (delete) an API key. This action cannot be undone. Optional parameter: token (2FA code -- required when account has 2FA enabled, not needed with API key auth).\n\n2fa-status -- Get the current two-factor authentication configuration status (enabled, unverified, or disabled).\n\n2fa-enable -- Enable two-factor authentication on the specified channel. For TOTP, returns a binding URI for QR code display. The account enters an 'unverified' state until 2fa-verify-setup is called.\n\n2fa-disable -- Disable (remove) two-factor authentication from the account. Requires a valid 2FA code to confirm when 2FA is in the enabled (verified) state.\n\n2fa-send -- Send a 2FA verification code to the user's phone via SMS, voice call, or WhatsApp.\n\n2fa-verify-setup -- Verify a 2FA setup code to confirm enrollment. Transitions 2FA from the 'unverified' state to 'enabled'.\n\noauth-list -- List all active OAuth sessions for the authenticated user.\n\noauth-details -- Get details of a specific OAuth session.\n\noauth-revoke -- Revoke a specific OAuth session (log out that device).\n\noauth-revoke-all -- Revoke all OAuth sessions. Optionally exclude the current session to enable 'log out everywhere else'."
      },
      {
        "title": "user",
        "body": "me -- Get the current authenticated user's profile details.\n\nupdate -- Update the current user's profile (name, email, etc.).\n\nsearch -- Search for users by name or email address.\n\nclose -- Close/delete the current user account (requires email confirmation).\n\ndetails-by-id -- Get another user's public profile details by their user ID.\n\nprofiles -- Check what profile types (orgs, workspaces, shares) the user has access to.\n\nallowed -- Check if the user's country allows creating shares and organizations.\n\norg-limits -- Get free org creation eligibility, limits, and cooldown status.\n\nlist-shares -- List all shares the current user is a member of.\n\ninvitation-list -- List all pending invitations for the current user.\n\ninvitation-details -- Get details of a specific invitation by its ID or key.\n\naccept-all-invitations -- Accept all pending invitations at once.\n\nasset-upload -- Upload a user asset (e.g. profile photo). Provide either plain-text content or base64-encoded content_base64 (not both).\n\nasset-delete -- Delete a user asset (e.g. profile photo).\n\nasset-types -- List available asset types for users.\n\nasset-list -- List all user assets."
      },
      {
        "title": "org",
        "body": "list -- List internal organizations (orgs the user is a direct member of, member: true). Each org includes web_url. Returns member orgs with subscription status, user permission, and plan info. Non-admin members only see orgs with active subscriptions. Does not include external orgs -- use discover-external for those.\n\ndetails -- Get detailed information about an organization. Returns web_url. Fields returned vary by the caller's role: owners see encryption keys and storage config, admins see billing and permissions, members see basic info.\n\nmembers -- List all members of an organization with their IDs, emails, names, and permission levels.\n\ninvite-member -- Invite a user to the organization by email. The email is passed in the URL path (not the body). If the user already has a Fast.io account they are added directly; otherwise an email invitation is sent. Cannot add as owner.\n\nremove-member -- Remove a member from the organization. Requires member management permission as configured by the org's perm_member_manage setting.\n\nupdate-member-role -- Update a member's role/permissions in the organization. Cannot set role to 'owner' -- use transfer-ownership instead.\n\nlimits -- Get organization plan limits and credit usage. Returns credit limits, usage stats, billing period, trial info, and run-rate projections. Requires admin or owner role.\n\nlist-workspaces -- List workspaces in an organization that the current user can access. Each workspace includes web_url. Owners and admins see all workspaces; members see workspaces matching the join permission setting.\n\nlist-shares -- List shares accessible to the current user. Each share includes web_url. Returns all shares including parent org and workspace info. Use parent_org in the response to identify shares belonging to a specific organization.\n\ncreate -- Create a new organization on the \"agent\" billing plan. Requires domain (2-63 chars, lowercase alphanumeric + hyphens) and name (3-100 chars, no control characters). The authenticated user becomes the owner. A storage instance and agent-plan subscription (free, 50 GB, 5,000 credits/month) are created automatically. Returns the new org and trial status.\n\nupdate -- Update organization details. Returns web_url. Only provided fields are changed. Supports identity, branding, social links, permissions, and billing email. Requires admin or owner role.\n\nclose -- Close/delete an organization. Cancels any active subscription and initiates deletion. Requires owner role. The confirm field must match the org domain or org ID.\n\npublic-details -- Get public details for an organization. Returns web_url. Does not require membership -- returns public-level fields only (name, domain, logo, accent color). The org must exist and not be closed/suspended.\n\ncreate-workspace -- Create a new workspace within the organization. Returns web_url. Checks workspace feature availability and creation limits based on the org billing plan. The creating user becomes the workspace owner. Namespace: Workspace folder_name is globally unique across the platform. If the requested name is already taken and does not contain a dash, the server automatically prefixes it with the org ID (e.g. reports → 3587676312889739297-reports). Names with dashes are sent as-is. The final folder_name is returned in the response.\n\nbilling-plans -- List available billing plans with pricing, features, and plan defaults. Returns plan IDs needed for subscription creation.\n\nbilling-create -- Create a new subscription or update an existing one. For new subscriptions, creates a Stripe Setup Intent. For existing subscriptions, updates the plan. Requires admin or owner.\n\nbilling-cancel -- Cancel the organization's subscription. Requires owner role. Some plans may cause the org to be closed on cancellation.\n\nbilling-details -- Get comprehensive billing and subscription details including Stripe customer info, subscription status, setup intents, payment intents, and plan info. Requires admin or owner.\n\nbilling-activate -- Activate a billing plan (development environment only). Simulates Stripe payment setup and activates the subscription using a test payment method.\n\nbilling-reset -- Reset billing status (development environment only). Deletes the Stripe customer and removes the subscriber flag.\n\nbilling-members -- List billable members with their workspace memberships. Shows who the org is being billed for. Requires admin or owner role.\n\nbilling-meters -- Get usage meter time-series data (storage, transfer, AI, etc). Returns grouped data points with cost and credit calculations. Requires admin or owner role.\n\nleave -- Leave an organization. Removes the current user's own membership. Owners cannot leave -- they must transfer ownership or close the org first.\n\nmember-details -- Get detailed membership information for a specific user in the organization, including permissions, invite status, notification preference, and expiration.\n\ntransfer-ownership -- Transfer organization ownership to another member. The current owner is demoted to admin. Requires owner role.\n\ntransfer-token-create -- Create a transfer token (valid 72 hours) for an organization. Send the claim URL https://go.fast.io/claim?token=<token> to a human. Use when handing off an org or when hitting 402 Payment Required on the agent plan. Requires owner role.\n\ntransfer-token-list -- List all active transfer tokens for an organization. Each token includes web_url (claim URL). Requires owner role.\n\ntransfer-token-delete -- Delete (revoke) a pending transfer token. Requires owner role.\n\ntransfer-claim -- Claim an organization using a transfer token. The authenticated user becomes the new owner and the previous owner is demoted to admin.\n\ninvitations-list -- List all pending invitations for the organization. Optionally filter by invitation state. Requires any org membership.\n\ninvitation-update -- Update an existing invitation for the organization. Can change state, permissions, or expiration.\n\ninvitation-delete -- Revoke/delete an invitation for the organization.\n\njoin -- Join an organization via invitation or authorized domain auto-join. Optionally provide an invitation key and action (accept/decline).\n\nasset-upload -- Upload an org asset (e.g. logo, banner). Provide either plain-text content or base64-encoded file_base64 (not both). Requires admin or owner role.\n\nasset-delete -- Delete an asset from the organization. Requires admin or owner role.\n\nasset-types -- List available asset types for organizations.\n\nasset-list -- List all organization assets.\n\ndiscover-all -- List all accessible organizations (joined + invited). Each org includes web_url. Returns org data with user_status indicating relationship.\n\ndiscover-available -- List organizations available to join. Each org includes web_url. Excludes orgs the user is already a member of.\n\ndiscover-check-domain -- Check if an organization domain name is available for use. Validates format, checks reserved names, and checks existing domains.\n\ndiscover-external -- List external organizations (member: false). Each org includes web_url. Orgs the user can access only through workspace membership, not as a direct org member. Common when a human invites an agent to a workspace without inviting them to the org. See Internal vs External Orgs in the Organizations section."
      },
      {
        "title": "workspace",
        "body": "list -- List all workspaces the user has access to across all organizations. Each workspace includes web_url.\n\ndetails -- Get detailed information about a specific workspace. Returns web_url.\n\nupdate -- Update workspace settings such as name, description, branding, and permissions. Returns web_url.\n\ndelete -- Permanently close (soft-delete) a workspace. Requires Owner permission and confirmation.\n\narchive -- Archive a workspace (blocks modifications, preserves data). Requires Admin+.\n\nunarchive -- Restore an archived workspace to active status. Requires Admin+.\n\nmembers -- List all members of a workspace with their roles and status.\n\nlist-shares -- List all shares within a workspace, optionally filtered by archive status. Each share includes web_url.\n\nimport-share -- Import a user-owned share into a workspace. You must be the sole owner of the share.\n\navailable -- List workspaces the current user can join but has not yet joined. Each workspace includes web_url.\n\ncheck-name -- Check if a workspace folder name is available for use. Workspace names are globally unique. Pass optional check_org_id to get an org-ID-prefixed alternative suggestion (e.g. 3587676312889739297-reports) if the name is taken.\n\ncreate-note -- Create a new markdown note in workspace storage. Returns web_url (note preview link).\n\nupdate-note -- Update a note's markdown content and/or name (at least one required). Returns web_url (note preview link).\n\nread-note -- Read a note's markdown content and metadata. Returns the note content and web_url (note preview link).\n\nquickshare-get -- Get existing quickshare details for a node. Returns web_url.\n\nquickshare-delete -- Revoke and delete a quickshare link for a node.\n\nquickshares-list -- List all active quickshares in the workspace. Each quickshare includes web_url.\n\nmetadata-template-create -- Create a new metadata template in the workspace. Requires name, description, category (legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr), and fields (JSON-encoded array of field definitions). Each field has name, description, type (string, int, float, bool, json, url, datetime), and optional constraints (min, max, default, fixed_list, can_be_null).\n\nmetadata-template-delete -- Delete a metadata template. System templates and locked templates cannot be deleted. Requires template_id.\n\nmetadata-template-list -- List metadata templates. Optional template_filter: enabled, disabled, custom (non-system), or system. Returns all non-deleted templates when no filter is specified.\n\nmetadata-template-details -- Get full details of a metadata template including all field definitions. Requires template_id.\n\nmetadata-template-update -- Update an existing metadata template. Any combination of name, description, category, and fields can be updated. Requires template_id.\n\nmetadata-template-clone -- Clone a metadata template with optional modifications. Creates a new template based on an existing one. Same parameters as metadata-template-update. Requires template_id.\n\nmetadata-template-assign -- Assign a metadata template to a workspace. Each workspace can have at most one assigned template. Assigning a system template automatically clones it. Requires template_id. Optional node_id (null for workspace-level assignment).\n\nmetadata-template-unassign -- Remove the template assignment from a workspace. Requires workspace admin permission.\n\nmetadata-template-resolve -- Resolve which metadata template applies to a given node. Returns the workspace-level template (node_id is accepted but currently inherits from workspace). Returns null if no template is assigned.\n\nmetadata-template-assignments -- List all template assignments in the workspace.\n\nmetadata-get -- Get all metadata for a file, including both template-conforming metadata and custom (freeform) key-value pairs. Returns node details, template_id, template_metadata array, and custom_metadata array. Requires node_id.\n\nmetadata-set -- Set or update metadata key-value pairs on a file. Values must conform to the template field definitions. Requires node_id, template_id, and key_values (JSON object of key-value pairs).\n\nmetadata-delete -- Delete metadata from a file. Provide keys (JSON array of key names) to delete specific entries, or omit to delete all metadata. Only works on files and notes, not folders. Requires node_id.\n\nmetadata-extract -- Trigger AI-powered metadata extraction from a file. The AI analyzes file content and populates metadata fields according to the template. Extracted values are marked with is_auto: true. Consumes AI credits. Optional template_id (defaults to workspace template). Requires node_id.\n\nmetadata-list-files -- List files that have metadata for a specific template, with optional filtering and sorting. Requires node_id (folder to search in) and template_id. Optional metadata_filters (JSON-encoded), order_by (field key), and order_desc.\n\nmetadata-list-templates-in-use -- List which metadata templates are in use within a folder, with usage counts per template. Requires node_id.\n\nmetadata-versions -- Get metadata version history for a file. Returns snapshots of metadata changes over time. Requires node_id.\n\nenable-workflow -- Enable workflow features (tasks, worklogs, approvals, todos) on a workspace. Must be called before using workflow tools on the workspace.\n\ndisable-workflow -- Disable workflow features on a workspace. All workflow data is preserved but inaccessible until re-enabled."
      },
      {
        "title": "share",
        "body": "list -- List shares the authenticated user has access to. Each share includes web_url.\n\ndetails -- Get full details of a specific share. Returns web_url.\n\ncreate -- Create a new share in a workspace.\n\nupdate -- Update share settings (partial update).\n\ndelete -- Delete (close) a share. Requires the share ID or custom name as confirmation.\n\npublic-details -- Get public-facing share info (no membership required, just auth).\n\narchive -- Archive a share. Blocks guest access and restricts modifications.\n\nunarchive -- Restore a previously archived share to active status.\n\npassword-auth -- Authenticate with a share password. Returns a scoped JWT for the share.\n\nmembers -- List all members of a share.\n\navailable -- List shares available to join (joined and owned, excludes pending invitations). Each share includes web_url.\n\ncheck-name -- Check if a share custom name (URL name) is available.\n\nquickshare-create -- Create a temporary QuickShare link for a file in a workspace. Optional expires (seconds, default 10,800, max 604,800 = 7 days) or expires_at (ISO 8601 datetime).\n\nenable-workflow -- Enable workflow features (tasks, worklogs, approvals, todos) on a share. Must be called before using workflow tools on the share.\n\ndisable-workflow -- Disable workflow features on a share. All workflow data is preserved but inaccessible until re-enabled."
      },
      {
        "title": "storage",
        "body": "All storage actions require context_type parameter (workspace or share) and context_id (the 19-digit profile ID).\n\nlist -- List files and folders in a directory with pagination. Each item includes web_url (workspace only). Requires context_type, context_id, and node_id (use root for root folder).\n\nrecent -- List recently modified files and folders across all directories, sorted by updated descending. Unlike list which is scoped to a single folder, this returns nodes from the entire storage tree. Supports optional type filter (file, folder, link, note), page_size (100, 250, or 500), and cursor for pagination. For workspace folder shares, results are automatically filtered to the share's subtree.\n\ndetails -- Get full details of a specific file or folder. Returns web_url (human-friendly link to the file preview or folder in the web UI, workspace only).\n\nsearch -- Search for files by keyword or semantic query. Each result includes web_url (workspace only).\n\ntrash-list -- List items currently in the trash. Each item includes web_url (workspace only).\n\ncreate-folder -- Create a new folder. Returns web_url (workspace only).\n\ncopy -- Copy files/folders. Single copy via node_id (workspace or share). Bulk copy via node_ids array (workspace only). Returns web_url on the new copy (workspace only).\n\nmove -- Move files/folders. Single move via node_id (workspace or share). Bulk move via node_ids array (workspace only). Returns web_url (workspace only).\n\ndelete -- Delete files/folders by moving them to the trash. Single delete via node_id (workspace or share). Bulk delete via node_ids array (workspace only).\n\nrename -- Rename a file or folder. Returns web_url (workspace only).\n\npurge -- Permanently delete a trashed node (irreversible). Requires Member permission.\n\nrestore -- Restore files/folders from the trash. Single restore via node_id (workspace or share). Bulk restore via node_ids array (workspace only). Returns web_url on the restored node (workspace only).\n\nadd-file -- Link a completed upload to a storage location. Returns web_url (workspace only).\n\nadd-link -- Add a share reference link node to storage.\n\ntransfer -- Copy or move a node to another workspace or share storage instance. Default mode is 'copy' (keeps source). Use transfer_mode='move' to copy then trash the source (cannot move root). When mode=move, response includes source_trashed (boolean) indicating whether the source was successfully trashed.\n\nversion-list -- List version history for a file. Returns web_url for the file (workspace only).\n\nversion-restore -- Restore a file to a previous version. Returns web_url for the file (workspace only).\n\nlock-acquire -- Acquire an exclusive lock on a file to prevent concurrent edits.\n\nlock-status -- Check the lock status of a file.\n\nlock-release -- Release an exclusive lock on a file.\n\npreview-url -- Get a preauthorized preview URL for a file (thumbnail, PDF, image, video, audio, spreadsheet). Requires preview_type parameter. Returns preview_url (ready-to-use URL) and web_url (human-friendly link to the file in the web UI, workspace only).\n\npreview-transform -- Request a file transformation (image resize, crop, format conversion) and get a download URL for the result. Requires transform_name parameter. Returns transform_url (ready-to-use URL) and web_url (human-friendly link to the file in the web UI, workspace only)."
      },
      {
        "title": "upload",
        "body": "create-session -- Create a chunked upload session for a file.\n\nchunk -- Upload a single chunk. Use content for text/strings, data for base64-encoded binary, or blob_ref for binary staged via stage-blob action or POST /blob. Provide exactly one.\n\nfinalize -- Finalize an upload session, trigger file assembly, and poll until fully stored or failed. Returns the final session state.\n\nstatus -- Get the current status of an upload session. Supports server-side long-poll via optional wait parameter (in milliseconds, 0 = immediate).\n\ncancel -- Cancel and delete an active upload session.\n\nlist-sessions -- List all active upload sessions for the current user.\n\ncancel-all -- Cancel and delete ALL active upload sessions at once.\n\nchunk-status -- Get chunk information for an upload session.\n\nchunk-delete -- Delete/reset a chunk in an upload session.\n\nstage-blob -- Stage base64-encoded binary data as a blob for later use with the chunk action's blob_ref parameter. Pass data (base64 string). Returns { blob_id, size }. Blobs expire after 5 minutes and are consumed on first use. Alternative to passing data directly in the chunk call.\n\ntext-file -- Upload a text file in a single step using the Fast.io single-request upload pattern. Sends the file in one multipart POST and returns the new file ID directly. Use for text-based files (code, markdown, CSV, JSON, config) instead of the multi-step chunked flow.\n\nweb-import -- Import a file from an external URL into a workspace or share.\n\nweb-list -- List the user's web upload jobs with optional filtering.\n\nweb-cancel -- Cancel an active web upload job.\n\nweb-status -- Get detailed status of a specific web upload job.\n\nlimits -- Get upload size and chunk limits for the user's plan.\n\nextensions -- Get restricted and allowed file extensions for uploads."
      },
      {
        "title": "download",
        "body": "file-url -- Get a download token and URL for a file. Optionally specify a version. Requires context_type, context_id, and node_id.\n\nzip-url -- Get a ZIP download URL for a folder or entire workspace/share. Returns the URL with auth instructions. Requires context_type, context_id, and node_id (use root for entire storage tree).\n\nquickshare-details -- Get metadata and download info for a quickshare link. No authentication required."
      },
      {
        "title": "ai",
        "body": "All AI actions require context_type parameter (workspace or share) and context_id (the 19-digit profile ID).\n\nchat-create -- Create a new AI chat with an initial question. Default scope is the entire workspace (all indexed documents) — omit files_scope and folders_scope unless you need to narrow the search. When using scope or attachments, provide nodeId:versionId pairs — versionId is auto-resolved to the current version if left empty (get explicit versionId from storage list/details version field). When using files_attach, verify ai.attach is true for each file first (check via storage details). Type is auto-promoted from chat to chat_with_files when file parameters are present. Returns chat ID and initial message ID -- use message-read to get the AI response.\n\nchat-list -- List AI chats.\n\nchat-details -- Get AI chat details including full message history.\n\nchat-update -- Update the name of an AI chat.\n\nchat-delete -- Delete an AI chat.\n\nchat-publish -- Publish a private AI chat, making it visible to all members.\n\nmessage-send -- Send a follow-up message in an existing AI chat. Returns message ID -- use message-read to get the AI response.\n\nmessage-list -- List all messages in an AI chat.\n\nmessage-details -- Get details for a specific message in an AI chat including response text and citations.\n\nmessage-read -- Read an AI message response. Polls the message details endpoint until the AI response is complete, then returns the full text.\n\nsearch -- Semantic search across indexed documents and code. Returns ranked document chunks with relevance scores -- faster and lighter than AI chat (stateless GET, no LLM inference). Requires Intelligence ON. Params: query_text (2-1,000 chars), optional files_scope, folders_scope (same format as chat scoping), limit (1-500, default 100), offset. Results include content snippets, scores, and source file details with web_url (workspace only). Use search to find relevant documents, then chat to ask questions about them.\n\nshare-generate -- Generate AI Share markdown with temporary download URLs for files that can be pasted into external AI chatbots.\n\ntransactions -- List AI token usage transactions for billing tracking.\n\nautotitle -- Generate AI-powered title and description based on contents (share context only)."
      },
      {
        "title": "comment",
        "body": "All comment endpoints use the path pattern /comments/{entity_type}/{parent_id}/ or /comments/{entity_type}/{parent_id}/{node_id}/ where entity_type is workspace or share, parent_id is the 19-digit profile ID, and node_id is the file's opaque ID.\n\nlist -- List comments on a specific file (node). Params: sort (created/-created), limit (2-200), offset, include_deleted, reference_type filter, include_total.\n\nlist-all -- List all comments across a workspace or share (not node-specific). Same listing params as list.\n\nadd -- Add a comment to a specific file. Body: text (max 8,192 chars total, max 2,048 chars display text with @[...] mention tags stripped). Supports mention tags: @[profile:id], @[user:opaqueId:Name], @[file:fileId:name.ext]. Optional parent_comment_id (single-level threading, replies to replies auto-flatten), optional reference (type, timestamp, page, region, text_snippet for content anchoring; exact, prefix, suffix, start_offset, end_offset for text anchoring on markdown/notes -- use type \"document\" or \"text\"), optional linked_entity_type (task or approval) and linked_entity_id to link the comment to a workflow entity at creation time. Uses JSON body.\n\ndelete -- Delete a comment. Recursive: deleting a parent also removes all its replies.\n\nbulk-delete -- Bulk soft-delete multiple comments (max 100). NOT recursive: replies to deleted comments are preserved.\n\ndetails -- Get full details of a single comment by its ID. Response includes linked_entity_type and linked_entity_id (null when not linked).\n\nreaction-add -- Add or change your emoji reaction. One reaction per user per comment; new replaces previous.\n\nreaction-remove -- Remove your emoji reaction from a comment.\n\nlink -- Link an existing comment to a workflow entity. Params: comment_id, linked_entity_type (task or approval), linked_entity_id. One link per comment; linking replaces any existing link. Returns the updated comment with linked fields populated.\n\nunlink -- Remove the workflow link from a comment. Params: comment_id. Returns the updated comment with linked fields set to null.\n\nlinked -- Reverse lookup: find all comments linked to a given workflow entity. Params: linked_entity_type (task or approval), linked_entity_id. Returns a list of comments linked to the specified entity."
      },
      {
        "title": "event",
        "body": "search -- Search the audit/event log with filters for profile, event type, category, subcategory, event name, and date range. See Event Filtering Reference in section 7 for the full taxonomy of categories, subcategories, and event names.\n\nsummarize -- Search events and return an AI-powered natural language summary of the activity. Accepts the same category/subcategory/event filters as search.\n\ndetails -- Get full details for a single event by its ID.\n\nactivity-list -- Poll for recent activity events on a workspace or share.\n\nactivity-poll -- Long-poll for activity changes on a workspace or share. The server holds the connection until a change occurs or the wait period expires. Returns activity keys indicating what changed and a lastactivity timestamp for the next poll."
      },
      {
        "title": "member",
        "body": "All member actions require entity_type parameter (workspace or share) and entity_id (the 19-digit profile ID).\n\nadd -- Add an existing user by user ID, or invite by email. Pass the email address or user ID as email_or_user_id. For workspaces, set access level with permissions (admin/member/guest). For shares, use role (admin/member/guest/view).\n\nremove -- Remove a member (cannot remove the owner).\n\ndetails -- Get detailed membership info for a specific member. For workspaces, pass member_id; for shares, pass user_id.\n\nupdate -- Update a member's role, notifications, or expiration.\n\ntransfer-ownership -- Transfer ownership to another member (current owner is demoted to admin).\n\nleave -- Leave (remove yourself). Owner must transfer ownership first.\n\njoin -- Self-join based on organization membership.\n\njoin-invitation -- Accept or decline an invitation using an invitation key."
      },
      {
        "title": "invitation",
        "body": "All invitation actions require entity_type parameter (workspace or share) and entity_id (the 19-digit profile ID).\n\nlist -- List all pending invitations.\n\nlist-by-state -- List invitations filtered by state.\n\nupdate -- Resend or update an invitation (by ID or invitee email).\n\ndelete -- Revoke and delete a pending invitation."
      },
      {
        "title": "asset",
        "body": "All asset actions require entity_type parameter (org, workspace, share, or user) and entity_id (the 19-digit profile ID for org/workspace/share).\n\nupload -- Upload an asset (e.g. logo, banner, profile photo). Provide either plain-text content or base64-encoded data (not both).\n\ndelete -- Delete an asset.\n\ntypes -- List available asset types for the entity.\n\nlist -- List all assets for the entity.\n\nread -- Read/download an asset."
      },
      {
        "title": "task",
        "body": "Task list and task management for workspaces and shares. All task actions require workflow to be enabled on the target entity (workspace action enable-workflow or share action enable-workflow).\n\nlist-lists -- List all task lists for a workspace or share. Requires profile_type and profile_id. Supports sort_by (created, updated, name), sort_dir, limit (1-200), offset, and format (\"md\" for markdown).\n\ncreate-list -- Create a new task list. Requires profile_type, profile_id, and name (1-255 chars). Optional description (max 2000 chars).\n\nlist-details -- Get details of a specific task list. Requires list_id. Supports format.\n\nupdate-list -- Update a task list's name or description. Requires list_id. Optional name, description.\n\ndelete-list -- Soft-delete a task list and all its tasks. Requires list_id. Destructive.\n\nlist-tasks -- List tasks in a task list. Requires list_id. Supports status filter, assignee filter, sort_by (created, updated, name, priority, status), sort_dir, limit (1-200), offset, and format.\n\ncreate-task -- Create a new task in a list. Requires list_id and title (1-500 chars). Optional description (max 5000 chars), status (pending, in_progress, complete, blocked), priority (0=none, 1=low, 2=medium, 3=high, 4=critical), assignee_id (profile ID), dependencies (array of task IDs), node_id (link to file/folder/note).\n\ntask-details -- Get full details of a specific task. Requires list_id and task_id. Supports format.\n\nupdate-task -- Update a task's title, description, status, priority, assignee, dependencies, or node link. Requires list_id and task_id.\n\ndelete-task -- Soft-delete a task. Requires list_id and task_id. Destructive.\n\nchange-status -- Change a task's status. Requires list_id, task_id, and status.\n\nassign-task -- Assign or unassign a task. Requires list_id and task_id. Pass assignee_id (profile ID) to assign, or null/omit to unassign.\n\nbulk-status -- Change status on multiple tasks at once. Requires list_id, task_ids (array of task IDs, max 100), and status.\n\nmove-task -- Move a task from one list to another within the same profile. Requires list_id (source list), task_id, and target_task_list_id (destination list). Optional sort_order (position in target list, default 0). Source and target lists must belong to the same profile. Returns the updated task with old_task_list_id and new_task_list_id.\n\nreorder-tasks -- Reorder tasks within a list. Requires list_id and task_ids (array of task IDs in the desired display order). The server converts this to {order: [{id, sort_order}, ...]} for the API.\n\nreorder-lists -- Reorder task lists within a workspace or share. Requires profile_type, profile_id, and list_ids (array of task list IDs in the desired display order). The server converts this to {order: [{id, sort_order}, ...]} for the API."
      },
      {
        "title": "worklog",
        "body": "Activity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. All worklog actions require workflow to be enabled on the target entity.\n\nappend -- Append a new entry to the worklog. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id, and content (1-10000 chars). Use after making changes to record what was done and why. Entries are immutable after creation.\n\nlist -- List worklog entries. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\") and entity_id (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type \"profile\"). Supports type filter (\"entry\" or \"interjection\"), sort_dir (\"asc\" or \"desc\", default \"desc\"), limit (1-200), offset, and format (\"md\" for markdown).\n\ninterject -- Create an urgent interjection entry that requires acknowledgement. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id, and content (1-10000 chars). Interjections are priority corrections -- always treated as urgent.\n\ndetails -- Get full details of a specific worklog entry. Requires entry_id. Supports format.\n\nacknowledge -- Acknowledge an interjection entry, marking it as seen. Requires entry_id. Only entries with acknowledgable: true can be acknowledged.\n\nunacknowledged -- List unacknowledged interjections (entries where acknowledgable is true). Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\") and entity_id. Supports limit, offset, and format. Always check for unacknowledged interjections before proceeding with work."
      },
      {
        "title": "approval",
        "body": "Formal approval requests scoped to tasks, storage nodes, or worklog entries. All approval actions require workflow to be enabled on the target entity.\n\nlist -- List approval requests for a workspace or share. Requires profile_type and profile_id. Supports status filter (pending, approved, rejected), limit (1-200, default 100), offset, and format.\n\ncreate -- Create a new approval request. Requires entity_type (\"task\", \"node\", or \"worklog_entry\"), entity_id, profile_id, and description (1-5000 chars). Optional approver_id (profile ID of designated approver), deadline (ISO 8601), node_id (artifact reference).\n\ndetails -- Get full details of an approval request including approver list and resolution. Requires approval_id (opaque alphanumeric). Supports format.\n\nresolve -- Resolve an approval request. Requires approval_id and resolve_action (\"approve\" or \"reject\"). Optional comment (max 5000 chars). Only designated approvers can resolve."
      },
      {
        "title": "todo",
        "body": "Simple flat checklists scoped to workspaces and shares. No nesting. All todo actions require workflow to be enabled on the target entity.\n\nlist -- List todos for a workspace or share. Requires profile_type and profile_id. Supports filter_done (boolean), sort_by (created, updated, title), sort_dir, limit (1-200, default 50), offset, and format.\n\ncreate -- Create a new todo item. Requires profile_type, profile_id, and title (1-500 chars). Optional assignee_id.\n\ndetails -- Get full details of a todo. Requires todo_id (opaque alphanumeric). Supports format.\n\nupdate -- Update a todo. Requires todo_id. Supports title, assignee_id, done.\n\ndelete -- Soft-delete a todo. Requires todo_id. Destructive.\n\ntoggle -- Toggle the done state of a todo. Requires todo_id. Flips between done and not done.\n\nbulk-toggle -- Set done state on multiple todos at once. Requires profile_type, profile_id, todo_ids (array of todo IDs, max 100), and done (boolean: true to mark done, false to mark not done)."
      },
      {
        "title": "apps",
        "body": "Interactive MCP App widget discovery and launching. Widgets are interactive HTML5 UIs that render in agent conversations.\n\nlist -- List all available MCP App widgets with their metadata (title, description, supported tools, supported actions, resource URI).\n\ndetails -- Get full metadata for a specific widget. Requires app_id (the widget name, e.g., \"file-picker\").\n\nlaunch -- Launch a widget with workspace or share context. Requires app_id, context_type (\"workspace\" or \"share\"), and context_id (the 19-digit profile ID). Returns the widget HTML content ready for rendering.\n\nget-tool-apps -- Find widgets associated with a specific tool domain. Requires tool_name (e.g., \"storage\", \"ai\", \"comment\"). Returns widgets that provide UI for that tool's operations."
      },
      {
        "title": "10. Code Mode (Headless Agents)",
        "body": "When connecting from a headless agent (Claude Code, Cursor, Continue, etc.), the server automatically enables Code Mode -- a lightweight alternative to the full 19-tool set. Code Mode exposes 4 tools total:\n\nToolPurposeauthAuthentication (signin, signup, API keys, PKCE, 2FA)uploadFile uploads (chunked, text, web-import)searchDiscover API endpoints by keyword, tag, or conceptexecuteMake authenticated API calls to Fast.io\n\nClients with MCP Apps support (Claude Desktop, Cline) continue to receive the full 19-tool set plus 12 app-* widget tools. Unknown clients default to the full tool set."
      },
      {
        "title": "search Tool",
        "body": "Query the API spec by keywords, paths, or concepts. Returns matching endpoints with method, path, parameters, and descriptions.\n\nsearch query=\"list files in workspace\" tag=\"storage\"\nsearch query=\"create share\" tag=\"share\"\nsearch query=\"authentication\"\nsearch query=\"pagination\" include_concepts=true\n\nParameters:\n\nquery (string, required) -- Keywords, endpoint paths, or concepts to search for\ntag (string, optional) -- Filter by domain: auth, workspace, storage, ai, share, upload, org, user, member, comment, event, metadata, etc.\ninclude_concepts (boolean, optional) -- Include concept docs (pagination, IDs, errors). Default true."
      },
      {
        "title": "execute Tool",
        "body": "Make authenticated API calls to the Fast.io REST API. Use search first to discover endpoints.\n\nMethods:\n\nget -- GET request with optional query parameters\npost -- POST with form-encoded body (default API format)\npostJson -- POST with JSON body\ndelete -- DELETE request\nput -- PUT with form-encoded body\n\nThe auth token is injected automatically. Path parameters must be filled by the caller (replace {workspace_id} with the actual ID). For multi-step operations, make multiple sequential execute calls.\n\nexecute method=\"get\" path=\"/org/1234567890123456789/list/workspaces/\"\n\nexecute method=\"post\" path=\"/workspace/1234567890123456789/storage/root/createfolder/\" body={\"name\": \"reports\"}\n\nexecute method=\"postJson\" path=\"/workspace/1234567890123456789/storage/root/createnote/\" body={\"name\": \"summary.md\", \"content\": \"# Summary\"}\n\nParameters:\n\nmethod (enum, required) -- HTTP method: \"get\", \"post\", \"postJson\", \"delete\", \"put\"\npath (string, required) -- API endpoint path (e.g., '/orgs/list/', '/workspace/{workspace_id}')\nbody (object, optional) -- Request body (form-encoded for post/put, JSON for postJson)\nparams (object, optional) -- Query parameters appended to the URL\ntimeout_ms (number, optional) -- Timeout in ms (default 30000, max 60000)\n\nResponse Handling\n\nThe execute tool handles three response types automatically:\n\nJSON (most endpoints) -- parsed as standard Fast.io API envelope\nText (markdown, plain text, etc.) -- returned as { content, content_type, http_status }\nBinary (images, PDFs, etc.) -- returns metadata with guidance to use download:// MCP resource\n\nReading Notes in Code Mode\n\nUse /readnote/ (returns JSON) instead of /read/ (returns raw binary):\n\nexecute method=\"get\" path=\"/workspace/{workspace_id}/storage/{node_id}/readnote/\"\n\nFor reading uploaded files (non-notes), use the download:// MCP resource:\n\nresources/read uri=\"download://workspace/{workspace_id}/{node_id}\""
      }
    ],
    "body": "Fast.io MCP Server -- AI Agent Guide\n\nVersion: 1.123 Last Updated: 2026-03-16\n\nThe definitive guide for AI agents using the Fast.io MCP server. Covers why and how to use the platform: product capabilities, the free agent plan, authentication, core concepts (workspaces, shares, intelligence, previews, comments, URL import, metadata, workflow, ownership transfer), 12 end-to-end workflows, interactive MCP App widgets, and all 19 consolidated tools with action-based routing.\n\nVersioned guide. This guide is versioned and updated with each server release. The version number at the top of this document tracks tool parameters, ID formats, and API behavior changes. If you encounter unexpected errors, the guide version may have changed since you last read it.\n\nPlatform reference. For a comprehensive overview of Fast.io's capabilities, the agent plan, key workflows, and upgrade paths, see references/REFERENCE.md.\n\n1. Overview\n\nWorkspaces for Agentic Teams. Collaborate, share, and query with AI -- all through one API, free.\n\nFast.io provides workspaces for agentic teams -- where agents collaborate with other agents and with humans. Upload outputs, create branded shares, ask questions about documents using built-in AI, and hand everything off to a human when the job is done. No infrastructure to manage, no subscriptions to set up, no credit card required.\n\nThe Problem Fast.io Solves\n\nAgentic teams -- groups of agents working together and with humans -- need a shared place to work. Today, agents cobble together S3 buckets, presigned URLs, email attachments, and custom download pages. Every agent reinvents collaboration, and there is no shared workspace where agents and humans can see the same files, track activity, and hand off work.\n\nWhen agents need to understand documents -- not just store them -- they have to download files, parse dozens of formats, build search indexes, and manage their own RAG pipeline. That is a lot of infrastructure for what should be a simple question: \"What does this document say?\"\n\nProblem\tFast.io Solution\nNo shared workspace for agentic teams\tWorkspaces where agents and humans collaborate with file preview, versioning, and AI\nAgent-to-agent coordination lacks structure\tShared workspaces with activity feeds, comments, and real-time sync across team members\nSharing outputs with humans is awkward\tPurpose-built shares (Send, Receive, Exchange) with link sharing, passwords, expiration\nCollecting files from humans is harder\tReceive shares let humans upload directly to your workspace -- no email attachments\nUnderstanding document contents\tBuilt-in AI reads, summarizes, and answers questions about your files\nBuilding a RAG pipeline from scratch\tEnable intelligence on a workspace and documents are automatically indexed, summarized, and queryable\nFinding the right file in a large collection\tSemantic search finds documents by meaning, not just filename\nHanding a project off to a human\tOne-click ownership transfer -- human gets the org, agent keeps admin access\nTracking what happened\tFull audit trail with AI-powered activity summaries\nCost\tFree. 50 GB storage, 5,000 monthly credits, no credit card\nMCP Server\n\nThis MCP server exposes 19 consolidated tools that cover the full Fast.io REST API surface. Every authenticated API endpoint has a corresponding tool action, and the server handles session management automatically.\n\nOnce a user authenticates, the auth token is stored in the server session and automatically attached to all subsequent API calls. There is no need to pass tokens between tool invocations.\n\nServer Endpoints\nProduction: mcp.fast.io\nDevelopment: mcp.fastdev1.com\n\nTwo transports are available on each:\n\nStreamable HTTP at /mcp -- the preferred transport for new integrations.\nSSE at /sse -- a legacy transport maintained for backward compatibility.\nMCP Resources\n\nThe server exposes static MCP resources, widget resources, and file download resource templates. Clients can read them via resources/list and resources/read:\n\nURI\tName\tDescription\tMIME Type\nskill://guide\tskill-guide\tFull agent guide (this document) with all 19 tools, workflows, and platform documentation\ttext/markdown\nsession://status\tsession-status\tCurrent authentication state: authenticated boolean, user_id, user_email, token_expires_at (Unix epoch), token_expires_at_iso (ISO 8601), scopes (raw scope string or null), scopes_detail (array of hydrated scope objects with entity names/domains/parents, or null), agent_name (string or null)\tapplication/json\nwidget://*\tWidget HTML\tInteractive HTML5 widgets (6 total) -- use the apps tool to discover and launch\ttext/html\n\nFile download resource templates -- read file content directly through MCP without needing external HTTP access:\n\nURI Template\tName\tAuth\tDynamic Listing\tDescription\ndownload://workspace/{workspace_id}/{node_id}\tdownload-workspace-file\tSession token\tYes\tDownload a file from a workspace\ndownload://share/{share_id}/{node_id}\tdownload-share-file\tSession token\tYes\tDownload a file from a share\ndownload://quickshare/{quickshare_id}\tdownload-quickshare-file\tNone (public)\tNo\tDownload a quickshare file\n\nFiles up to 50 MB are returned inline as base64-encoded blob content. Larger files return a text fallback with a URL to the HTTP pass-through endpoint (see below). The download tool responses include a resource_uri field with the appropriate URI for each file.\n\nDynamic resource listing: When authenticated, workspace and share file resources are dynamically listed via resources/list. MCP clients (such as Claude Desktop's @ mention picker) can discover available files without any tool calls. Up to 10 workspaces and 10 shares are enumerated, with up to 25 most recently updated root-level files from each. Resources appear as \"WorkspaceName / filename.ext\" or \"ShareTitle / filename.ext\". Results are cached for 1 minute per session. Only root-level files are listed -- subdirectories are not recursively enumerated. Use the storage tool with action list to browse deeper. The quickshare template remains template-only and is not dynamically enumerable.\n\nMCP Prompts\n\nThe server registers MCP prompts that appear in the client's \"Add From\" / \"+\" menu as user-clickable app launchers. These are primarily for desktop MCP clients (e.g., Claude Desktop); code-mode clients (Claude Code, Cursor) do not surface prompts.\n\nPrompt Name\tDescription\nApp: Choose Workspace or Org\tLaunch the Workspace Picker to browse orgs, select workspaces, and manage shares\nApp: Pick a File\tLaunch the File Picker with built-in workspace navigator for browsing, searching, and selecting files\nApp: Open Workflow\tLaunch the Workflow Manager (auto-selects workspace if only one, otherwise opens Workspace Picker first)\nApp: Upload Files\tLaunch the Uploader to upload files with drag-and-drop, progress tracking, and text file creation\nApp: Available Apps\tList all available MCP App widgets with descriptions and launch instructions\nHTTP File Pass-Through\n\nFor files larger than 50 MB or when raw binary streaming is needed, the server provides an HTTP pass-through endpoint that streams file content directly from the API:\n\nEndpoint\tAuth\tDescription\nGET /file/workspace/{workspace_id}/{node_id}\tMcp-Session-Id header\tStream a workspace file\nGET /file/share/{share_id}/{node_id}\tMcp-Session-Id header\tStream a share file\nGET /file/quickshare/{quickshare_id}\tNone (public)\tStream a quickshare file\n\nThe response includes proper Content-Type, Content-Length, and Content-Disposition headers from the upstream API. Errors are returned as HTML pages. The Mcp-Session-Id header is the same session identifier used for MCP protocol communication.\n\nWorkflow Overview\n\nThe server includes workflow features for project tracking: tasks (structured work items with priorities and assignees), worklogs (append-only activity logs), approvals (formal sign-off requests), and todos (simple checklists). Enable workflow on a workspace with workspace action enable-workflow before using these tools. See the Full Agent Workflow recipe in section 6 for the complete pattern.\n\nBest practice (IMPORTANT): After state-changing actions (uploading files, creating shares, changing task status, member changes, file moves/deletes), append a worklog entry describing what you did and why. Without worklog entries, agent work is invisible to humans reviewing the workspace. For multiple related actions (e.g., uploading several files), you may log once after the batch completes rather than after each individual action. Worklog entries are append-only and permanent.\n\nAdditional References\nAgent guide (this file): /skill.md on the MCP server -- tool documentation, workflows, and constraints.\nREST API reference: https://api.fast.io/llms.txt -- endpoint documentation for the underlying Fast.io API.\nPlatform guide: references/REFERENCE.md -- capabilities, agent plan details, key workflows, and upgrade paths.\n2. Authentication (Critical First Step)\n\nAuthentication is required before calling any tool except these unauthenticated tools:\n\nauth with actions: signin, signup, set-api-key, pkce-login, email-check, password-reset-request, password-reset\ndownload with action: quickshare-details\nChoosing the Right Approach\n\nThere are three ways to use Fast.io as an agent, depending on whether you are operating autonomously or assisting an existing human user.\n\nOption 1: Autonomous Agent -- Create an Agent Account\n\nIf you are operating independently (storing files, running workflows, building workspaces for users), create your own agent account with auth action signup. Agent accounts get the free agent plan (50 GB, 5,000 monthly credits) and can transfer orgs to humans when ready. This is the recommended path for autonomous agents. See Agent Account Creation below for steps.\n\nOption 2: Assisting a Human -- Use Their API Key\n\nIf a human already has a Fast.io account and wants your help managing their files, workspaces, or shares, they can create an API key for you to use. No separate agent account is needed -- you operate as the human user. The human creates a key at Settings -> Devices & Agents -> API Keys (direct link: https://go.fast.io/settings/api-keys). Call auth with action set-api-key and the key to authenticate -- the key is validated and stored in the session automatically. API keys work as Bearer tokens and by default have the same permissions as the account owner. Keys can optionally be scoped to specific organizations, workspaces, or shares (using the same scope system as OAuth tokens), tagged with an agent_name for tracking, and given an expiration date. Unscoped keys do not expire unless revoked. Agents can also manage API keys programmatically with auth actions api-key-create, api-key-update, api-key-list, api-key-get, and api-key-delete.\n\nOption 3: Agent Account Invited to a Human's Org\n\nIf you want your own agent identity but need to work within a human's existing organization, create an agent account with auth action signup, then have the human invite you to their org with member action add (entity_type org) or to a workspace with member action add (entity_type workspace). Alternatively the human can invite via the UI: Settings -> Your Organization -> Manage People. This gives you access to their workspaces and shares while keeping your own account separate. After accepting invitations with user action accept-all-invitations, use auth action signin to authenticate normally. Note: If the human only invites you to a workspace (not the org), the org will appear as external -- see Internal vs External Orgs in the Organizations section.\n\nOption 4: Browser Login (PKCE)\n\nIf you prefer not to send a password through the agent, use browser-based PKCE login. Call auth action pkce-login (optionally with an email hint) to get a login URL. The user opens the URL in a browser, signs in (email/password or SSO like Google/Microsoft), and approves access. The browser displays an authorization code which the user copies back to the agent. Call auth action pkce-complete with the code to finish signing in. This is the most secure option -- no credentials pass through the agent.\n\nPKCE login supports optional scoped access via the scope_type parameter. By default, scope_type is \"user\" (full account access). Other scope types restrict the token to specific entity types:\n\nscope_type\tAccess granted\nuser\tFull account access (default)\norg\tUser selects specific organizations\nworkspace\tUser selects specific workspaces\nall_orgs\tAll organizations the user belongs to\nall_workspaces\tAll workspaces the user has access to\nall_shares\tAll shares the user is a member of (share:*:<mode>)\n\nScope inheritance: Broader scopes include access to child entities automatically:\n\nall_orgs includes all orgs + all workspaces + all shares within those orgs\nall_workspaces includes all workspaces + all shares within those workspaces\norg scope on a specific org includes access to all workspaces and shares within that org\nworkspace scope on a specific workspace includes access to shares within that workspace\nall_shares grants direct access to all shares the user has membership in, bypassing workspace/org inheritance\n\nThe agent_name parameter controls what the user sees on the approval screen -- the screen displays \"[agent_name] will act on your behalf\". If omitted, only the client name is shown. Use a descriptive name so the user knows which agent is requesting access.\n\nApproval flow by scope_type:\n\nuser (default): Full account access. The user sees a simple approve/decline prompt with no entity picker.\norg, workspace: The user sees an entity selection screen listing their accessible entities with checkboxes, plus a read-only / read-write toggle. The user picks which entities to grant, then approves or declines.\nall_orgs, all_workspaces, all_shares: The user sees a summary of the wildcard access being requested (no entity picker), then approves or declines.\n\nThe MCP server defaults to scope_type=\"user\" for backward compatibility.\n\nScenario\tRecommended Approach\nOperating autonomously, storing files, building for users\tCreate an agent account with your own org (Option 1)\nHelping a human manage their existing account\tAsk the human to create an API key for you (Option 2)\nWorking within a human's org with your own identity\tCreate an agent account, have the human invite you (Option 3)\nBuilding something to hand off to a human\tCreate an agent account, build it, then transfer the org (Option 1)\nSigning in without sending a password through the agent\tBrowser-based PKCE login (Option 4)\n\nCredit limits by account type: Agent accounts (Options 1, 3) can transfer orgs to humans when credits run out -- see Ownership Transfer in section 3. Human accounts (Option 2) cannot use the transfer/claim API; direct the human to upgrade their plan at https://go.fast.io/settings/billing or via org action billing-create.\n\nStandard Sign-In Flow\nCall auth with action signin, email and password.\nThe server returns a JWT auth_token and stores it in the session automatically.\nAll subsequent tool calls use this token without any manual passing.\nAgent Account Creation\n\nWhen creating a new account (Options 1 and 3 above), agents MUST use auth action signup which automatically registers with agent=true. Never sign up as a human account. Agent accounts provide:\n\naccount_type set to \"agent\"\nFree agent plan assigned automatically\nTransfer/claim workflow enabled for handing orgs off to humans\n\nSteps:\n\nOptionally call auth action email-check with the desired email to verify it is available for registration before attempting signup.\nCall auth action signup with first_name, last_name, email, and password. The agent=true flag is sent automatically by the MCP server.\nThe account is created and a session is established automatically -- the agent is signed in immediately.\nVerify your email (required before using most endpoints): Call auth action email-verify with email to send a verification code, then call auth action email-verify again with email and email_token to validate the code.\nNo credit card is required. No trial period. No expiration. The account persists indefinitely.\nTwo-Factor Authentication Flow\nCall auth action signin with email and password.\nIf the response includes two_factor_required: true, the returned token has limited scope.\nCall auth action 2fa-verify with the 2FA code (TOTP, SMS, or WhatsApp).\nThe server replaces the limited-scope token with a full-scope token automatically.\nInline 2FA for Sensitive Operations\n\nSome API endpoints require per-request 2FA verification when the account has 2FA enabled. These operations require a valid 2FA token parameter (6-digit TOTP or SMS/call/WhatsApp code) in addition to normal authentication:\n\napi-key-create — creating a new API key\napi-key-delete — revoking an API key\n\nIf the account does not have 2FA enabled, these operations work normally without a token. If 2FA is enabled and the token is missing or invalid, the request fails.\n\nWorkflow:\n\nCheck 2FA status: auth action 2fa-status — if state is \"enabled\", inline 2FA is required.\nPrompt the user for a TOTP code from their authenticator app, or send a code via auth action 2fa-send.\nPass the code as the token parameter to api-key-create or api-key-delete.\n\nTip: API key authentication (auth action set-api-key) bypasses inline 2FA checks entirely. If the agent is already authenticated via API key, no token is needed for these operations.\n\nBrowser Login (PKCE) Flow\nCall auth action pkce-login (optionally with email to pre-fill the sign-in form, scope_type to request scoped access, and agent_name to identify the agent).\nThe tool returns a login_url -- present it to the user to open in a browser.\nThe user signs in (email/password or SSO).\nThe user sees the approval screen showing the agent_name (or client name if not provided). Depending on scope_type: for user they simply approve; for org/workspace they select specific entities and read-only/read-write access; for all_orgs/all_workspaces/all_shares they review the wildcard access summary.\nThe user clicks Approve. The browser displays an authorization code. The user copies it.\nCall auth action pkce-complete with the code to exchange it for an access token.\nThe session is established automatically -- all subsequent tool calls are authenticated. If scoped access was granted, scopes and agent_name are included in the response and stored in the session.\nChecking Session Status\nauth action status -- checks the local Durable Object session. No API call is made. Returns authentication state, user ID, email, token expiry, scopes, and agent_name.\nauth action check -- validates the token against the Fast.io API. Returns the user ID if the token is still valid.\nSession Expiry\n\nJWT tokens last 1 hour. API keys do not expire by default, but can optionally have an expiration set via api-key-create or api-key-update with the key_expires parameter. When a JWT session expires or a time-limited API key expires, tool calls return a clear error indicating that re-authentication is needed. Call auth action signin again to establish a new session. The MCP server does not auto-refresh tokens.\n\nTip: For long-running sessions, use auth action status to check remaining token lifetime before starting a multi-step workflow. If the token is close to expiring, re-authenticate first to avoid mid-workflow interruptions.\n\nSigning Out\n\nCall auth action signout to clear the stored session from the Durable Object.\n\n3. Core Concepts\nOrganizations\n\nOrganizations are top-level containers that collect workspaces. An organization can represent a company, a business unit, a team, or simply your own personal collection. Every user belongs to one or more organizations. Organizations have:\n\nWorkspaces — the file storage containers that belong to the organization.\nMembers with roles: owner, admin, member, guest, view.\nBilling and subscriptions managed through Stripe integration.\nPlan limits that govern storage, transfer, AI tokens, and member counts.\n\nOrganizations are identified by a 19-digit numeric profile ID or a domain string.\n\nIMPORTANT: When creating orgs, agents MUST use org action create which automatically assigns billing_plan: \"agent\". This ensures the org gets the free agent plan (50 GB, 5,000 credits/month). Do not use any other billing plan for agent-created organizations.\n\nOrg Discovery (IMPORTANT)\n\nTo discover all available orgs, agents must call both actions:\n\norg action list -- returns internal orgs where you are a direct member (member: true)\norg action discover-external -- returns external orgs you access via workspace membership only (member: false)\n\nAn agent that only checks org action list will miss external orgs entirely and won't discover the workspaces it's been invited to. External orgs are the most common pattern when a human invites an agent to help with a specific project -- they add the agent to a workspace but not to the org itself.\n\nInternal vs External Orgs\n\nInternal orgs (member: true) -- orgs you created or were invited to join as a member. You have org-level access: you can see all workspaces (subject to permissions), manage settings if you're an admin, and appear in the org's member list.\n\nExternal orgs (member: false) -- orgs you can access only through workspace membership. You can see the org's name and basic public info, but you cannot manage org settings, see other workspaces, or add members at the org level. Your access is limited to the specific workspaces you were explicitly invited to.\n\nExample: A human invites your agent to their \"Q4 Reports\" workspace. You can upload files, run AI queries, and collaborate in that workspace. But you cannot create new workspaces in their org, view their billing, or access their other workspaces. The org shows up via org action discover-external -- not org action list. If the human later invites you to the org itself, the org moves from external to internal.\n\nWorkspaces\n\nWorkspaces are file storage containers within organizations. Each workspace has:\n\nIts own set of members with roles (owner, admin, member, guest).\nA storage tree of files and folders (storage nodes).\nOptional AI features for RAG-powered chat.\nShares that can be created within the workspace.\nArchive/unarchive lifecycle management.\n50 GB included storage on the free agent plan, with files up to 1 GB per upload.\nFile versioning -- every edit creates a new version, old versions are recoverable.\nFull-text and semantic search -- find files by name or content, and documents by meaning.\n\nWorkspaces are identified by a 19-digit numeric profile ID.\n\nIntelligence: On or Off\n\nWorkspaces have an intelligence toggle that controls whether AI features are active.\n\n⚠️ COST WARNING: Intelligence incurs significant ingestion costs (10 credits per page for every uploaded document). For a workspace with hundreds or thousands of pages, this adds up quickly. Do NOT enable intelligence unless the user specifically needs RAG queries across many documents or AI-powered semantic search. Most workflows (file storage, sharing, collaboration, one-off file analysis) work perfectly without it.\n\nIntelligence OFF (recommended default) -- the workspace is pure file storage. You can still attach files directly to an AI chat conversation (up to 20 files, 200 MB total) and ask questions about them -- no ingestion cost. This is the right choice for most use cases: file storage, sharing, collaboration, project coordination, and analyzing a small number of specific files.\n\nIntelligence ON (only when needed) -- the workspace becomes an AI-powered knowledge base. Every document and code file uploaded is automatically ingested, summarized, and indexed. Only enable this when the user needs one of these two capabilities:\n\nRAG queries across many documents -- scope AI chat to entire folders or the full workspace and ask questions across all indexed content. The AI retrieves relevant passages and answers with citations. This is useful when you have a large volume of documents and need to search across all of them.\nAI-powered semantic search -- find files by meaning, not just keywords. \"Show me contracts with indemnity clauses\" works even if those exact words do not appear in the filename.\n\nIntelligence also enables auto-summarization and automatic metadata extraction, but these alone do not justify the ingestion cost.\n\nComing soon: RAG indexing support for images, video, and audio files. Currently only documents and code are indexed.\n\nDefault behavior: Intelligence defaults to ON for workspaces created via the API by agent accounts. You should explicitly set intelligence to \"false\" when creating workspaces unless the user has asked for RAG or AI search capabilities. Do not enable it speculatively \"just in case\" -- it can always be enabled later, but ingestion costs are incurred immediately and are non-refundable.\n\nAgent use case: Create a workspace per project or client. Keep intelligence OFF for storage and collaboration. Only enable it when users need to query across a large document set. Upload reports, datasets, and deliverables. Invite other agents and human stakeholders. Everything is organized, searchable, and versioned.\n\nFor full details on AI chat types, file context modes, AI state, and how intelligence affects them, see the AI Chat section below.\n\nShares\n\nShares are purpose-built spaces for exchanging files with people outside your workspace. They can exist within workspaces and have three types:\n\nMode\tWhat It Does\tAgent Use Case\nSend\tRecipients can download files\tDeliver reports, exports, generated content\nReceive\tRecipients can upload files\tCollect documents, datasets, user submissions\nExchange\tBoth upload and download\tCollaborative workflows, review cycles\nPortals\n\nA Portal is a Send share created from a workspace folder (storage_mode=workspace_folder). Portals are always Send-only -- recipients can view and download files but cannot upload. The portal displays the live contents of the linked workspace folder, so any changes to the folder are immediately reflected. Portals are ideal for publishing a folder's contents externally (e.g., a client deliverables folder) without duplicating files. To create a portal: use share action create with share_type: \"send\", storage_mode: \"workspace_folder\", and folder_node_id (or create_folder: true).\n\nShare Features\nPassword protection -- require a password for link access\nExpiration dates -- shares auto-expire after a set period\nDownload controls -- enable or disable file downloads\nAccess levels -- Members Only, Org Members, Registered Users, or Public (anyone with the link)\nCustom branding -- background images, gradient colors, accent colors, logos\nPost-download messaging -- show custom messages and links after download\nUp to 3 custom links per share for context or calls-to-action\nGuest chat -- let share recipients ask questions in real-time\nAI-powered auto-titling -- shares automatically generate smart titles from their contents\nActivity notifications -- get notified when files are sent or received\nComment controls -- configure who can see and post comments (owners, guests, or both)\nTwo Storage Modes\n\nWhen creating a share with share action create, the storage_mode parameter determines how files are stored:\n\nindependent (independent storage, default) -- The share has its own isolated storage. Files are added directly to the share and are independent of any workspace. This creates a self-contained share -- changes to workspace files do not affect the share, and vice versa. Use for final deliverables, compliance packages, archived reports, or any scenario where you want an immutable snapshot.\n\nworkspace_folder (workspace-backed) -- The share is backed by a specific folder in a workspace. The share displays the live contents of that folder -- any files added, updated, or removed in the workspace folder are immediately reflected in the share. No file duplication, so no extra storage cost. To create a workspace folder share, pass storage_mode=workspace_folder and folder_node_id={folder_opaque_id} when creating the share. Note: Expiration dates are not allowed on workspace folder shares since the content is live.\n\nBoth modes look the same to share recipients -- a branded share with file preview, download controls, and all share features. The difference is whether the content is a snapshot (independent) or a live view (workspace folder).\n\nResponse fields: API responses include both storage_mode (independent or workspace_folder) and share_category (portal or shared_folder). Use storage_mode when creating shares; share_category is a read-only classification in responses.\n\nShares are identified by a 19-digit numeric profile ID.\n\nAgent use case: Generate a quarterly report, create a Send share with your client's branding, set a 30-day expiration, and share the link. The client sees a professional, branded page with instant file preview -- not a raw download link.\n\nStorage Nodes\n\nFiles and folders are represented as storage nodes. Each node has an opaque ID (a 30-character alphanumeric string, displayed with hyphens, e.g. f3jm5-zqzfx-pxdr2-dx8z5-bvnb3-rpjfm4). The special value root refers to the root folder of a workspace or share, and trash refers to the trash folder.\n\nKey operations on storage nodes: list, create-folder, move, copy, rename, delete (moves to trash), purge (permanently deletes), restore (recovers from trash), search, add-file (link an upload), and add-link (create a share reference).\n\nNodes have versions. Each file modification creates a new version. Version history can be listed and files can be restored to previous versions.\n\nConflict resolution (REPLACE by default): When a file operation encounters an existing file with the same name in the target folder, the default behavior is to replace (overwrite) the existing file:\n\nUpload (addfile) -- silently overwrites the existing file. The previous content is preserved as a version entry, recoverable via storage action version-list / version-restore.\nMove / Copy -- trashes the existing conflicting file, then completes the operation. The old file is recoverable from trash.\nRestore from trash -- trashes the existing conflicting file, then restores.\nFolder conflicts and type mismatches (file vs folder) still fall back to rename (e.g. folder (2)).\n\nThis means uploading a file with the same name as an existing file will overwrite it, not create a renamed copy like report (2).pdf. If you need multiple files with the same name to coexist, rename them before uploading.\n\nNotes\n\nNotes are a storage node type (alongside files and folders) that store markdown content directly on the server. They live in the same folder hierarchy as files, are versioned like any other node, and appear in storage listings with type: \"note\".\n\nCreating and Updating Notes\n\nCreate notes with workspace action create-note, read with workspace action read-note, and update with workspace action update-note.\n\nCreating: Provide workspace_id, parent_id (folder opaque ID or \"root\"), name (must end in .md, max 100 characters), and content (markdown text, max 100 KB).\n\nReading: Provide workspace_id and node_id. Returns the note's markdown content and metadata.\n\nUpdating: Provide workspace_id, node_id, and at least one of name (must end in .md) or content (max 100 KB).\n\nConstraint\tLimit\nContent encoding\tValid UTF-8 (UTF8MB4). Invalid byte sequences and control characters (\\p{C} except \\t, \\n, \\r) are stripped.\nContent size\t100 KB max\nFilename\t1-100 characters, must end in .md\nMarkdown validation\tCode blocks and emphasis markers must be balanced\nRate limit\t2 per 10s, 5 per 60s\nNotes as Long-Term Knowledge Grounding\n\nIn an intelligent workspace, notes are automatically ingested and indexed just like uploaded documents. This makes notes a way to bank knowledge over time -- any facts, context, or decisions stored in notes become grounding material for future AI queries.\n\nWhen an AI chat uses folder scope (or defaults to the entire workspace), notes within that scope are searched alongside files. The AI retrieves relevant passages from notes and cites them in answers.\n\nKey behaviors:\n\nNotes are ingested for RAG when workspace intelligence is enabled\nNotes within a folder scope are included in scoped queries\nNotes with ai_state: ready are searchable via RAG\nNotes can also be attached directly to a chat via files_attach (check ai.attach is true in storage details)\n\nUse cases:\n\nStore project context, decisions, and rationale. Months later, ask \"Why did we choose vendor X?\" and the AI retrieves the note.\nSave research findings in a note. Future AI chats automatically use those findings as grounding.\nCreate reference documents (style guides, naming conventions) that inform all future AI queries in the workspace.\nOther Note Operations\n\nNotes support the same storage operations as files and folders: move (via storage action move), copy (storage action copy), delete/trash (storage action delete), restore (storage action restore), version history (storage action version-list), and details (storage action details).\n\nLinking Users to Notes\nNote in workspace context (opens workspace with note panel): https://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}\nNote preview (standalone view): https://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}\nAI Chat\n\nAI chat lets agents ask questions about files stored in workspaces and shares. Two chat types are available, each with different file context options.\n\nAI chat is read-only. It can read, analyze, search, and answer questions about file contents, but it cannot modify files, change workspace settings, manage members, or access events. Any action beyond reading file content — uploading, deleting, moving files, changing settings, managing shares, reading events — must be done through the MCP tools directly. Do not attempt to use AI chat as a general-purpose tool for workspace management.\n\nTwo Chat Types\nchat — Basic AI conversation with no file context from the workspace index. Use for general questions only.\nchat_with_files — AI grounded in your files. Two mutually exclusive modes for providing file context:\nFolder/file scope (RAG) — limits the retrieval search space. Requires intelligence enabled; files must be in ready AI state.\nFile attachments — files read directly by the AI. No intelligence required; files must have ai.attach: true in storage details (the file must be a supported type for AI analysis). Max 20 files, 200 MB total.\n\nAuto-promotion: If you create a chat with type=chat but include files_scope, folders_scope, or files_attach, the system automatically promotes the type to chat_with_files. You don't need to worry about setting the type exactly right — the intent is unambiguous when file parameters are present.\n\nBoth types augment answers with web knowledge when relevant.\n\nFile Context: Scope vs Attachments\n\nFor chat_with_files, choose one of these mutually exclusive approaches:\n\nFeature\tFolder/File Scope (RAG)\tFile Attachments\nHow it works\tLimits RAG search space\tFiles read directly by AI\nRequires intelligence\tYes\tNo\nFile readiness requirement\tai_state: ready\tai.attach: true\nBest for\tMany files, knowledge retrieval\tSpecific files, direct analysis\nMax references\t100 folder refs (subfolder tree expansion) or 100 file refs\t20 files / 200 MB\nDefault (no scope given)\tEntire workspace\tN/A\n\nScope parameters (REQUIRES intelligence — will error if intelligence is off):\n\nfolders_scope — comma-separated nodeId:depth pairs (depth 1-10, max 100 subfolder refs). Defines a search boundary — the RAG backend finds documents within scoped folders automatically. Just pass folder IDs with depth; do not enumerate individual files. A folder with thousands of files and few subfolders works fine.\nfiles_scope — comma-separated nodeId:versionId pairs (max 100). Limits RAG to specific indexed files. nodeId is required; versionId is required in the pair format but will be auto-resolved to the node's current version if left empty (e.g., nodeId: with nothing after the colon). Get versionId from the file's version field in storage action list or details responses.\nIf neither is specified, the default scope is the entire workspace (all indexed documents). This is the recommended default — omit scope parameters unless you specifically need to narrow the search.\n\nAttachment parameter (no intelligence required):\n\nfiles_attach — comma-separated nodeId:versionId pairs (max 20, 200 MB total). nodeId is required; versionId will be auto-resolved to the current version if left empty. Files are read directly, not via RAG. FILES ONLY: passing a folder nodeId returns a 406 error. To include folder contents in AI context, use folders_scope instead (requires intelligence). Only files with ai.attach: true in storage details can be attached — check before using.\n\nDo not list folder contents and pass individual file IDs as files_scope when you mean to search a folder — use folders_scope with the folder's nodeId instead. files_scope is only for targeting specific known file versions.\n\nScope vs attach: files_scope and folders_scope narrow the RAG search boundary and require workspace intelligence to be enabled — they will error on non-intelligent workspaces. files_attach sends files directly to the AI without indexing and works regardless of intelligence setting, but accepts only file nodeIds (not folders).\n\nfiles_scope/folders_scope and files_attach are mutually exclusive — sending both will error.\n\nIntelligence and AI State\n\nThe workspace intelligence toggle (see Workspaces above) controls whether uploaded documents and code files are auto-ingested, summarized, and indexed for RAG. When intelligence is enabled, each file has an ai_state indicating its readiness:\n\nState\tMeaning\ndisabled\tAI processing disabled for this file\npending\tQueued for processing\nin_progress\tCurrently being ingested and indexed\nready\tComplete — available for folder/file scope queries\nfailed\tProcessing failed\n\nOnly files with ai_state: ready are included in folder/file scope searches. Check file state via storage action details with context_type: \"workspace\".\n\nAttachability — the ai.attach Flag\n\nFile nodes in storage list/details responses include an ai object with three fields:\n\nField\tType\tMeaning\nai.state\tstring\tAI indexing state (disabled, pending, inprogress, ready, failed)\nai.attach\tboolean\tWhether the file can be used with files_attach\nai.summary\tboolean\tWhether the file already has an AI-generated summary\n\nBefore using files_attach, check that ai.attach is true. A file is attachable when its type supports AI analysis (documents, code, images, PDFs, spreadsheets, etc.) or when it already has a summary from prior processing. Files with ai.attach: false (unsupported formats, corrupt files, or files still processing) will be rejected by the API.\n\nThis flag is independent of the workspace intelligence setting — a file can have ai.attach: true even when intelligence is off.\n\nWhen to enable intelligence: You need RAG queries across many documents (scoped to folders or the full workspace) or AI-powered semantic search. Do NOT enable just for auto-summarization or metadata extraction alone -- the ingestion cost (10 credits/page) is significant.\n\nWhen to disable intelligence (recommended default): The workspace is for storage, sharing, collaboration, or you only need to analyze specific files via attachments. This covers most use cases. Saves significant credits. Intelligence can always be enabled later if needed.\n\nEven with intelligence off, chat_with_files with file attachments still works for files with ai.attach: true.\n\nHow to Phrase Questions\n\nWith folder/file scope (RAG): Write questions likely to match content in indexed files. The AI searches the scope, retrieves passages, and cites them.\n\nGood: \"What are the payment terms in the vendor contracts?\"\nGood: \"Summarize the key findings from the Q3 analysis reports\"\nBad: \"Tell me about these files\" — too vague, no specific content to match\nBad: \"What's in this workspace?\" — cannot meaningfully search for \"everything\"\n\nWith file attachments: Be direct — the AI reads the full file content. No retrieval step.\n\n\"Describe this image in detail\"\n\"Extract all dates and amounts from this invoice\"\n\"Convert this CSV data into a summary table\"\n\nPersonality: The personality parameter controls the tone and length of AI responses. Pass it when creating a chat or sending a message:\n\nconcise — short, brief answers\ndetailed — comprehensive answers with context and evidence (default)\n\nUse concise when you need a quick fact, a yes/no answer, or a brief summary. Use detailed (or omit the parameter) when you need thorough analysis with supporting evidence and citations. The personality can also be overridden per follow-up message.\n\nControlling verbosity in questions: You can also guide verbosity through how you phrase the question itself:\n\n\"In one sentence, what is the main conclusion of this report?\"\n\"List only the file names that mention GDPR compliance, no explanations\"\n\"Give me a brief summary — 2-3 bullet points max\"\n\nCombining personality: \"concise\" with a direct question produces the shortest answers and uses the fewest AI credits.\n\nChat Parameters\n\nCreate a chat with ai action chat-create (with context_type: \"workspace\") or ai action chat-create (with context_type: \"share\"):\n\ntype (required) — chat or chat_with_files\nquery_text (required for workspace, optional for share) — initial message, 2-12,768 characters\npersonality (optional) — concise or detailed (default: detailed)\nprivacy (optional) — private or public (default: public)\nfiles_scope (optional) — nodeId:versionId,... (max 100, requires chat_with_files + intelligence). nodeId required; versionId auto-resolved if empty. Omit to search all indexed documents (recommended default).\nfolders_scope (optional) — nodeId:depth,... (depth 1-10, max 100 subfolder refs, requires chat_with_files + intelligence). Folder scope = search boundary, not file enumeration. Omit to search all indexed documents (recommended default).\nfiles_attach (optional) — nodeId:versionId,... (max 20 / 200 MB, nodeId required, versionId auto-resolved if empty, mutually exclusive with scope params)\nFollow-up Messages\n\nSend follow-ups with ai action message-send (with context_type: \"workspace\" or \"share\"). The chat type is inherited from the parent chat. Each follow-up can update the scope, attachment, and personality parameters.\n\nWaiting for AI Responses\n\nAfter creating a chat or sending a message, the AI response is asynchronous. Message states progress: ready → in_progress → complete (or errored).\n\nRecommended: Call ai action message-read (with context_type: \"workspace\" or \"share\") with the returned message_id. The tool polls automatically (up to 15 attempts, 2-second intervals, ~30 seconds). If the response is still processing after that window, use event action activity-poll with the workspace/share ID instead of calling the read action in a loop — see Activity Polling in section 7.\n\nResponse Citations\n\nCompleted AI responses include citations pointing to source files:\n\nnodeId — storage node opaque ID\nversionId — file version opaque ID\nentries[].page — page number\nentries[].snippet — text excerpt\nentries[].timestamp — audio/video timestamp\nLinking Users to AI Chats\n\nAppend ?chat={chat_opaque_id} to the workspace storage URL:\n\nhttps://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}\n\nShare AI Chats\n\nShares support AI chat with identical capabilities. All workspace AI endpoints have share equivalents accessible via ai actions with context_type: \"share\".\n\nAI Share / Export\n\nGenerate temporary markdown-formatted download URLs for files that can be pasted into external AI tools (ChatGPT, Claude, etc.). Use ai action share-generate (with context_type: \"workspace\" or \"share\"). URLs expire after 5 minutes. Limits: 25 files maximum, 50 MB per file, 100 MB total.\n\nProfile IDs\n\nOrganizations, workspaces, and shares are all identified by 19-digit numeric profile IDs. These appear throughout the tool parameters as workspace_id, share_id, org_id, profile_id, and member_id.\n\nMost endpoints also accept custom names as identifiers:\n\nProfile Type\tNumeric ID\tCustom Name\nWorkspace\t19-digit ID\tFolder name (e.g., my-project)\nShare\t19-digit ID\tURL name (e.g., q4-financials)\nOrganization\t19-digit ID\tDomain name (e.g., acme)\nUser\t19-digit ID\tEmail address (e.g., user@example.com)\nQuickShares\n\nQuickShares are temporary public download links for individual files in workspaces (not available for shares). They can be accessed without authentication. Expires in seconds from creation (default 10,800 = 3 hours, max 604,800 = 7 days) or as an ISO 8601 datetime via expires_at. Max file size: 1 GB. Each quickshare has an opaque identifier used to retrieve metadata and download the file.\n\nFile Preview\n\nFiles uploaded to Fast.io get automatic preview generation. When humans open a share or workspace, they see the content immediately -- no \"download and open in another app\" friction.\n\nSupported preview formats:\n\nImages -- full-resolution with auto-rotation and zoom\nVideo -- HLS adaptive streaming (50--60% faster load than raw video)\nAudio -- interactive waveform visualization\nPDF -- page navigation, zoom, text selection\nSpreadsheets -- grid navigation with multi-sheet support\nCode and text -- syntax highlighting, markdown rendering\n\nUse storage action preview-url (with context_type: \"workspace\" or \"share\") to generate preview URLs. Use storage action preview-transform (with context_type: \"workspace\" or \"share\") for image resize, crop, and format conversion.\n\nAgent use case: Your generated PDF report does not just appear as a download link. The human sees it rendered inline, can flip through pages, zoom in, and comment on specific sections -- all without leaving the browser.\n\nComments and Annotations\n\nHumans and agents can leave feedback directly on files, anchored to specific content using the reference parameter:\n\nImage comments -- anchored to spatial regions (normalized x/y/width/height coordinates)\nVideo comments -- anchored to timestamps with spatial region selection\nAudio comments -- anchored to timestamps or time ranges\nPDF comments -- anchored to specific pages with optional text snippet selection\nText-anchored comments -- anchored to selected text in markdown/notes using exact, prefix, suffix, start_offset, and end_offset fields (use type: \"document\" or type: \"text\")\nThreaded replies -- single-level threading only; replies to replies are auto-flattened to the parent\nEmoji reactions -- one reaction per user per comment; adding a new reaction replaces the previous one\nMention tags -- reference users and files inline using bracket syntax: @[profile:id], @[user:opaqueId:Display Name], @[file:fileId:filename.ext]. Get IDs from member lists, user details, or storage listings. The display name segment is optional for profile tags but recommended for user and file tags\n\nComments use JSON request bodies (Content-Type: application/json), unlike most other endpoints which use form-encoded data.\n\nListing comments: Use comment action list for per-file comments and comment action list-all for all comments across a workspace or share. Both support sort, limit (2-200), offset, include_deleted, reference_type filter, and include_total.\n\nAdding comments: Use comment action add with profile_type, profile_id, node_id, and text. Optionally include parent_comment_id for replies and reference to anchor to a specific position. Supports mention tags in the body. Two character limits apply: total body including tags max 8,192 chars, display text (body with @[...] tags stripped) max 2,048 chars. Optionally include linked_entity_type and linked_entity_id to link the comment to a task or approval at creation time.\n\nDeleting comments: comment action delete is recursive -- deleting a parent also removes all replies. comment action bulk-delete is NOT recursive -- replies to deleted comments are preserved.\n\nComment Linking: Comments can be linked to workflow entities (tasks or approvals). Each comment supports one link at a time (nullable). Use comment action link to associate an existing comment with a task or approval, comment action unlink to remove the association, and comment action linked to reverse-lookup all comments linked to a given entity. You can also link at creation time by passing linked_entity_type and linked_entity_id to the add action. Comment responses include linked_entity_type and linked_entity_id fields (null when unlinked).\n\nLinking users to comments: The preview URL opens the comments sidebar automatically. Deep link query parameters let you target a specific comment or position:\n\nParameter\tFormat\tPurpose\n?comment={id}\tComment opaque ID\tScrolls to and highlights a specific comment for 2 seconds\n?t={seconds}\te.g. ?t=45.5\tSeeks to timestamp for audio/video comments\n?p={pageNum}\te.g. ?p=3\tNavigates to page for PDF comments\n\nWorkspace: https://{org.domain}.fast.io/workspace/{folder_name}/preview/{file_opaque_id}?comment={comment_id}\n\nShare: https://go.fast.io/shared/{custom_name}/{title-slug}/preview/{file_opaque_id}?comment={comment_id}\n\nParameters can be combined -- e.g. ?comment={id}&t=45.5 to deep link to a video comment at a specific timestamp. In shares, the comments sidebar only opens if the share has comments enabled.\n\nAgent use case: You generate a design mockup. The human comments \"Change the header color\" on a specific region of the image. You read the comment, see exactly what region they are referring to via the reference.region coordinates, and regenerate.\n\nText-anchored comments (markdown/notes): To anchor a comment to specific text in a markdown or notes file, use the reference parameter with type: \"document\" (or \"text\", which is an alias) and the text selection fields:\n\nexact (string, max 500 chars) -- the selected text verbatim\nprefix (string, max 100 chars) -- ~30-50 characters of context before the selection for disambiguation\nsuffix (string, max 100 chars) -- ~30-50 characters of context after the selection for disambiguation\nstart_offset (integer) -- character offset from document start (hint for resolving ambiguous matches)\nend_offset (integer) -- character offset for end of selection (hint for resolving ambiguous matches)\n\nAt minimum, provide exact. The prefix/suffix fields help locate the selection when the same text appears multiple times. The start_offset/end_offset fields are optional hints that may not survive document edits.\n\nExample -- text-anchored comment on a markdown file:\n\n{\n  \"action\": \"add\",\n  \"profile_type\": \"workspace\",\n  \"profile_id\": \"1234567890123456789\",\n  \"node_id\": \"abc123-def456-ghi789\",\n  \"text\": \"This section needs a citation\",\n  \"reference\": {\n    \"type\": \"document\",\n    \"exact\": \"Studies show a 40% improvement\",\n    \"prefix\": \"In the results section, \",\n    \"suffix\": \" compared to the baseline.\",\n    \"start_offset\": 1250,\n    \"end_offset\": 1280\n  }\n}\n\nURL Import\n\nAgents can import files directly from URLs without downloading them locally first. Fast.io's server fetches the file, processes it, and adds it to your workspace or share.\n\nSupports any HTTP/HTTPS URL\nSupports OAuth-protected sources: Google Drive, OneDrive, Dropbox\nFiles go through the same processing pipeline (preview generation, AI indexing if intelligence is enabled, virus scanning)\n\nUse upload action web-import with the source URL, target profile, and parent node ID. Use upload action web-status to check progress and upload action web-list to list active import jobs.\n\nAgent use case: A user says \"Add this Google Doc to the project.\" You call upload action web-import with the URL. Fast.io downloads it server-side, generates previews, indexes it for AI, and it appears in the workspace. No local I/O.\n\nMetadata\n\nMetadata enables structured data annotation on files within workspaces. The system uses a template-based approach: administrators create templates that define the fields (name, type, constraints), then assign a template to the workspace. Files can then have metadata values set against the template fields.\n\nKey points:\n\nOne template per workspace -- each workspace supports at most one assigned metadata template at a time.\nTemplate categories -- legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr.\nField types -- string, int, float, bool, json, url, datetime -- each with optional constraints (min, max, default, fixed_list, can_be_null).\nTwo metadata types -- template metadata conforms to template field definitions; custom metadata is freeform key-value pairs not tied to any template.\nSystem templates -- pre-built templates that are automatically cloned when assigned to a workspace, so customizations do not affect the global definition.\nAI extraction -- the extract action uses AI to analyze file content and automatically populate metadata fields. Extracted values are flagged with is_auto: true. Consumes AI credits.\nVersion history -- metadata changes are tracked with version snapshots, accessible via the versions action.\nRequires billing feature -- the organization must have the metadata billing feature enabled.\nTemplate IDs are alphanumeric strings prefixed with mt_ (e.g. mt_abc123def456).\nOwnership Transfer\n\nThe primary way agents deliver value: build something, then give it to a human. Also the recommended action when the agent plan runs out of credits and API calls start returning 402 Payment Required -- transfer the org to a human who can upgrade to a paid plan.\n\nIMPORTANT: Account type restriction. The transfer/claim workflow (org actions transfer-token-create, transfer-token-list, transfer-token-delete, transfer-claim) is only available when the agent created an agent account (via auth action signup) and that agent account owns the org. If the agent is signed in with a human account (via auth action signin), the transfer/claim API cannot be used. Human-owned orgs must be upgraded directly by the human through the Fast.io dashboard.\n\nThe flow:\n\nAgent creates an agent account with auth action signup and an org with org action create, sets up workspaces with org action create-workspace, uploads files, configures shares\nAgent generates a transfer token (valid 72 hours) with org action transfer-token-create\nAgent sends the claim URL to the human: https://go.fast.io/claim?token=<token>\nHuman clicks the link and claims the org with their account\n\nWhen to transfer:\n\nThe org is ready for human use (workspaces configured, files uploaded, shares set up)\nThe agent plan runs out of credits (402 Payment Required) -- transfer so the human can upgrade\nThe human explicitly asks to take over the org\n\nManaging transfer tokens:\n\norg action transfer-token-list -- check for existing pending tokens before creating new ones\norg action transfer-token-delete -- revoke a token if the transfer is no longer needed\norg action transfer-claim -- claim an org using a token (used by the receiving human's agent)\n\nWhat happens after transfer:\n\nHuman becomes the owner of the org and all workspaces\nAgent retains admin access (can still manage files and shares)\nHuman gets a free plan (credit-based, no trial period)\nHuman can upgrade to Pro or Business at any time\n\nAgent use case: A user says \"Set up a project workspace for my team.\" You create the org, build out the workspace structure, upload templates, configure shares for client deliverables, invite team members -- then transfer ownership. The human walks into a fully configured platform. You stay on as admin to keep managing things.\n\n402 Payment Required use case (agent account): While working, the agent hits credit limits. Call org action transfer-token-create, send the claim URL to the human, and explain they can upgrade to continue. The agent keeps admin access and resumes work once the human upgrades.\n\n402 Payment Required use case (human account): The agent cannot transfer the org. Instead, inform the user that their org has run out of credits and they need to upgrade their billing plan. Direct them to the Fast.io dashboard or use org action billing-create to update to a paid plan.\n\nWorkflow (Tasks, Worklogs, Approvals, Todos)\n\nWorkspaces and shares support an optional workflow layer that adds structured task management, activity logging, approval gates, and simple checklists. Workflow features are controlled by a toggle -- they must be explicitly enabled before use. On shares, workflow access requires admin or named member role -- guests and view-only users cannot access workflow features.\n\nEnabling Workflow\nWorkspaces: workspace action enable-workflow with workspace_id\nShares: share action enable-workflow with share_id\n\nCheck whether workflow is enabled via workspace action details or share action details -- look for workflow: true in the response.\n\nDisabling workflow (workspace action disable-workflow or share action disable-workflow) makes all workflow data inaccessible but preserves it. Re-enabling restores access.\n\nTask Lists and Tasks\n\nTasks are organized into lists. Each workspace or share can have multiple task lists, and each list contains individual tasks.\n\nTask lists have a name and optional description. Create with task action create-list, list with task action list-lists.\nTasks have a title, description, status, priority, assignee, dependencies, and optional node link. Create with task action create-task, list with task action list-tasks.\nStatuses: pending, in_progress, complete, blocked\nPriorities: 0 = none, 1 = low, 2 = medium, 3 = high, 4 = critical\nAssignees are profile IDs (workspace or share members). Use task action assign-task to assign or unassign.\nBulk operations: task action bulk-status changes status on up to 100 tasks at once.\nMoving tasks: task action move-task moves a task from one list to another within the same profile. Requires the source list_id, task_id, and target_task_list_id. Optionally set sort_order to control position in the target list (default: 0).\nReordering: task action reorder-tasks sets the display order of tasks within a list. task action reorder-lists sets the display order of task lists within a profile. Pass arrays of IDs in the desired order; the server converts them to {id, sort_order} objects for the API.\nCreator tracking: Tasks and task lists include a created_by field (profile ID of the creator).\nMarkdown output: Pass format: \"md\" to get human-readable markdown instead of JSON.\nWorklogs\n\nWorklogs are append-only chronological activity logs scoped to tasks, task lists, storage nodes, or profiles. Entries cannot be edited or deleted after creation.\n\nEntries: Regular log entries appended with worklog action append. Use for progress updates, decisions, reasoning, and status changes.\nInterjections: Priority corrections created with worklog action interject. Interjections are always urgent and require acknowledgement from other participants.\nAcknowledgement: worklog action acknowledge marks an interjection as seen. worklog action unacknowledged lists interjections that still need acknowledgement. Entries include an acknowledgable boolean -- when true, the entry is an unacknowledged interjection that can be acknowledged.\nResponse fields: Entries include acknowledged (boolean), acknowledgable (boolean), updated (ISO 8601 timestamp), and created (ISO 8601 timestamp).\nMarkdown output: Pass format: \"md\" for human-readable output.\nApprovals\n\nFormal approval requests scoped to tasks, storage nodes, or worklog entries. Use when a decision requires explicit sign-off.\n\nCreate: approval action create with profile_id, description (1-5000 chars), entity_type (\"task\", \"node\", or \"worklog_entry\"), and optionally approver_id (a single profile ID, must be an entity member).\nResolve: approval action resolve with resolve_action: \"approve\" or \"reject\" and an optional comment. Only designated approvers can resolve.\nStatuses: pending, approved, rejected\nMarkdown output: Pass format: \"md\" for human-readable output.\nTodos\n\nSimple flat checklists scoped to workspaces and shares. No nesting -- just a list of items that can be checked off.\n\nCreate: todo action create with a title.\nToggle: todo action toggle flips the done state of a single todo. todo action bulk-toggle sets done state on up to 100 todos at once.\nUpdate/Delete: todo action update changes title. todo action delete soft-deletes a todo.\nCreator tracking: Todos include a created_by field (profile ID of the creator).\nMarkdown output: Pass format: \"md\" for human-readable output.\nNotes as Agent Knowledge Layer\n\nNotes (type: \"note\") are markdown files stored in workspace storage (see Notes above). When combined with workflow features, notes become a knowledge layer:\n\nAutomatic AI indexing: When workspace intelligence is enabled, notes are ingested and indexed for RAG just like uploaded files.\nLink tasks to notes: Tasks can reference storage nodes, including notes. Create context notes for project background, requirements, or reference material, then create tasks that link to those notes for full context.\nWorklogs for reasoning: Use worklog entries to record decisions, progress, and reasoning over time. The chronological log builds a narrative that complements the structured task list.\nAI can search all context: With intelligence enabled, AI chat can search across notes, worklogs, task descriptions, and uploaded files -- giving comprehensive answers grounded in the project's full history.\n\nRecommended pattern: Create notes for project context and requirements. Create task lists for work phases. Link tasks to relevant notes. Log progress with worklogs. Request approvals for decisions. The AI can then answer questions like \"Why did we choose this approach?\" by searching across all of these artifacts.\n\nPermission Parameter Values\n\nSeveral tools use permission parameters with specific allowed values. Use these exact strings when calling the tools.\n\nOrganization Creation (org action create)\nParameter\tAllowed Values\tDefault\nperm_member_manage\tOwner only, Admin or above, Member or above\tMember or above\nindustry\tunspecified, technology, healthcare, financial, education, manufacturing, construction, professional, media, retail, real_estate, logistics, energy, automotive, agriculture, pharmaceutical, legal, government, non_profit, insurance, telecommunications, research, entertainment, architecture, consulting, marketing\tunspecified\nbackground_mode\tstretched, fixed\tstretched\nWorkspace Creation (org action create-workspace) and Update (workspace action update)\nParameter\tAllowed Values\tDefault\nperm_join\tOnly Org Owners, Admin or above, Member or above\tMember or above\nperm_member_manage\tAdmin or above, Member or above\tMember or above\nShare Creation (share action create)\nParameter\tAllowed Values\tDefault\ntype\tsend, receive, exchange\texchange\nstorage_mode\tindependent, workspace_folder\tindependent\naccess_options\tOnly members of the Share or Workspace, Members of the Share, Workspace or Org, Anyone with a registered account, Anyone with the link\tOnly members of the Share or Workspace\ninvite\towners, guests\towners\nnotify\tnever, notify_on_file_received, notify_on_file_sent_or_received\tnever\ndisplay_type\tlist, grid\tgrid\nintelligence\ttrue, false\tfalse\ncomments_enabled\ttrue, false\ttrue\ndownload_enabled\ttrue, false\ttrue\nguest_chat_enabled\ttrue, false\tfalse\nworkspace_style\ttrue, false\ttrue\nbackground_image\t0-128\t0\n\nShare constraints:\n\nReceive and Exchange shares cannot use Anyone with the link access -- this option is only available for Send shares.\nPassword protection (password parameter) is only allowed when access_options is Anyone with the link.\nExpiration (expires parameter in MySQL format YYYY-MM-DD HH:MM:SS) is not allowed on workspace_folder shares.\nField length and format constraints for custom_name, title, and description are documented in the Profile Field Constraints table below.\nColor parameters (accent_color, background_color1, background_color2) accept JSON strings.\ncreate_folder creates a new workspace folder for the share when used with storage_mode='workspace_folder'.\nProfile Field Constraints\n\nAll profile fields are validated server-side. Requests that violate these constraints are rejected with a 400 error.\n\nEntity\tField\tAPI Key\tMin\tMax\tPattern\tRequired\tNullable\nOrg\tdomain\tdomain\t2\t63\t^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$\tYes (create)\tNo\nOrg\tname\tname\t3\t100\tNo control chars\tYes\tNo\nOrg\tdescription\tdescription\t10\t1000\tNo control chars\tNo\tYes\nWorkspace\tfolder_name\tfolder_name\t4\t80\t^[\\p{L}\\p{N}-]+$ (letters, digits, hyphens)\tYes (create)\tNo\nWorkspace\tname\tname\t2\t100\tNo control chars\tYes\tNo\nWorkspace\tdescription\tdescription\t10\t1000\tNo control chars\tNo\tYes\nShare\tcustom_name\tcustom_name\t4\t80\t^[\\p{L}\\p{N}]+$ (letters, digits only)\tYes (create)\tNo\nShare\tcustom_url\tcustom_url\t10\t100\t—\tYes\tYes\nShare\ttitle\ttitle\t2\t80\tNo control chars\tYes\tYes\nShare\tdescription\tdescription\t10\t500\tNo control chars\tNo\tYes\n\"No control chars\" = rejects Unicode control characters (\\p{C})\nOrg domain: lowercase ASCII alphanumeric + hyphens; cannot start/end with hyphen\nWorkspace folder_name: Unicode letters, digits, and hyphens. Globally unique -- not scoped to an org. Recommend {org_id}-{name} convention to avoid collisions (auto-applied by create-workspace when name is taken)\nShare custom_name: Unicode letters and digits only (no hyphens or special chars)\nShare description max is 500 (org/workspace is 1000)\n4. Agent Plan -- Free Tier\n\nThe agent plan is a free tier designed for AI agents. No credit card, no trial period, no expiration. Enough resources to build and demonstrate value, with room to grow when the org transfers to a human on a paid plan.\n\nResource Limits\nResource\tIncluded\nPrice\t$0 -- no credit card, no trial period, no expiration\nStorage\t50 GB\nMax file size\t1 GB\nMonthly credits\t5,000 (resets every 30 days)\nWorkspaces\t5\nShares\t50\nMembers per workspace\t5\nShare invitations\t10 per share\nAccount auto-deletion\tNever\nCredit Costs\n\nAll platform activity consumes credits from the monthly 5,000 allowance:\n\nResource\tCost\nStorage\t100 credits/GB\nBandwidth\t212 credits/GB\nAI chat tokens\t1 credit per 100 tokens\nDocument pages ingested\t10 credits/page\nVideo ingested\t5 credits/second\nAudio ingested\t0.5 credits/second\nImages ingested\t5 credits/image\nFile conversions\t25 credits/conversion\n\nWhen credits run out, the org enters a reduced-capability state and API calls return 402 Payment Required. The org is never deleted. Use org action limits to check current credit usage and remaining balance.\n\nWhen you hit 402 or run low on credits:\n\nAgent account (created via auth action signup): Transfer the org to the human. Call org action transfer-token-create to generate a transfer token, then send the human the claim URL: https://go.fast.io/claim?token=<token>. Once they claim the org they can upgrade to a paid plan with unlimited credits. You retain admin access and can resume work immediately after the upgrade. This is the expected workflow -- agents build on the free plan, then hand off to humans who pay when they are ready.\nHuman account (signed in via auth action signin): You cannot use the transfer/claim API. Tell the user they need to upgrade the org's billing plan directly. They can do this from the Fast.io dashboard or by calling org action billing-create to update their subscription to a paid plan.\nAfter Transfer -- Human Plan Options\n\nOnce an agent transfers an org to a human, the human gets a free plan (credit-based, no trial period) and can upgrade:\n\nFeature\tAgent (Free)\tFree (Human)\tPro\tBusiness\nMonthly credits\t5,000\t5,000\tUnlimited\tUnlimited\nStorage\t50 GB\t50 GB\t1 TB\t5 TB\nMax file size\t1 GB\t1 GB\t25 GB\t50 GB\nWorkspaces\t5\t5\t10\t1,000\nShares\t50\t50\t1,000\t50,000\n\nThe transfer flow is the primary way agents deliver value: set everything up on the free agent plan, then hand it off. The human upgrades when they are ready, and the agent retains admin access to keep managing things.\n\n5. Tool Categories\n\nThe 19 tools use action-based routing. Each tool covers a specific area of the Fast.io platform and exposes multiple actions.\n\nauth\n\nAuthentication, sign-in/sign-up, two-factor authentication, API key management, and OAuth session management. This is always the starting point for any agent interaction.\n\nActions: signin, signout, signup, check, session, status, set-api-key, email-check, email-verify, password-reset-request, password-reset, 2fa-verify, 2fa-status, 2fa-enable, 2fa-disable, 2fa-send, 2fa-verify-setup, pkce-login, pkce-complete, api-key-create, api-key-update, api-key-list, api-key-get, api-key-delete, oauth-list, oauth-details, oauth-revoke, oauth-revoke-all\n\nuser\n\nRetrieve and update the current user profile, search for other users, manage invitations, upload and delete user assets (profile photos), check account eligibility, and list shares the user belongs to.\n\nActions: me, update, search, close, details-by-id, profiles, allowed, org-limits, list-shares, invitation-list, invitation-details, accept-all-invitations, asset-upload, asset-delete, asset-types, asset-list\n\norg\n\nOrganization CRUD, member management, billing and subscription operations, workspace creation, invitation workflows, asset management (upload, delete), organization discovery, and ownership transfer.\n\nActions: list, details, create, update, close, public-details, limits, list-workspaces, list-shares, create-workspace, billing-plans, billing-create, billing-cancel, billing-details, billing-activate, billing-reset, billing-members, billing-meters, members, invite-member, remove-member, update-member-role, member-details, leave, transfer-ownership, join, invitations-list, invitation-update, invitation-delete, transfer-token-create, transfer-token-list, transfer-token-delete, transfer-claim, discover-all, discover-available, discover-check-domain, discover-external, asset-upload, asset-delete, asset-types, asset-list\n\nworkspace\n\nWorkspace-level settings, lifecycle operations (update, delete, archive, unarchive), listing and importing shares, managing workspace assets, workspace discovery, notes (create, read, update), quickshare management, metadata operations (template CRUD, assignment, file metadata get/set/delete, AI extraction), and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).\n\nActions: list, details, update, delete, archive, unarchive, members, list-shares, import-share, available, check-name, create-note, read-note, update-note, quickshare-get, quickshare-delete, quickshares-list, metadata-template-create, metadata-template-delete, metadata-template-list, metadata-template-details, metadata-template-update, metadata-template-clone, metadata-template-assign, metadata-template-unassign, metadata-template-resolve, metadata-template-assignments, metadata-get, metadata-set, metadata-delete, metadata-extract, metadata-list-files, metadata-list-templates-in-use, metadata-versions, enable-workflow, disable-workflow\n\nshare\n\nShare CRUD, public details, archiving, password authentication, asset management, share name availability checks, and workflow toggle (enable/disable tasks, worklogs, approvals, and todos).\n\nActions: list, details, create, update, delete, public-details, archive, unarchive, password-auth, members, available, check-name, quickshare-create, enable-workflow, disable-workflow\n\nstorage\n\nFile and folder operations within workspaces and shares. List, list recently modified files across all folders, create folders, move, copy, delete, rename, purge, restore, search, add files from uploads, add share links, transfer nodes, manage trash, version operations, file locking, and preview/transform URL generation. Requires context_type parameter (workspace or share).\n\nActions: list, recent, details, search, trash-list, create-folder, copy, move, delete, rename, purge, restore, add-file, add-link, transfer, version-list, version-restore, lock-acquire, lock-status, lock-release, preview-url, preview-transform\n\nupload\n\nFile upload operations. Single-step text file upload, chunked upload lifecycle (create session, stage binary blobs, upload chunks as plain text / base64 / blob reference, finalize, check status, cancel), web imports from external URLs, upload limits and file extension restrictions, and session management.\n\nActions: create-session, chunk, finalize, status, cancel, list-sessions, cancel-all, chunk-status, chunk-delete, stage-blob, text-file, web-import, web-list, web-cancel, web-status, limits, extensions\n\ndownload\n\nGenerate download URLs and ZIP archive URLs for workspace files, share files, and quickshare links. MCP tools cannot stream binary data -- these actions return URLs that can be opened in a browser or passed to download utilities. Requires context_type parameter (workspace or share) for file-url and zip-url actions. Responses include a resource_uri field (e.g. download://workspace/{id}/{node_id}) that MCP clients can use to read file content directly via MCP resources. Direct download URLs include ?error=html so errors render as human-readable HTML in browsers.\n\nActions: file-url, zip-url, quickshare-details\n\nai\n\nAI-powered chat with RAG, semantic search, and document analysis in workspaces and shares. Create chats, send messages, read AI responses (with polling), list and manage chats, search indexed documents and code by meaning with relevance scores, publish private chats, generate AI share markdown, track AI token usage, and auto-title generation. Requires context_type parameter (workspace or share).\n\nActions: chat-create, chat-list, chat-details, chat-update, chat-delete, chat-publish, message-send, message-list, message-details, message-read, search, share-generate, transactions, autotitle\n\ncomment\n\nComments are scoped to {entity_type}/{parent_id}/{node_id} where entity_type is workspace or share, parent_id is the 19-digit profile ID, and node_id is the storage node opaque ID. List comments on files (per-node and profile-wide with sort/limit/offset/filter params), add comments with optional reference anchoring (image regions, video/audio timestamps, PDF pages with text selection, text selections in markdown/notes), single-level threaded replies, recursive single delete, non-recursive bulk delete, get comment details, emoji reactions (one per user per comment), and workflow linking (link/unlink comments to tasks or approvals, reverse lookup). Comments use JSON request bodies.\n\nActions: list, list-all, add, delete, bulk-delete, details, reaction-add, reaction-remove, link, unlink, linked\n\nevent\n\nSearch the audit/event log with rich filtering by category, subcategory, and event name (see Event Filtering Reference in section 7 for the full taxonomy). Get AI-powered summaries of activity, retrieve full details for individual events, list recent activity, and long-poll for activity changes.\n\nActions: search, summarize, details, activity-list, activity-poll\n\nmember\n\nMember management for organizations, workspaces, and shares. Add, remove, update roles, transfer ownership, leave, join, and join via invitation. Requires entity_type parameter (workspace or share).\n\nActions: add, remove, details, update, transfer-ownership, leave, join, join-invitation\n\ninvitation\n\nInvitation management for organizations, workspaces, and shares. List invitations, list by state, update, and delete. Requires entity_type parameter (workspace or share).\n\nActions: list, list-by-state, update, delete\n\nasset\n\nAsset management (upload, delete, list, read) for organizations, workspaces, shares, and users. Requires entity_type parameter (org, workspace, share, or user).\n\nActions: upload, delete, types, list, read\n\ntask\n\nTask list and task management for workspaces and shares. Create and manage task lists, then create tasks within them with statuses, priorities, assignees, and dependencies. Supports bulk status changes, reordering, and markdown output. Tasks and lists include created_by (creator profile ID). Requires workflow to be enabled on the target entity.\n\nActions: list-lists, create-list, list-details, update-list, delete-list, list-tasks, create-task, task-details, update-task, delete-task, change-status, assign-task, bulk-status, move-task, reorder-tasks, reorder-lists\n\nworklog\n\nActivity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. Also create urgent interjections that require acknowledgement. Entries are append-only and permanent. Requires workflow to be enabled on the target entity.\n\nActions: append, list, interject, details, acknowledge, unacknowledged\n\napproval\n\nFormal approval requests scoped to tasks, storage nodes, or worklog entries. Create approval requests with designated approvers, then resolve them with approve or reject decisions. Requires workflow to be enabled on the target entity.\n\nActions: list, create, details, resolve\n\ntodo\n\nSimple flat checklists scoped to workspaces and shares. Create, update, delete, toggle todos individually or in bulk. Todos include created_by (creator profile ID). No nesting. Requires workflow to be enabled on the target entity.\n\nActions: list, create, details, update, delete, toggle, bulk-toggle\n\napps\n\nInteractive MCP App widget discovery and launching. List available widgets, get details for a specific widget, launch a widget with workspace or share context, and find widgets associated with a specific tool domain.\n\nActions: list, details, launch, get-tool-apps\n\n6. Common Workflows\n1. Create an Account and Sign In\n\nSee Choosing the Right Approach in section 2 for which option fits your scenario.\n\nOption 1 -- Autonomous agent (new account):\n\nOptionally call auth action email-check with the desired email to verify availability.\nauth action signup with first_name, last_name, email, and password -- registers as an agent account (agent=true is sent automatically) and signs in immediately.\nauth action email-verify with email -- sends a verification code. Then auth action email-verify with email and email_token -- validates the code. Required before using most endpoints.\norg action create to create a new org on the agent plan, or org action list to check existing orgs.\n\nOption 2 -- Assisting a human (API key):\n\nThe human creates an API key at https://go.fast.io/settings/api-keys and provides it to the agent.\nCall auth action set-api-key with the API key. The key is validated against the API and stored in the session -- all subsequent tool calls are authenticated automatically. No account creation needed.\norg action list and org action discover-external to discover all available organizations (see Org Discovery).\n\nOption 3 -- Agent invited to a human's org:\n\nCreate an agent account with auth action signup (same as Option 1).\nHave the human invite you via org action invite-member or member action add (with entity_type: \"workspace\").\nAccept invitations with user action accept-all-invitations.\norg action list and org action discover-external to discover all available orgs (see Org Discovery). If the human only invited you to a workspace (not the org), it will only appear via discover-external.\n\nReturning users:\n\nauth action signin with email and password.\nIf two_factor_required: true, call auth action 2fa-verify with the 2FA code.\norg action list and org action discover-external to discover all available organizations (see Org Discovery).\n2. Browse and Download a File\norg action list and org action discover-external -- discover all available organizations (see Org Discovery). Note the org_id values.\norg action list-workspaces with org_id -- get workspaces in the organization. Note the workspace_id values.\nstorage action list with context_type: \"workspace\", context_id (workspace ID), and node_id: \"root\" -- browse the root folder. Note the node_id values for files and subfolders.\nstorage action details with context_type: \"workspace\", context_id, and node_id -- get full details for a specific file (name, size, type, versions).\ndownload action file-url with context_type: \"workspace\", context_id, and node_id -- get a temporary download URL with an embedded token. The response also includes a resource_uri (e.g. download://workspace/{id}/{node_id}) that MCP clients can use to read file content directly. Return the download URL to the user, or use the resource URI to read the file through MCP.\n3. Upload a File to a Workspace\n\nText files (recommended): Use upload action text-file with profile_type: \"workspace\", profile_id, parent_node_id, filename, and content (plain text). This single action uploads the file and returns new_file_id on success. Internally it uses the Fast.io single-request upload pattern (one multipart POST with the file data), so there is no separate chunking, finalization, or polling step. Use this for code, markdown, CSV, JSON, config files, and any other text content.\n\nBinary files (choose the right approach):\n\nUnderstanding upload constraints. The Fast.io API requires each chunk to be ≥ 1 MB (except the last chunk of a session, which may be smaller). MCP tool calls have a practical transport limit of ~64 KB of raw binary per call (~96 KB base64). This means multi-chunk binary uploads through MCP tool calls alone will fail for files larger than ~64 KB — each MCP-sized chunk is far below the 1 MB API minimum. Use upload action limits to check your plan's exact chunk size and file size limits.\n\nOption A: web-import (preferred for URL-accessible files) If the file has a URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use upload action web-import. Single call, no chunking, no base64. See Workflow 4 below.\n\nOption B: Single-chunk upload for small binary files (≤ ~64 KB) Small files that fit in one MCP tool call can be uploaded as a single chunk:\n\nupload action create-session with profile_type, profile_id, parent_node_id, filename, and filesize in bytes.\nupload action chunk with upload_id, chunk_number: 1, and data (base64-encoded file, ≤96 KB base64 / ~64 KB binary). Since this is the only chunk, the API's \"1 small chunk allowed\" rule permits it.\nupload action finalize with upload_id.\n\nOption C: POST /blob sidecar endpoint for larger binary files For files > ~64 KB, use the HTTP blob endpoint to bypass MCP transport limits. The POST /blob endpoint accepts raw binary via HTTP (no base64, no size splitting within MCP). Stage blobs of ≥ 1 MB each (except the last), then reference them in chunk calls:\n\nupload action create-session with profile_type, profile_id, parent_node_id, filename, and filesize.\nFor each chunk: POST /blob with raw binary (≥ 1 MB, ≤ 100 MB). Returns blob_id.\nupload action chunk with upload_id, chunk_number, and blob_ref: \"<blob_id>\".\nupload action finalize with upload_id.\n\nOption D: External upload tooling For reliable binary uploads of any size, use an external HTTP client (Python requests, curl, etc.) to call the Fast.io REST API upload endpoints directly, bypassing MCP transport constraints entirely. Use MCP for control-plane tasks (session creation, finalization, status) and the external client for the data plane (chunk uploads).\n\nThree options for passing chunk data (provide exactly one):\n\ncontent — for text (strings, code, JSON, etc.). Do NOT use data for text.\ndata — base64-encoded binary. Limited by MCP transport to ~96 KB base64 (~64 KB binary) per call. Only practical for single-chunk small files.\nblob_ref — blob ID from upload action stage-blob or POST /blob. The POST /blob approach is recommended for larger files since it bypasses MCP transport limits.\n\nupload action finalize with upload_id triggers file assembly and polls until stored. Returns the final session state with status: \"stored\" or \"complete\" on success (including new_file_id), or throws on failure. Terminal failure states: assembly_failed (chunks could not be assembled) and store_failed (assembled file could not be stored — check status_message for details). The file is automatically added to the target workspace and folder specified during session creation -- no separate add-file call is needed.\n\nUpload status states:\n\nStatus\tMeaning\tTerminal?\nready\tSession created, awaiting chunks\tNo\nuploading\tChunks being received\tNo\nassembling\tAssembly in progress\tNo\ncomplete\tAssembled, awaiting storage import\tNo\nstoring\tBeing imported to storage\tNo\nstored\tDone — file is in storage, new_file_id available\tYes (success)\nassembly_failed\tAssembly error\tYes (failure)\nstore_failed\tStorage import failed\tYes (failure)\n\nNote: storage action add-file is only needed if you want to link the upload to a different location than the one specified during session creation.\n\nSame-name uploads: If a file with the same name already exists in the target folder, the upload replaces (overwrites) it. The previous content is preserved as a version. To keep both files, rename before uploading.\n\n4. Import a File from URL\n\nUse this when you have a file URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox) and want to add it to a workspace without downloading locally.\n\nupload action web-import with url (the source URL), profile_type: \"workspace\", profile_id (the workspace ID), and parent_node_id (target folder or \"root\"). Returns an upload_id.\nupload action web-status with upload_id -- check import progress. The server downloads the file, scans it, generates previews, and indexes it for AI (if intelligence is enabled).\nThe file appears in the workspace storage tree once the job completes.\n5. Deliver Files to a Client\n\nCreate a branded, professional share for outbound file delivery. This replaces raw download links, email attachments, and S3 presigned URLs.\n\nUpload files to the workspace (see workflow 3 or 4).\nshare action create with workspace_id, name, and type: \"send\" -- creates a Send share. Returns a share_id.\nshare action update with share_id to configure:\npassword -- require a password for access\nexpiry_date -- auto-expire the share after a set period\naccess_level -- Members Only, Org Members, Registered Users, or Public\nallow_downloads -- enable or disable file downloads\nBranding options: background_color, accent_color, gradient_color\npost_download_message and post_download_url -- show a message after download\nmember action add with entity_type: \"share\", entity_id (share ID), and email_or_user_id -- adds the recipient. An invitation is sent if they do not have a Fast.io account.\nasset action upload with entity_type: \"share\" and entity_id (share ID) to add a logo or background image for branding.\nThe recipient sees a branded page with instant file preview, not a raw download link.\n6. Collect Documents from a User\n\nCreate a Receive share so humans can upload files directly to you -- no email attachments, no cloud drive links.\n\nshare action create with workspace_id, name (e.g., \"Upload your tax documents here\"), and type: \"receive\". Returns a share_id.\nshare action update with share_id to set access level, expiration, and branding as needed.\nmember action add with entity_type: \"share\", entity_id (share ID), and email_or_user_id to invite the uploader.\nThe human uploads files through a clean, branded interface.\nFiles appear in your workspace. If intelligence is enabled, they are auto-indexed by AI.\nUse ai action chat-create with context_type: \"share\" scoped to the receive share's folder to ask questions like \"Are all required forms present?\"\n7. Build a Knowledge Base\n\nCreate an intelligent workspace that auto-indexes all content for RAG queries.\n\norg action create-workspace with org_id, name, and intelligence: \"true\" (this workflow specifically requires intelligence for RAG).\nUpload reference documents (see workflow 3 or 4). AI auto-indexes and summarizes everything on upload.\nai action chat-create with context_type: \"workspace\", context_id (workspace ID), query_text, type: \"chat_with_files\", and folders_scope (comma-separated nodeId:depth pairs) to query across folders or the entire workspace.\nai action message-read with context_type: \"workspace\", context_id, chat_id, and message_id -- polls until the AI response is complete. Returns response_text and citations pointing to specific files, pages, and snippets.\nstorage action search with context_type: \"workspace\", context_id, and a query string for semantic search -- find files by meaning, not just filename.\nAnswers include citations to specific pages and files. Pass these back to the user with source references.\n8. Ask AI About Files\n\nTwo modes depending on whether intelligence is enabled on the workspace.\n\nWith intelligence (persistent index):\n\nai action chat-create with context_type: \"workspace\", context_id (workspace ID), query_text, type: \"chat_with_files\", and either files_scope (comma-separated nodeId:versionId pairs) or folders_scope (comma-separated nodeId:depth pairs, depth range 1-10). Important: files_scope and files_attach are mutually exclusive — sending both will error. Returns chat_id and message_id.\nai action message-read with context_type: \"workspace\", context_id, chat_id, and message_id -- polls the API up to 15 times (2-second intervals, approximately 30 seconds) until the AI response is complete. Returns response_text and citations. Tip: If the built-in polling window expires, use event action activity-poll with the workspace ID instead of calling message-read in a loop — see the Activity Polling section above.\nai action message-send with context_type: \"workspace\", context_id, chat_id, and query_text for follow-up questions. Returns a new message_id.\nai action message-read again with the new message_id to get the follow-up response.\n\nWithout intelligence (file attachments):\n\nai action chat-create with context_type: \"workspace\", context_id, query_text, type: \"chat_with_files\", and files_attach pointing to specific files (comma-separated nodeId:versionId, max 20 files / 200 MB). Files must have ai.attach: true (check via storage action details). The AI reads attached files directly without persistent indexing.\nai action message-read to get the response. No ingestion credit cost -- only chat token credits are consumed.\n9. Set Up a Project for a Human\n\nThe full agent-to-human handoff workflow. This is the primary way agents deliver value on Fast.io.\n\norg action create -- creates a new org on the agent billing plan. The agent becomes owner. An agent-plan subscription (free, 50 GB, 5,000 credits/month) is created automatically.\norg action create-workspace with org_id and name -- create workspaces for each project area.\nstorage action create-folder with context_type: \"workspace\" to build out folder structure (templates, deliverables, reference docs, etc.).\nUpload files to each workspace (see workflow 3 or 4).\nshare action create with type: \"send\" for client deliverables, type: \"receive\" for intake/collection.\nshare action update to configure branding, passwords, expiration, and access levels on each share.\norg action invite-member or member action add with entity_type: \"workspace\" to invite team members.\norg action transfer-token-create with org_id -- generates a transfer token valid for 72 hours. Send the claim URL (https://go.fast.io/claim?token=<token>) to the human.\nHuman clicks the link and claims the org. They become owner, agent retains admin access. Human gets a free plan.\n10. Manage Organization Billing\norg action billing-plans -- list all available billing plans with pricing and features.\norg action billing-create with org_id and optionally billing_plan -- create or update a subscription. For new subscriptions, this creates a Stripe Setup Intent.\norg action billing-details with org_id -- check the current subscription status, Stripe customer info, and payment details.\norg action limits with org_id -- check credit usage against plan limits, including storage, transfer, AI tokens, and billing period info.\n11. Manage Tasks in a Workspace\n\nTrack work with structured task lists and tasks.\n\nworkspace action enable-workflow with workspace_id -- enable workflow features (required before using task, worklog, approval, or todo tools).\ntask action create-list with profile_type: \"workspace\", profile_id (workspace ID), and name -- create a task list. Returns list_id.\ntask action create-task with list_id, title, and optionally description, priority (0-4), assignee_id, dependencies, node_id, and status -- add tasks to the list.\ntask action list-tasks with list_id -- view all tasks, optionally filtered by status or assignee.\ntask action change-status with list_id, task_id, and status -- update task progress (pending → in_progress → complete).\ntask action assign-task with list_id, task_id, and assignee_id -- assign work to team members.\ntask action bulk-status with list_id, task_ids, and status -- batch-update up to 100 tasks at once.\n12. Full Agent Workflow (Tasks + Worklogs + Approvals)\n\nThe complete agentic workflow pattern: plan work, execute with logging, and gate decisions with approvals.\n\nworkspace action enable-workflow with workspace_id -- enable workflow features on the workspace.\nworkspace action create-note -- create context notes with project background, requirements, and reference material.\ntask action create-list -- create task lists for each work phase (e.g., \"Research\", \"Implementation\", \"Review\").\ntask action create-task -- add tasks linked to context. Include descriptive titles and reference note node_ids in descriptions.\ntask action change-status with status: \"in_progress\" -- mark a task as started.\nworklog action append with entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type \"profile\"), and content -- log progress, decisions, and reasoning as you work. Build a chronological narrative.\nIf a priority correction is needed: worklog action interject -- creates an urgent entry that requires acknowledgement from other participants.\nworklog action unacknowledged -- check for unacknowledged interjections before proceeding.\nworklog action acknowledge -- mark interjections as seen.\nWhen a decision needs sign-off: approval action create with profile_id, description, entity_type (\"task\", \"node\", or \"worklog_entry\"), and optionally approver_id -- request formal approval.\napproval action resolve with resolve_action: \"approve\" or \"reject\" and optional comment -- approvers resolve the request.\ntask action change-status with status: \"complete\" -- mark completed tasks.\ntodo action create -- track simple checklist items alongside the main task flow.\nWith intelligence enabled, ai action chat-create -- the AI can search across notes, task descriptions, and worklogs to answer questions about the project.\n7. Key Patterns and Gotchas\nID Format\n\nProfile IDs (org, workspace, share, user) are 19-digit numeric strings. Most endpoints also accept custom names as identifiers -- workspace folder names, share URL names, org domain names, or user email addresses. Both formats are interchangeable in URL path parameters.\n\nAll other IDs (node IDs, upload IDs, chat IDs, comment IDs, invitation IDs, etc.) are 30-character alphanumeric opaque IDs (displayed with hyphens). Do not apply numeric validation to these.\n\nPagination\n\nTwo pagination styles are used depending on the endpoint:\n\nCursor-based (storage list endpoints): sort_by, sort_dir, page_size, and cursor. The response includes a next_cursor value when more results are available. Pass this cursor in the next call to retrieve the next page. Page sizes are typically 100, 250, or 500. Used by: storage action list (with context_type: \"workspace\" or \"share\").\n\nLimit/offset (all other list endpoints): limit (1-500, default 100) and offset (default 0). Used by: org actions list, members, list-workspaces, list-shares, billing-members, discover-all, discover-external; share actions list, members; workspace actions list, members, list-shares; user action list-shares; storage action search.\n\nBinary Downloads\n\nMCP tools return download URLs -- they never stream binary content directly. download action file-url (with context_type: \"workspace\" or \"share\") and download action quickshare-details call the /requestread/ endpoint to obtain a temporary token, then construct a full download URL. The agent should return these URLs to the user or pass them to a download utility.\n\ndownload actions zip-url (workspace and share) return the URL along with the required Authorization header value.\n\nBinary Uploads\n\nThree approaches for uploading binary data as chunks, each suited to different situations.\n\nPrefer web-import for URL-accessible files. If the binary file is accessible via any URL (HTTP/HTTPS, Google Drive, OneDrive, Box, Dropbox), use upload action web-import instead of chunked upload. It's a single tool call — no chunking, no base64, no session management. Only use chunked upload when you have local binary data with no URL available.\n\nChunk size limit for MCP agents. MCP tool parameters pass through the AI model's output, which limits how much data you can include in a single tool call. Keep each chunk's base64 data under 32 KB (~24 KB of binary). For example, a 145 KB PDF needs at least 6 chunks, and even a 17 KB file should be split into 1-2 chunks rather than assumed to fit in one call. The create-session response includes a recommended_mcp_chunk_bytes hint (default 24576) — use it to calculate the number of chunks: ceil(filesize / recommended_mcp_chunk_bytes). Always split files into multiple chunks when using data or stage-blob through MCP tool calls.\n\nCommon pitfall: do NOT pre-process binary data into intermediate formats. Pass base64 data directly in the data parameter of chunk or stage-blob tool calls. Do NOT read binary files into Python/JSON variables, pickle them, or save to temp files hoping to reference them later — the MCP tool can only receive data through its own parameters. If you have local binary files, base64-encode them in ≤32 KB segments and pass each segment directly as the data parameter in sequential stage-blob → chunk calls. Create upload sessions immediately before uploading — sessions expire, so do not debug between creating a session and uploading chunks.\n\n1. data parameter (base64) — simplest for MCP agents\n\nPass base64-encoded binary directly in the data parameter of upload action chunk. No extra steps required. Works with any MCP client. Adds ~33% size overhead from base64 encoding. Split files into chunks of ≤24 KB binary (≤32 KB base64) to stay within MCP client parameter limits.\n\n2. stage-blob action — MCP tool-based blob staging\n\nUse upload action stage-blob with data (base64) to pre-stage binary data as a blob. Returns a blob_id that you pass as blob_ref in the chunk call. Useful when you want to decouple staging from uploading, or when preparing multiple chunks in advance. The same 32 KB base64 limit per call applies — stage one chunk-sized piece at a time.\n\nFlow:\n\nupload action stage-blob with data (base64-encoded binary, ≤32 KB). Returns { \"blob_id\": \"<uuid>\", \"size\": <bytes> }.\nupload action chunk with blob_ref: \"<blob_id>\". The server retrieves the staged bytes and uploads them.\n\n3. POST /blob endpoint — HTTP blob staging for non-MCP clients\n\nA sidecar HTTP endpoint that accepts raw binary data outside the JSON-RPC pipe. This avoids base64 encoding entirely — useful for clients that can make direct HTTP requests alongside MCP tool calls. No chunk size splitting needed with this approach.\n\nFlow:\n\nPOST /blob with headers Mcp-Session-Id: <session_id> and Content-Type: application/octet-stream. Send raw binary bytes as the request body. Returns { \"blob_id\": \"<uuid>\", \"size\": <bytes> } (HTTP 201).\nupload action chunk with blob_ref: \"<blob_id>\".\n\nBlob constraints (apply to both staging methods):\n\nBlobs expire after 5 minutes. Stage and consume them promptly.\nEach blob is consumed (deleted) on first use — it cannot be reused.\nMaximum blob size: 100 MB.\nSSE transport clients must add ?transport=sse to the /blob URL.\nEvent Filtering Reference\n\nThe event tool's search and summarize actions accept category, subcategory, and event parameters to narrow results. Use these to target specific activity instead of scanning all events.\n\nEvent Categories\nCategory\tWhat It Covers\nuser\tAccount creation, updates, deletion, avatar changes\norg\tOrganization lifecycle, settings, transfers\nworkspace\tWorkspace creation, updates, archival, file operations\nshare\tShare lifecycle, settings, file operations\nnode\tFile and folder operations (cross-profile)\nai\tAI chat, summaries, RAG indexing\ninvitation\tMember invitations sent, accepted, declined\nbilling\tSubscriptions, trials, credit usage\ndomain\tCustom domain configuration\napps\tApplication integrations\nmetadata\tMetadata extraction, templates, key-value updates\nEvent Subcategories\nSubcategory\tWhat It Covers\nstorage\tFile/folder add, move, copy, delete, restore, download\ncomments\tComment created, updated, deleted, mentioned, replied, reaction\nmembers\tMember added/removed from org, workspace, or share\nlifecycle\tProfile created, updated, deleted, archived\nsettings\tConfiguration and preference changes\nsecurity\tSecurity-related events (2FA, password)\nauthentication\tLogin, SSO, session events\nai\tAI processing, chat, indexing\ninvitations\tInvitation management\nbilling\tSubscription and payment events\nassets\tAvatar/asset updates\nupload\tUpload session management\ntransfer\tCross-profile file transfers\nquickshare\tQuick share operations\nmetadata\tMetadata operations\nCommon Event Names\n\nFile operations (workspace): workspace_storage_file_added, workspace_storage_file_deleted, workspace_storage_file_moved, workspace_storage_file_copied, workspace_storage_file_updated, workspace_storage_file_restored, workspace_storage_folder_created, workspace_storage_folder_deleted, workspace_storage_folder_moved, workspace_storage_download_token_created, workspace_storage_zip_downloaded, workspace_storage_file_version_restored, workspace_storage_link_added\n\nFile operations (share): share_storage_file_added, share_storage_file_deleted, share_storage_file_moved, share_storage_file_copied, share_storage_file_updated, share_storage_file_restored, share_storage_folder_created, share_storage_folder_deleted, share_storage_folder_moved, share_storage_download_token_created, share_storage_zip_downloaded\n\nComments: comment_created, comment_updated, comment_deleted, comment_mentioned, comment_replied, comment_reaction\n\nMembership: added_member_to_org, added_member_to_workspace, added_member_to_share, removed_member_from_org, removed_member_from_workspace, removed_member_from_share, membership_updated\n\nWorkspace lifecycle: workspace_created, workspace_updated, workspace_deleted, workspace_archived, workspace_unarchived\n\nShare lifecycle: share_created, share_updated, share_deleted, share_archived, share_unarchived, share_imported_to_workspace\n\nAI: ai_chat_created, ai_chat_new_message, ai_chat_updated, ai_chat_deleted, ai_chat_published, node_ai_summary_created, workspace_ai_share_created\n\nMetadata: metadata_kv_update, metadata_kv_delete, metadata_kv_extract, metadata_template_update, metadata_template_delete, metadata_template_settings_update, metadata_view_update, metadata_view_delete, metadata_template_select\n\nQuick shares: workspace_quickshare_created, workspace_quickshare_updated, workspace_quickshare_deleted, workspace_quickshare_file_downloaded, workspace_quickshare_file_previewed\n\nInvitations: invitation_email_sent, invitation_accepted, invitation_declined\n\nUser: user_created, user_updated, user_deleted, user_email_reset, user_asset_updated\n\nOrg: org_created, org_updated, org_closed, org_transfer_token_created, org_transfer_completed\n\nBilling: subscription_created, subscription_cancelled, billing_free_trial_ended\n\nExample Queries\nRecent comments in a workspace: event action search with workspace_id and subcategory: \"comments\"\nFiles uploaded to a share: event action search with share_id and event: \"share_storage_file_added\"\nAll membership changes across an org: event action search with org_id and subcategory: \"members\"\nAI activity in a workspace: event action search with workspace_id and category: \"ai\"\nWho downloaded files from a share: event action search with share_id and event: \"share_storage_download_token_created\"\nActivity Polling\n\nThree mechanisms for detecting changes, listed from most to least preferred:\n\nevent action activity-poll — The server holds the connection for up to 95 seconds and returns immediately when something changes. Returns activity keys (e.g. ai_chat:{chatId}, storage, members) and a lastactivity timestamp for the next poll. Use this for any \"wait for something to happen\" scenario, including AI chat completion.\nWebSocket — For real-time push events. Best for live UIs.\nevent action activity-list — Retrieves recent activity events on demand. Use when you need a one-time snapshot rather than continuous monitoring.\n\nWhy this matters: Do not poll detail endpoints (like ai action message-read) in tight loops. Instead, use event action activity-poll to detect when something has changed, then fetch the details once.\n\nAI Message Completion\n\nai action message-read (with context_type: \"workspace\" or \"share\") implements built-in polling (up to 15 attempts, 2-second intervals). If the response is still processing after that window, use event action activity-poll with the workspace or share ID instead of calling the read action in a loop:\n\nCall event action activity-poll with entity_id set to the workspace/share ID.\nWhen the response includes an ai_chat:{chatId} key matching your chat, call ai action message-read once to get the completed response.\nActivity Poll Workflow\nMake an API call (e.g. ai action chat-create) and note the server_date field in the response.\nCall event action activity-poll with entity_id (workspace or share ID) and lastactivity set to the server_date value.\nThe server holds the connection. When something changes (or the wait period expires), it returns activity keys.\nInspect the keys to determine what changed, then fetch the relevant detail (e.g. ai action message-read, storage action list).\nUse the new lastactivity value from the poll response (or the latest server_date) for the next poll call. Repeat as needed.\nTrash, Delete, and Purge\nstorage action delete (with context_type: \"workspace\" or \"share\") moves items to the trash. They are recoverable.\nstorage action restore recovers items from the trash.\nstorage action purge permanently and irreversibly deletes items from the trash.\n\nAlways confirm with the user before calling purge operations.\n\nNode Types\n\nStorage nodes can be files, folders, notes, or links. The type is indicated in the storage details response. Notes are markdown files created with workspace action create-note, read with workspace action read-note, and updated with workspace action update-note. Links are share reference nodes created with storage action add-link.\n\nText Content and Newlines\n\nAll text content (notes, comments, worklogs, file uploads, descriptions) must use Unix-style line feeds (\\n, U+000A) for newlines. The frontend normalizes all line endings to \\n before saving -- Windows-style \\r\\n (CRLF) and legacy Mac \\r (CR) are converted automatically. Agents should use \\n exclusively to avoid mismatches in content comparison and display.\n\nEncoding rules:\n\nNewlines: Use \\n (U+000A). Never send \\r\\n or \\r alone.\nAllowed control characters: Only \\t (U+0009), \\n (U+000A), and \\r (U+000D) survive server-side sanitization. All other Unicode control characters (\\p{C}) are stripped.\nEmpty lines in markdown: Use two consecutive \\n characters (\\n\\n) for paragraph breaks. Do not use non-breaking spaces (U+00A0) or other whitespace characters as line placeholders.\nTrailing newlines: Content may or may not end with a trailing \\n. Do not assume either convention -- both are valid.\n\nThis applies to: workspace actions create-note and update-note, upload action text-file, comment action add, worklog actions append and interject, and any other tool that accepts free-text or markdown content.\n\nError Pattern\n\nFailed API calls throw errors with two fields: code (unique numeric error ID) and text (human-readable description). Tools surface these as error text in the MCP response. Common HTTP status codes include 401 (unauthorized), 403 (forbidden), 404 (not found), and 429 (rate limited).\n\nSession State\n\nThe auth token, user ID, email, and token expiry are persisted in the server session. There is no need to pass tokens between tool calls. The session survives across multiple tool invocations within the same MCP connection.\n\nHuman-Facing URLs\n\nMCP tools manage data via the API, but humans access Fast.io through a web browser. Always use the web_url field from tool responses -- it is a ready-to-use, clickable URL for the resource. Include it in your responses whenever you create or reference a workspace, share, file, note, or transfer. The human cannot see API responses directly -- the URL you provide is how they get to their content. Fall back to the URL patterns below only when web_url is absent (e.g., share-context storage operations):\n\nAutomatic web_url field. All entity-returning tool responses include a web_url field — a ready-to-use, human-friendly URL for the resource. NEVER construct URLs manually — always use the web_url field from tool responses. It appears on: org list/details/create/update/public-details/discover-*, org list-workspaces/list-shares, workspace list/details/update/available/list-shares, share list/details/create/update/public-details/available, storage list/details/search/trash-list/copy/move/rename/restore/add-file/create-folder/version-list/version-restore/preview-url/preview-transform, quickshare create/get/list, upload text-file/finalize, download file-url/quickshare-details, AI chat-create/chat-details/chat-list, transfer-token create/list, and notes create/update. Fall back to the URL patterns below only when web_url is absent (e.g., share context storage operations).\n\nOrganization domain values become subdomains: \"acme\" → https://acme.fast.io/. The base domain go.fast.io handles public routes that do not require org context.\n\nAuthenticated Links (require login)\nWhat the human needs\tURL pattern\nWorkspace root\thttps://{domain}.fast.io/workspace/{folder_name}/storage/root\nSpecific folder\thttps://{domain}.fast.io/workspace/{folder_name}/storage/{node_id}\nFile preview\thttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}\nFile with specific comment\thttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?comment={comment_id}\nFile at video/audio time\thttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?t={seconds}\nFile at PDF page\thttps://{domain}.fast.io/workspace/{folder_name}/preview/{node_id}?p={page_num}\nAI chat in workspace\thttps://{domain}.fast.io/workspace/{folder_name}/storage/root?chat={chat_id}\nNote in workspace\thttps://{domain}.fast.io/workspace/{folder_name}/storage/root?note={note_id}\nNote preview\thttps://{domain}.fast.io/workspace/{folder_name}/preview/{note_id}\nBrowse workspaces\thttps://{domain}.fast.io/browse-workspaces\nEdit share settings\thttps://{domain}.fast.io/workspace/{folder_name}/share/{custom_name}\nOrg settings\thttps://{domain}.fast.io/settings\nBilling\thttps://{domain}.fast.io/settings/billing\nPublic Links (no login required)\nWhat the human needs\tURL pattern\nPublic share\thttps://go.fast.io/shared/{custom_name}/{title-slug}\nOrg-branded share\thttps://{domain}.fast.io/shared/{custom_name}/{title-slug}\nFile in share\thttps://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}\nFile in share with comment\thttps://go.fast.io/shared/{custom_name}/{title-slug}/preview/{node_id}?comment={comment_id}\nQuickShare\thttps://go.fast.io/quickshare/{quickshare_id}\nClaim org transfer\thttps://go.fast.io/claim?token={transfer_token}\nOnboarding\thttps://go.fast.io/onboarding or https://go.fast.io/onboarding?orgId={org_id}&orgDomain={domain}\nWhere the values come from\nValue\tAPI source\ndomain\torg action create or details response\nfolder_name\torg action create-workspace or workspace action details response\nnode_id\tstorage action list, create-folder, or add-file response\ncustom_name\tshare action create or details response (the {title-slug} is cosmetic -- the share resolves on custom_name alone)\nquickshare_id\tworkspace action quickshare-create response\ntransfer_token\torg action transfer-token-create response\nchat_id\tai action chat-create or chat-list response\nnote_id\tworkspace action create-note or storage action list response (node opaque ID)\ncomment_id\tcomment action add or list response\norg_id\torg action create or list response\n\nAlways provide URLs to the human in these situations:\n\nCreated a workspace? Include the workspace URL in your response. Example: https://acme.fast.io/workspace/q4-reports/storage/root\nCreated or configured a share? Include the share URL. Example: https://go.fast.io/shared/q4-financials/Q4-Financial-Report -- this is the branded page the human (or their recipients) will open.\nGenerated a transfer token? Include the claim URL. Example: https://go.fast.io/claim?token=abc123 -- this is the only way the human can claim ownership.\nUploaded files or created folders? Include the workspace URL pointing to the relevant folder so the human can see what you built.\nHuman asks \"where can I see this?\" Construct the URL from API response data you already have and provide it.\n\nImportant: The domain is the org's domain string (e.g. acme), not the numeric org ID. The folder_name is the workspace's folder name string (e.g. q4-reports), not the numeric workspace ID. Both are returned by their respective API tools.\n\nResponse Hints (_next, _warnings, and _recovery)\n\nWorkflow-critical tool responses include a _next field -- a short array of suggested next actions using exact tool and action names. Use these hints to guide your workflow instead of guessing what to do next. Example:\n\n{\n  \"workspace_id\": \"...\",\n  \"web_url\": \"https://acme.fast.io/workspace/q4-reports/storage/root\",\n  \"_next\": [\n    \"Upload files: upload action text-file or web-import\",\n    \"Create a share: share action create\",\n    \"Query with AI: ai action chat-create\"\n  ]\n}\n\n\n_warnings appear on destructive, irreversible, or potentially problematic actions. Always read warnings before proceeding -- they flag permanent consequences or important caveats. Actions with _warnings: storage purge, storage bulk copy/move/delete/restore (partial failures), workspace details (intelligence=false), workspace update (intelligence=false), workspace archive/delete, org close, org billing-create, share delete, share archive, share update (type change), ai chat-delete, download file-url (token expiry), download zip-url (auth required), upload stage-blob (5-min expiry), org transfer-token-create.\n\n_recovery hints appear on error responses (when isError: true). They provide recovery actions based on HTTP status codes AND error message pattern matching. Error messages also include action context (e.g., \"during: org create\") to help pinpoint the failing operation.\n\nHTTP Status\tRecovery\n400\tCheck required parameters and ID formats\n401\tRe-authenticate: auth action signin or pkce-login\n402\tCredits exhausted -- check balance: org action limits\n403\tPermission denied -- check role: org action details\n404\tResource not found -- verify the ID, use list actions to discover valid IDs\n409\tConflict -- resource may already exist\n413\tRequest too large -- reduce file/chunk size\n422\tValidation error -- check field formats and constraints\n429\tRate limited -- wait 2-4s and retry with exponential backoff\n500/503\tServer error -- retry after 2-5 seconds\n\nPattern-based recovery: error messages are also matched against common patterns (e.g., \"email not verified\", \"workspace not found\", \"intelligence disabled\") to provide specific recovery steps even when the HTTP status is generic.\n\nai_capabilities is included in workspace details responses. It shows which AI modes are available based on the workspace intelligence setting:\n\nIntelligence ON: files_scope, folders_scope, files_attach (full RAG with indexed document search)\nIntelligence OFF: files_attach only (max 20 files, 200 MB, no RAG indexing)\n\n_ai_state_legend is included in storage list and search responses when files have AI indexing state. States: ready (indexed, queryable), pending (queued), inprogress (indexing), disabled (intelligence off), failed (re-upload needed). Also includes _attach_field explaining the ai.attach boolean — check this flag before using files_attach.\n\n_context provides contextual metadata on specific responses. Currently used by comment add when anchoring is involved, providing anchor_formats with the expected format for image regions, video/audio timestamps, and PDF pages.\n\nAll tool actions now include _next hints. Every successful tool response includes contextual next-step suggestions. Key workflow transitions: auth → org list/create, org create → workspace create, workspace create → upload/share/AI, upload → AI chat/comment/download, share create → add files/members, AI chat create → message read. The hints include the exact tool name, action, and relevant IDs from the current response.\n\nTool annotations: Tools include MCP annotation hints -- readOnlyHint, destructiveHint, idempotentHint (download, event), and openWorldHint (org, user, workspace, share, storage) -- to help clients understand tool behavior without documentation.\n\nResource completion and listing: The workspace and share download resource templates support both dynamic listing (resources/list) and tab-completion (completion/complete). Dynamic listing shows root-level files across workspaces and shares in the client's resource picker. Tab-completion suggests valid workspace and share IDs as you type.\n\nUnauthenticated Tools\n\nThe following actions work without a session: auth actions signin, signup, set-api-key, pkce-login, email-check, password-reset-request, password-reset; and download action quickshare-details.\n\n8. MCP Apps (Interactive UI Widgets)\n\nFast.io MCP Server includes interactive HTML5 widgets that render rich UIs directly in agent conversations. Widgets communicate with the MCP server through tool calls and display file browsers, dashboards, workflow managers, and more.\n\nAvailable Widgets\nWidget\tResource URI\tDescription\nFile Picker\twidget://file-picker\tBrowse and pick files to attach to your conversation — navigate folders, search, preview, select files for the agent. Also supports file management (upload, move, copy, delete) in workspace and share contexts\nWorkspace Picker\twidget://workspace-picker\tOrg/workspace/share selection with search, 4-step workspace creation wizard, 5-step share creation wizard\nFile Viewer\twidget://file-viewer\tUnified file preview (image, PDF, video, audio, code, spreadsheet) with info panel (details, versions, AI summary, metadata)\nWorkflow Manager\twidget://workflow\tTask board, task detail, approvals panel, todos checklist, worklog viewer\nComments Panel\twidget://comments\tThreaded comments, reactions, anchored comments (image regions, timestamps)\nUploader\twidget://uploader\tUpload files to a workspace or share with drag-and-drop, chunked binary uploads, single-step text file creation, and web URL imports with real-time progress tracking\nUploader Widget\n\nThe Uploader widget provides a 4-step file upload flow:\n\nChoose destination -- select an organization, then a workspace or share, then optionally navigate to a subfolder\nSelect files -- drag-and-drop files onto the widget or use the file picker button to browse local files\nUpload with progress -- files upload automatically with real-time progress bars. Binary files use chunked uploads (create-session, stage-blob, chunk, finalize). Text files use single-step text-file upload. Web URLs use web-import\nReference in chat -- after upload completes, click \"Reference in Chat\" to attach the uploaded files to the agent conversation for further discussion or AI analysis\n\nThe widget uses the upload tool (actions: create-session, chunk, finalize, stage-blob, text-file, web-import, status, cancel, limits, extensions) and the storage tool (action: list) via the MCP bridge.\n\nLaunch via prompt: Use the App: Upload Files prompt in desktop MCP clients.\n\nLaunch via tool:\n\napps action launch app_id uploader context_type workspace context_id <workspace_id>\n\nUsing the Apps Tool\n\nThe apps tool provides widget discovery and launching:\n\nList apps: apps action list -- returns all available widgets with metadata\nApp details: apps action details with app_id -- full metadata for a specific widget\nLaunch app: apps action launch with app_id, context_type, context_id -- opens widget with context\nFind apps for a tool: apps action get-tool-apps with tool_name -- maps tools to their widgets\nWidget Context\n\nAll widgets accept workspace or share context:\n\ncontext_type: \"workspace\" + context_id: \"<workspace_id>\"\ncontext_type: \"share\" + context_id: \"<share_id>\"\nDesign System\n\nWidgets use a shared design system matching the Fast.io frontend:\n\nLight and dark mode support (follows system preference or explicit data-theme attribute)\nConsistent typography, spacing, colors, and icons derived from the frontend theme\nResponsive layout (desktop, tablet, mobile breakpoints)\nExample: Launch File Picker\napps action launch app_id file-picker context_type workspace context_id <workspace_id>\n\nExample: Find Widgets for Storage Operations\napps action get-tool-apps tool_name storage\n\n9. Complete Tool Reference\n\nAll 19 tools with their actions organized by functional area. Each entry shows the action name and its description. Workflow tools (task, worklog, approval, todo) require workflow to be enabled on the target workspace or share.\n\nauth\n\nsignin -- Sign in to Fast.io with email and password. Returns a JWT auth token. If the account has 2FA enabled the token will have limited scope until 2fa-verify is called. The token is stored in the session automatically.\n\nset-api-key -- Authenticate using a Fast.io API key. API keys work as Bearer tokens and by default have the same permissions as the account owner. Scoped keys restrict access to specific entities (same scope system as OAuth tokens). The key is validated against the API and stored in the session. All subsequent tool calls are authenticated automatically. Unscoped API keys do not expire unless revoked; scoped keys may have an optional expiration.\n\nsignup -- Create a new Fast.io agent account (agent=true), then automatically sign in. Sets account_type to \"agent\" and assigns the free agent plan. Email verification is required after signup -- call email-verify to send a code, then call it again with the code to verify. Most endpoints require a verified email. No authentication required for signup itself.\n\ncheck -- Check whether the current session token is still valid. Returns the user ID associated with the token.\n\nsession -- Get current session information for the authenticated user, including profile details such as name, email, and account flags.\n\nsignout -- Sign out by clearing the stored session. If currently authenticated the token is verified first.\n\n2fa-verify -- Complete two-factor authentication by submitting a 2FA code. Call this after signin returns two_factor_required: true. The new full-scope token is stored automatically.\n\nemail-check -- Check if an email address is available for registration. No authentication required.\n\npassword-reset-request -- Request a password reset email. Always returns success for security (does not reveal whether the email exists). No authentication required.\n\npassword-reset -- Set a new password using a reset code received by email. No authentication required.\n\nemail-verify -- Send or validate an email verification code. When email_token is omitted a new code is sent. When provided the code is validated and the email marked as verified.\n\nstatus -- Check local session status. No API call is made. Returns whether the user is authenticated, and if so their user_id, email, token expiry, scopes (raw string), scopes_detail (hydrated array with entity names, domains, and parent hierarchy -- or null if not yet fetched), and agent_name (if set).\n\npkce-login -- Start a browser-based PKCE login flow. Returns a URL for the user to open in their browser. After signing in and approving access, the browser displays an authorization code. The user copies the code and provides it to pkce-complete to finish signing in. No password is sent through the agent. Optional params: scope_type (default \"user\" for full access; use \"org\", \"workspace\", \"all_orgs\", \"all_workspaces\", or \"all_shares\" for scoped access), agent_name (displayed in the approval screen and audit logs; defaults to MCP client name).\n\npkce-complete -- Complete a PKCE login flow by exchanging the authorization code for an access token. Call this after the user has approved access in the browser and copied the code from the screen. The token is stored in the session automatically. If scoped access was granted, the response includes scopes (JSON array of granted scope strings like \"org:123:rw\") and agent_name.\n\napi-key-create -- Create a new persistent API key. The full key value is only returned once at creation time -- store it securely. Optional parameters: name (memo/label), scopes (JSON array of scope strings like [\"org:123:rw\", \"workspace:456:r\"] for restricted access -- omit for full access), agent_name (agent/application name, max 128 chars), key_expires (ISO 8601 expiration datetime -- omit for no expiration), token (2FA code -- required when account has 2FA enabled, not needed with API key auth). Scoped keys use the same scope system as v2.0 JWT tokens.\n\napi-key-update -- Update an existing API key's metadata. Requires key_id. Optional parameters: name (memo/label), scopes (JSON scope array -- send empty string to clear and restore full access), agent_name (send empty string to clear), key_expires (send empty string to clear expiration). Only specified fields are updated.\n\napi-key-list -- List all API keys for the authenticated user. Key values are masked (only last 4 characters visible). Responses include scopes, agent_name, and expires fields for each key.\n\napi-key-get -- Get details of a specific API key. The key value is masked. Response includes scopes, agent_name, and expires fields.\n\napi-key-delete -- Revoke (delete) an API key. This action cannot be undone. Optional parameter: token (2FA code -- required when account has 2FA enabled, not needed with API key auth).\n\n2fa-status -- Get the current two-factor authentication configuration status (enabled, unverified, or disabled).\n\n2fa-enable -- Enable two-factor authentication on the specified channel. For TOTP, returns a binding URI for QR code display. The account enters an 'unverified' state until 2fa-verify-setup is called.\n\n2fa-disable -- Disable (remove) two-factor authentication from the account. Requires a valid 2FA code to confirm when 2FA is in the enabled (verified) state.\n\n2fa-send -- Send a 2FA verification code to the user's phone via SMS, voice call, or WhatsApp.\n\n2fa-verify-setup -- Verify a 2FA setup code to confirm enrollment. Transitions 2FA from the 'unverified' state to 'enabled'.\n\noauth-list -- List all active OAuth sessions for the authenticated user.\n\noauth-details -- Get details of a specific OAuth session.\n\noauth-revoke -- Revoke a specific OAuth session (log out that device).\n\noauth-revoke-all -- Revoke all OAuth sessions. Optionally exclude the current session to enable 'log out everywhere else'.\n\nuser\n\nme -- Get the current authenticated user's profile details.\n\nupdate -- Update the current user's profile (name, email, etc.).\n\nsearch -- Search for users by name or email address.\n\nclose -- Close/delete the current user account (requires email confirmation).\n\ndetails-by-id -- Get another user's public profile details by their user ID.\n\nprofiles -- Check what profile types (orgs, workspaces, shares) the user has access to.\n\nallowed -- Check if the user's country allows creating shares and organizations.\n\norg-limits -- Get free org creation eligibility, limits, and cooldown status.\n\nlist-shares -- List all shares the current user is a member of.\n\ninvitation-list -- List all pending invitations for the current user.\n\ninvitation-details -- Get details of a specific invitation by its ID or key.\n\naccept-all-invitations -- Accept all pending invitations at once.\n\nasset-upload -- Upload a user asset (e.g. profile photo). Provide either plain-text content or base64-encoded content_base64 (not both).\n\nasset-delete -- Delete a user asset (e.g. profile photo).\n\nasset-types -- List available asset types for users.\n\nasset-list -- List all user assets.\n\norg\n\nlist -- List internal organizations (orgs the user is a direct member of, member: true). Each org includes web_url. Returns member orgs with subscription status, user permission, and plan info. Non-admin members only see orgs with active subscriptions. Does not include external orgs -- use discover-external for those.\n\ndetails -- Get detailed information about an organization. Returns web_url. Fields returned vary by the caller's role: owners see encryption keys and storage config, admins see billing and permissions, members see basic info.\n\nmembers -- List all members of an organization with their IDs, emails, names, and permission levels.\n\ninvite-member -- Invite a user to the organization by email. The email is passed in the URL path (not the body). If the user already has a Fast.io account they are added directly; otherwise an email invitation is sent. Cannot add as owner.\n\nremove-member -- Remove a member from the organization. Requires member management permission as configured by the org's perm_member_manage setting.\n\nupdate-member-role -- Update a member's role/permissions in the organization. Cannot set role to 'owner' -- use transfer-ownership instead.\n\nlimits -- Get organization plan limits and credit usage. Returns credit limits, usage stats, billing period, trial info, and run-rate projections. Requires admin or owner role.\n\nlist-workspaces -- List workspaces in an organization that the current user can access. Each workspace includes web_url. Owners and admins see all workspaces; members see workspaces matching the join permission setting.\n\nlist-shares -- List shares accessible to the current user. Each share includes web_url. Returns all shares including parent org and workspace info. Use parent_org in the response to identify shares belonging to a specific organization.\n\ncreate -- Create a new organization on the \"agent\" billing plan. Requires domain (2-63 chars, lowercase alphanumeric + hyphens) and name (3-100 chars, no control characters). The authenticated user becomes the owner. A storage instance and agent-plan subscription (free, 50 GB, 5,000 credits/month) are created automatically. Returns the new org and trial status.\n\nupdate -- Update organization details. Returns web_url. Only provided fields are changed. Supports identity, branding, social links, permissions, and billing email. Requires admin or owner role.\n\nclose -- Close/delete an organization. Cancels any active subscription and initiates deletion. Requires owner role. The confirm field must match the org domain or org ID.\n\npublic-details -- Get public details for an organization. Returns web_url. Does not require membership -- returns public-level fields only (name, domain, logo, accent color). The org must exist and not be closed/suspended.\n\ncreate-workspace -- Create a new workspace within the organization. Returns web_url. Checks workspace feature availability and creation limits based on the org billing plan. The creating user becomes the workspace owner. Namespace: Workspace folder_name is globally unique across the platform. If the requested name is already taken and does not contain a dash, the server automatically prefixes it with the org ID (e.g. reports → 3587676312889739297-reports). Names with dashes are sent as-is. The final folder_name is returned in the response.\n\nbilling-plans -- List available billing plans with pricing, features, and plan defaults. Returns plan IDs needed for subscription creation.\n\nbilling-create -- Create a new subscription or update an existing one. For new subscriptions, creates a Stripe Setup Intent. For existing subscriptions, updates the plan. Requires admin or owner.\n\nbilling-cancel -- Cancel the organization's subscription. Requires owner role. Some plans may cause the org to be closed on cancellation.\n\nbilling-details -- Get comprehensive billing and subscription details including Stripe customer info, subscription status, setup intents, payment intents, and plan info. Requires admin or owner.\n\nbilling-activate -- Activate a billing plan (development environment only). Simulates Stripe payment setup and activates the subscription using a test payment method.\n\nbilling-reset -- Reset billing status (development environment only). Deletes the Stripe customer and removes the subscriber flag.\n\nbilling-members -- List billable members with their workspace memberships. Shows who the org is being billed for. Requires admin or owner role.\n\nbilling-meters -- Get usage meter time-series data (storage, transfer, AI, etc). Returns grouped data points with cost and credit calculations. Requires admin or owner role.\n\nleave -- Leave an organization. Removes the current user's own membership. Owners cannot leave -- they must transfer ownership or close the org first.\n\nmember-details -- Get detailed membership information for a specific user in the organization, including permissions, invite status, notification preference, and expiration.\n\ntransfer-ownership -- Transfer organization ownership to another member. The current owner is demoted to admin. Requires owner role.\n\ntransfer-token-create -- Create a transfer token (valid 72 hours) for an organization. Send the claim URL https://go.fast.io/claim?token=<token> to a human. Use when handing off an org or when hitting 402 Payment Required on the agent plan. Requires owner role.\n\ntransfer-token-list -- List all active transfer tokens for an organization. Each token includes web_url (claim URL). Requires owner role.\n\ntransfer-token-delete -- Delete (revoke) a pending transfer token. Requires owner role.\n\ntransfer-claim -- Claim an organization using a transfer token. The authenticated user becomes the new owner and the previous owner is demoted to admin.\n\ninvitations-list -- List all pending invitations for the organization. Optionally filter by invitation state. Requires any org membership.\n\ninvitation-update -- Update an existing invitation for the organization. Can change state, permissions, or expiration.\n\ninvitation-delete -- Revoke/delete an invitation for the organization.\n\njoin -- Join an organization via invitation or authorized domain auto-join. Optionally provide an invitation key and action (accept/decline).\n\nasset-upload -- Upload an org asset (e.g. logo, banner). Provide either plain-text content or base64-encoded file_base64 (not both). Requires admin or owner role.\n\nasset-delete -- Delete an asset from the organization. Requires admin or owner role.\n\nasset-types -- List available asset types for organizations.\n\nasset-list -- List all organization assets.\n\ndiscover-all -- List all accessible organizations (joined + invited). Each org includes web_url. Returns org data with user_status indicating relationship.\n\ndiscover-available -- List organizations available to join. Each org includes web_url. Excludes orgs the user is already a member of.\n\ndiscover-check-domain -- Check if an organization domain name is available for use. Validates format, checks reserved names, and checks existing domains.\n\ndiscover-external -- List external organizations (member: false). Each org includes web_url. Orgs the user can access only through workspace membership, not as a direct org member. Common when a human invites an agent to a workspace without inviting them to the org. See Internal vs External Orgs in the Organizations section.\n\nworkspace\n\nlist -- List all workspaces the user has access to across all organizations. Each workspace includes web_url.\n\ndetails -- Get detailed information about a specific workspace. Returns web_url.\n\nupdate -- Update workspace settings such as name, description, branding, and permissions. Returns web_url.\n\ndelete -- Permanently close (soft-delete) a workspace. Requires Owner permission and confirmation.\n\narchive -- Archive a workspace (blocks modifications, preserves data). Requires Admin+.\n\nunarchive -- Restore an archived workspace to active status. Requires Admin+.\n\nmembers -- List all members of a workspace with their roles and status.\n\nlist-shares -- List all shares within a workspace, optionally filtered by archive status. Each share includes web_url.\n\nimport-share -- Import a user-owned share into a workspace. You must be the sole owner of the share.\n\navailable -- List workspaces the current user can join but has not yet joined. Each workspace includes web_url.\n\ncheck-name -- Check if a workspace folder name is available for use. Workspace names are globally unique. Pass optional check_org_id to get an org-ID-prefixed alternative suggestion (e.g. 3587676312889739297-reports) if the name is taken.\n\ncreate-note -- Create a new markdown note in workspace storage. Returns web_url (note preview link).\n\nupdate-note -- Update a note's markdown content and/or name (at least one required). Returns web_url (note preview link).\n\nread-note -- Read a note's markdown content and metadata. Returns the note content and web_url (note preview link).\n\nquickshare-get -- Get existing quickshare details for a node. Returns web_url.\n\nquickshare-delete -- Revoke and delete a quickshare link for a node.\n\nquickshares-list -- List all active quickshares in the workspace. Each quickshare includes web_url.\n\nmetadata-template-create -- Create a new metadata template in the workspace. Requires name, description, category (legal, financial, business, medical, technical, engineering, insurance, educational, multimedia, hr), and fields (JSON-encoded array of field definitions). Each field has name, description, type (string, int, float, bool, json, url, datetime), and optional constraints (min, max, default, fixed_list, can_be_null).\n\nmetadata-template-delete -- Delete a metadata template. System templates and locked templates cannot be deleted. Requires template_id.\n\nmetadata-template-list -- List metadata templates. Optional template_filter: enabled, disabled, custom (non-system), or system. Returns all non-deleted templates when no filter is specified.\n\nmetadata-template-details -- Get full details of a metadata template including all field definitions. Requires template_id.\n\nmetadata-template-update -- Update an existing metadata template. Any combination of name, description, category, and fields can be updated. Requires template_id.\n\nmetadata-template-clone -- Clone a metadata template with optional modifications. Creates a new template based on an existing one. Same parameters as metadata-template-update. Requires template_id.\n\nmetadata-template-assign -- Assign a metadata template to a workspace. Each workspace can have at most one assigned template. Assigning a system template automatically clones it. Requires template_id. Optional node_id (null for workspace-level assignment).\n\nmetadata-template-unassign -- Remove the template assignment from a workspace. Requires workspace admin permission.\n\nmetadata-template-resolve -- Resolve which metadata template applies to a given node. Returns the workspace-level template (node_id is accepted but currently inherits from workspace). Returns null if no template is assigned.\n\nmetadata-template-assignments -- List all template assignments in the workspace.\n\nmetadata-get -- Get all metadata for a file, including both template-conforming metadata and custom (freeform) key-value pairs. Returns node details, template_id, template_metadata array, and custom_metadata array. Requires node_id.\n\nmetadata-set -- Set or update metadata key-value pairs on a file. Values must conform to the template field definitions. Requires node_id, template_id, and key_values (JSON object of key-value pairs).\n\nmetadata-delete -- Delete metadata from a file. Provide keys (JSON array of key names) to delete specific entries, or omit to delete all metadata. Only works on files and notes, not folders. Requires node_id.\n\nmetadata-extract -- Trigger AI-powered metadata extraction from a file. The AI analyzes file content and populates metadata fields according to the template. Extracted values are marked with is_auto: true. Consumes AI credits. Optional template_id (defaults to workspace template). Requires node_id.\n\nmetadata-list-files -- List files that have metadata for a specific template, with optional filtering and sorting. Requires node_id (folder to search in) and template_id. Optional metadata_filters (JSON-encoded), order_by (field key), and order_desc.\n\nmetadata-list-templates-in-use -- List which metadata templates are in use within a folder, with usage counts per template. Requires node_id.\n\nmetadata-versions -- Get metadata version history for a file. Returns snapshots of metadata changes over time. Requires node_id.\n\nenable-workflow -- Enable workflow features (tasks, worklogs, approvals, todos) on a workspace. Must be called before using workflow tools on the workspace.\n\ndisable-workflow -- Disable workflow features on a workspace. All workflow data is preserved but inaccessible until re-enabled.\n\nshare\n\nlist -- List shares the authenticated user has access to. Each share includes web_url.\n\ndetails -- Get full details of a specific share. Returns web_url.\n\ncreate -- Create a new share in a workspace.\n\nupdate -- Update share settings (partial update).\n\ndelete -- Delete (close) a share. Requires the share ID or custom name as confirmation.\n\npublic-details -- Get public-facing share info (no membership required, just auth).\n\narchive -- Archive a share. Blocks guest access and restricts modifications.\n\nunarchive -- Restore a previously archived share to active status.\n\npassword-auth -- Authenticate with a share password. Returns a scoped JWT for the share.\n\nmembers -- List all members of a share.\n\navailable -- List shares available to join (joined and owned, excludes pending invitations). Each share includes web_url.\n\ncheck-name -- Check if a share custom name (URL name) is available.\n\nquickshare-create -- Create a temporary QuickShare link for a file in a workspace. Optional expires (seconds, default 10,800, max 604,800 = 7 days) or expires_at (ISO 8601 datetime).\n\nenable-workflow -- Enable workflow features (tasks, worklogs, approvals, todos) on a share. Must be called before using workflow tools on the share.\n\ndisable-workflow -- Disable workflow features on a share. All workflow data is preserved but inaccessible until re-enabled.\n\nstorage\n\nAll storage actions require context_type parameter (workspace or share) and context_id (the 19-digit profile ID).\n\nlist -- List files and folders in a directory with pagination. Each item includes web_url (workspace only). Requires context_type, context_id, and node_id (use root for root folder).\n\nrecent -- List recently modified files and folders across all directories, sorted by updated descending. Unlike list which is scoped to a single folder, this returns nodes from the entire storage tree. Supports optional type filter (file, folder, link, note), page_size (100, 250, or 500), and cursor for pagination. For workspace folder shares, results are automatically filtered to the share's subtree.\n\ndetails -- Get full details of a specific file or folder. Returns web_url (human-friendly link to the file preview or folder in the web UI, workspace only).\n\nsearch -- Search for files by keyword or semantic query. Each result includes web_url (workspace only).\n\ntrash-list -- List items currently in the trash. Each item includes web_url (workspace only).\n\ncreate-folder -- Create a new folder. Returns web_url (workspace only).\n\ncopy -- Copy files/folders. Single copy via node_id (workspace or share). Bulk copy via node_ids array (workspace only). Returns web_url on the new copy (workspace only).\n\nmove -- Move files/folders. Single move via node_id (workspace or share). Bulk move via node_ids array (workspace only). Returns web_url (workspace only).\n\ndelete -- Delete files/folders by moving them to the trash. Single delete via node_id (workspace or share). Bulk delete via node_ids array (workspace only).\n\nrename -- Rename a file or folder. Returns web_url (workspace only).\n\npurge -- Permanently delete a trashed node (irreversible). Requires Member permission.\n\nrestore -- Restore files/folders from the trash. Single restore via node_id (workspace or share). Bulk restore via node_ids array (workspace only). Returns web_url on the restored node (workspace only).\n\nadd-file -- Link a completed upload to a storage location. Returns web_url (workspace only).\n\nadd-link -- Add a share reference link node to storage.\n\ntransfer -- Copy or move a node to another workspace or share storage instance. Default mode is 'copy' (keeps source). Use transfer_mode='move' to copy then trash the source (cannot move root). When mode=move, response includes source_trashed (boolean) indicating whether the source was successfully trashed.\n\nversion-list -- List version history for a file. Returns web_url for the file (workspace only).\n\nversion-restore -- Restore a file to a previous version. Returns web_url for the file (workspace only).\n\nlock-acquire -- Acquire an exclusive lock on a file to prevent concurrent edits.\n\nlock-status -- Check the lock status of a file.\n\nlock-release -- Release an exclusive lock on a file.\n\npreview-url -- Get a preauthorized preview URL for a file (thumbnail, PDF, image, video, audio, spreadsheet). Requires preview_type parameter. Returns preview_url (ready-to-use URL) and web_url (human-friendly link to the file in the web UI, workspace only).\n\npreview-transform -- Request a file transformation (image resize, crop, format conversion) and get a download URL for the result. Requires transform_name parameter. Returns transform_url (ready-to-use URL) and web_url (human-friendly link to the file in the web UI, workspace only).\n\nupload\n\ncreate-session -- Create a chunked upload session for a file.\n\nchunk -- Upload a single chunk. Use content for text/strings, data for base64-encoded binary, or blob_ref for binary staged via stage-blob action or POST /blob. Provide exactly one.\n\nfinalize -- Finalize an upload session, trigger file assembly, and poll until fully stored or failed. Returns the final session state.\n\nstatus -- Get the current status of an upload session. Supports server-side long-poll via optional wait parameter (in milliseconds, 0 = immediate).\n\ncancel -- Cancel and delete an active upload session.\n\nlist-sessions -- List all active upload sessions for the current user.\n\ncancel-all -- Cancel and delete ALL active upload sessions at once.\n\nchunk-status -- Get chunk information for an upload session.\n\nchunk-delete -- Delete/reset a chunk in an upload session.\n\nstage-blob -- Stage base64-encoded binary data as a blob for later use with the chunk action's blob_ref parameter. Pass data (base64 string). Returns { blob_id, size }. Blobs expire after 5 minutes and are consumed on first use. Alternative to passing data directly in the chunk call.\n\ntext-file -- Upload a text file in a single step using the Fast.io single-request upload pattern. Sends the file in one multipart POST and returns the new file ID directly. Use for text-based files (code, markdown, CSV, JSON, config) instead of the multi-step chunked flow.\n\nweb-import -- Import a file from an external URL into a workspace or share.\n\nweb-list -- List the user's web upload jobs with optional filtering.\n\nweb-cancel -- Cancel an active web upload job.\n\nweb-status -- Get detailed status of a specific web upload job.\n\nlimits -- Get upload size and chunk limits for the user's plan.\n\nextensions -- Get restricted and allowed file extensions for uploads.\n\ndownload\n\nfile-url -- Get a download token and URL for a file. Optionally specify a version. Requires context_type, context_id, and node_id.\n\nzip-url -- Get a ZIP download URL for a folder or entire workspace/share. Returns the URL with auth instructions. Requires context_type, context_id, and node_id (use root for entire storage tree).\n\nquickshare-details -- Get metadata and download info for a quickshare link. No authentication required.\n\nai\n\nAll AI actions require context_type parameter (workspace or share) and context_id (the 19-digit profile ID).\n\nchat-create -- Create a new AI chat with an initial question. Default scope is the entire workspace (all indexed documents) — omit files_scope and folders_scope unless you need to narrow the search. When using scope or attachments, provide nodeId:versionId pairs — versionId is auto-resolved to the current version if left empty (get explicit versionId from storage list/details version field). When using files_attach, verify ai.attach is true for each file first (check via storage details). Type is auto-promoted from chat to chat_with_files when file parameters are present. Returns chat ID and initial message ID -- use message-read to get the AI response.\n\nchat-list -- List AI chats.\n\nchat-details -- Get AI chat details including full message history.\n\nchat-update -- Update the name of an AI chat.\n\nchat-delete -- Delete an AI chat.\n\nchat-publish -- Publish a private AI chat, making it visible to all members.\n\nmessage-send -- Send a follow-up message in an existing AI chat. Returns message ID -- use message-read to get the AI response.\n\nmessage-list -- List all messages in an AI chat.\n\nmessage-details -- Get details for a specific message in an AI chat including response text and citations.\n\nmessage-read -- Read an AI message response. Polls the message details endpoint until the AI response is complete, then returns the full text.\n\nsearch -- Semantic search across indexed documents and code. Returns ranked document chunks with relevance scores -- faster and lighter than AI chat (stateless GET, no LLM inference). Requires Intelligence ON. Params: query_text (2-1,000 chars), optional files_scope, folders_scope (same format as chat scoping), limit (1-500, default 100), offset. Results include content snippets, scores, and source file details with web_url (workspace only). Use search to find relevant documents, then chat to ask questions about them.\n\nshare-generate -- Generate AI Share markdown with temporary download URLs for files that can be pasted into external AI chatbots.\n\ntransactions -- List AI token usage transactions for billing tracking.\n\nautotitle -- Generate AI-powered title and description based on contents (share context only).\n\ncomment\n\nAll comment endpoints use the path pattern /comments/{entity_type}/{parent_id}/ or /comments/{entity_type}/{parent_id}/{node_id}/ where entity_type is workspace or share, parent_id is the 19-digit profile ID, and node_id is the file's opaque ID.\n\nlist -- List comments on a specific file (node). Params: sort (created/-created), limit (2-200), offset, include_deleted, reference_type filter, include_total.\n\nlist-all -- List all comments across a workspace or share (not node-specific). Same listing params as list.\n\nadd -- Add a comment to a specific file. Body: text (max 8,192 chars total, max 2,048 chars display text with @[...] mention tags stripped). Supports mention tags: @[profile:id], @[user:opaqueId:Name], @[file:fileId:name.ext]. Optional parent_comment_id (single-level threading, replies to replies auto-flatten), optional reference (type, timestamp, page, region, text_snippet for content anchoring; exact, prefix, suffix, start_offset, end_offset for text anchoring on markdown/notes -- use type \"document\" or \"text\"), optional linked_entity_type (task or approval) and linked_entity_id to link the comment to a workflow entity at creation time. Uses JSON body.\n\ndelete -- Delete a comment. Recursive: deleting a parent also removes all its replies.\n\nbulk-delete -- Bulk soft-delete multiple comments (max 100). NOT recursive: replies to deleted comments are preserved.\n\ndetails -- Get full details of a single comment by its ID. Response includes linked_entity_type and linked_entity_id (null when not linked).\n\nreaction-add -- Add or change your emoji reaction. One reaction per user per comment; new replaces previous.\n\nreaction-remove -- Remove your emoji reaction from a comment.\n\nlink -- Link an existing comment to a workflow entity. Params: comment_id, linked_entity_type (task or approval), linked_entity_id. One link per comment; linking replaces any existing link. Returns the updated comment with linked fields populated.\n\nunlink -- Remove the workflow link from a comment. Params: comment_id. Returns the updated comment with linked fields set to null.\n\nlinked -- Reverse lookup: find all comments linked to a given workflow entity. Params: linked_entity_type (task or approval), linked_entity_id. Returns a list of comments linked to the specified entity.\n\nevent\n\nsearch -- Search the audit/event log with filters for profile, event type, category, subcategory, event name, and date range. See Event Filtering Reference in section 7 for the full taxonomy of categories, subcategories, and event names.\n\nsummarize -- Search events and return an AI-powered natural language summary of the activity. Accepts the same category/subcategory/event filters as search.\n\ndetails -- Get full details for a single event by its ID.\n\nactivity-list -- Poll for recent activity events on a workspace or share.\n\nactivity-poll -- Long-poll for activity changes on a workspace or share. The server holds the connection until a change occurs or the wait period expires. Returns activity keys indicating what changed and a lastactivity timestamp for the next poll.\n\nmember\n\nAll member actions require entity_type parameter (workspace or share) and entity_id (the 19-digit profile ID).\n\nadd -- Add an existing user by user ID, or invite by email. Pass the email address or user ID as email_or_user_id. For workspaces, set access level with permissions (admin/member/guest). For shares, use role (admin/member/guest/view).\n\nremove -- Remove a member (cannot remove the owner).\n\ndetails -- Get detailed membership info for a specific member. For workspaces, pass member_id; for shares, pass user_id.\n\nupdate -- Update a member's role, notifications, or expiration.\n\ntransfer-ownership -- Transfer ownership to another member (current owner is demoted to admin).\n\nleave -- Leave (remove yourself). Owner must transfer ownership first.\n\njoin -- Self-join based on organization membership.\n\njoin-invitation -- Accept or decline an invitation using an invitation key.\n\ninvitation\n\nAll invitation actions require entity_type parameter (workspace or share) and entity_id (the 19-digit profile ID).\n\nlist -- List all pending invitations.\n\nlist-by-state -- List invitations filtered by state.\n\nupdate -- Resend or update an invitation (by ID or invitee email).\n\ndelete -- Revoke and delete a pending invitation.\n\nasset\n\nAll asset actions require entity_type parameter (org, workspace, share, or user) and entity_id (the 19-digit profile ID for org/workspace/share).\n\nupload -- Upload an asset (e.g. logo, banner, profile photo). Provide either plain-text content or base64-encoded data (not both).\n\ndelete -- Delete an asset.\n\ntypes -- List available asset types for the entity.\n\nlist -- List all assets for the entity.\n\nread -- Read/download an asset.\n\ntask\n\nTask list and task management for workspaces and shares. All task actions require workflow to be enabled on the target entity (workspace action enable-workflow or share action enable-workflow).\n\nlist-lists -- List all task lists for a workspace or share. Requires profile_type and profile_id. Supports sort_by (created, updated, name), sort_dir, limit (1-200), offset, and format (\"md\" for markdown).\n\ncreate-list -- Create a new task list. Requires profile_type, profile_id, and name (1-255 chars). Optional description (max 2000 chars).\n\nlist-details -- Get details of a specific task list. Requires list_id. Supports format.\n\nupdate-list -- Update a task list's name or description. Requires list_id. Optional name, description.\n\ndelete-list -- Soft-delete a task list and all its tasks. Requires list_id. Destructive.\n\nlist-tasks -- List tasks in a task list. Requires list_id. Supports status filter, assignee filter, sort_by (created, updated, name, priority, status), sort_dir, limit (1-200), offset, and format.\n\ncreate-task -- Create a new task in a list. Requires list_id and title (1-500 chars). Optional description (max 5000 chars), status (pending, in_progress, complete, blocked), priority (0=none, 1=low, 2=medium, 3=high, 4=critical), assignee_id (profile ID), dependencies (array of task IDs), node_id (link to file/folder/note).\n\ntask-details -- Get full details of a specific task. Requires list_id and task_id. Supports format.\n\nupdate-task -- Update a task's title, description, status, priority, assignee, dependencies, or node link. Requires list_id and task_id.\n\ndelete-task -- Soft-delete a task. Requires list_id and task_id. Destructive.\n\nchange-status -- Change a task's status. Requires list_id, task_id, and status.\n\nassign-task -- Assign or unassign a task. Requires list_id and task_id. Pass assignee_id (profile ID) to assign, or null/omit to unassign.\n\nbulk-status -- Change status on multiple tasks at once. Requires list_id, task_ids (array of task IDs, max 100), and status.\n\nmove-task -- Move a task from one list to another within the same profile. Requires list_id (source list), task_id, and target_task_list_id (destination list). Optional sort_order (position in target list, default 0). Source and target lists must belong to the same profile. Returns the updated task with old_task_list_id and new_task_list_id.\n\nreorder-tasks -- Reorder tasks within a list. Requires list_id and task_ids (array of task IDs in the desired display order). The server converts this to {order: [{id, sort_order}, ...]} for the API.\n\nreorder-lists -- Reorder task lists within a workspace or share. Requires profile_type, profile_id, and list_ids (array of task list IDs in the desired display order). The server converts this to {order: [{id, sort_order}, ...]} for the API.\n\nworklog\n\nActivity log for tracking agent work. After uploads, task changes, share creation, or any significant action, log what you did and why — builds a searchable audit trail for humans and AI. All worklog actions require workflow to be enabled on the target entity.\n\nappend -- Append a new entry to the worklog. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id, and content (1-10000 chars). Use after making changes to record what was done and why. Entries are immutable after creation.\n\nlist -- List worklog entries. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\") and entity_id (the corresponding entity's opaque ID, or profile 19-digit ID for entity_type \"profile\"). Supports type filter (\"entry\" or \"interjection\"), sort_dir (\"asc\" or \"desc\", default \"desc\"), limit (1-200), offset, and format (\"md\" for markdown).\n\ninterject -- Create an urgent interjection entry that requires acknowledgement. Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\"), entity_id, and content (1-10000 chars). Interjections are priority corrections -- always treated as urgent.\n\ndetails -- Get full details of a specific worklog entry. Requires entry_id. Supports format.\n\nacknowledge -- Acknowledge an interjection entry, marking it as seen. Requires entry_id. Only entries with acknowledgable: true can be acknowledged.\n\nunacknowledged -- List unacknowledged interjections (entries where acknowledgable is true). Requires entity_type (\"task\", \"task_list\", \"node\", or \"profile\") and entity_id. Supports limit, offset, and format. Always check for unacknowledged interjections before proceeding with work.\n\napproval\n\nFormal approval requests scoped to tasks, storage nodes, or worklog entries. All approval actions require workflow to be enabled on the target entity.\n\nlist -- List approval requests for a workspace or share. Requires profile_type and profile_id. Supports status filter (pending, approved, rejected), limit (1-200, default 100), offset, and format.\n\ncreate -- Create a new approval request. Requires entity_type (\"task\", \"node\", or \"worklog_entry\"), entity_id, profile_id, and description (1-5000 chars). Optional approver_id (profile ID of designated approver), deadline (ISO 8601), node_id (artifact reference).\n\ndetails -- Get full details of an approval request including approver list and resolution. Requires approval_id (opaque alphanumeric). Supports format.\n\nresolve -- Resolve an approval request. Requires approval_id and resolve_action (\"approve\" or \"reject\"). Optional comment (max 5000 chars). Only designated approvers can resolve.\n\ntodo\n\nSimple flat checklists scoped to workspaces and shares. No nesting. All todo actions require workflow to be enabled on the target entity.\n\nlist -- List todos for a workspace or share. Requires profile_type and profile_id. Supports filter_done (boolean), sort_by (created, updated, title), sort_dir, limit (1-200, default 50), offset, and format.\n\ncreate -- Create a new todo item. Requires profile_type, profile_id, and title (1-500 chars). Optional assignee_id.\n\ndetails -- Get full details of a todo. Requires todo_id (opaque alphanumeric). Supports format.\n\nupdate -- Update a todo. Requires todo_id. Supports title, assignee_id, done.\n\ndelete -- Soft-delete a todo. Requires todo_id. Destructive.\n\ntoggle -- Toggle the done state of a todo. Requires todo_id. Flips between done and not done.\n\nbulk-toggle -- Set done state on multiple todos at once. Requires profile_type, profile_id, todo_ids (array of todo IDs, max 100), and done (boolean: true to mark done, false to mark not done).\n\napps\n\nInteractive MCP App widget discovery and launching. Widgets are interactive HTML5 UIs that render in agent conversations.\n\nlist -- List all available MCP App widgets with their metadata (title, description, supported tools, supported actions, resource URI).\n\ndetails -- Get full metadata for a specific widget. Requires app_id (the widget name, e.g., \"file-picker\").\n\nlaunch -- Launch a widget with workspace or share context. Requires app_id, context_type (\"workspace\" or \"share\"), and context_id (the 19-digit profile ID). Returns the widget HTML content ready for rendering.\n\nget-tool-apps -- Find widgets associated with a specific tool domain. Requires tool_name (e.g., \"storage\", \"ai\", \"comment\"). Returns widgets that provide UI for that tool's operations.\n\n10. Code Mode (Headless Agents)\n\nWhen connecting from a headless agent (Claude Code, Cursor, Continue, etc.), the server automatically enables Code Mode -- a lightweight alternative to the full 19-tool set. Code Mode exposes 4 tools total:\n\nTool\tPurpose\nauth\tAuthentication (signin, signup, API keys, PKCE, 2FA)\nupload\tFile uploads (chunked, text, web-import)\nsearch\tDiscover API endpoints by keyword, tag, or concept\nexecute\tMake authenticated API calls to Fast.io\n\nClients with MCP Apps support (Claude Desktop, Cline) continue to receive the full 19-tool set plus 12 app-* widget tools. Unknown clients default to the full tool set.\n\nsearch Tool\n\nQuery the API spec by keywords, paths, or concepts. Returns matching endpoints with method, path, parameters, and descriptions.\n\nsearch query=\"list files in workspace\" tag=\"storage\"\nsearch query=\"create share\" tag=\"share\"\nsearch query=\"authentication\"\nsearch query=\"pagination\" include_concepts=true\n\n\nParameters:\n\nquery (string, required) -- Keywords, endpoint paths, or concepts to search for\ntag (string, optional) -- Filter by domain: auth, workspace, storage, ai, share, upload, org, user, member, comment, event, metadata, etc.\ninclude_concepts (boolean, optional) -- Include concept docs (pagination, IDs, errors). Default true.\nexecute Tool\n\nMake authenticated API calls to the Fast.io REST API. Use search first to discover endpoints.\n\nMethods:\n\nget -- GET request with optional query parameters\npost -- POST with form-encoded body (default API format)\npostJson -- POST with JSON body\ndelete -- DELETE request\nput -- PUT with form-encoded body\n\nThe auth token is injected automatically. Path parameters must be filled by the caller (replace {workspace_id} with the actual ID). For multi-step operations, make multiple sequential execute calls.\n\nexecute method=\"get\" path=\"/org/1234567890123456789/list/workspaces/\"\n\nexecute method=\"post\" path=\"/workspace/1234567890123456789/storage/root/createfolder/\" body={\"name\": \"reports\"}\n\nexecute method=\"postJson\" path=\"/workspace/1234567890123456789/storage/root/createnote/\" body={\"name\": \"summary.md\", \"content\": \"# Summary\"}\n\n\nParameters:\n\nmethod (enum, required) -- HTTP method: \"get\", \"post\", \"postJson\", \"delete\", \"put\"\npath (string, required) -- API endpoint path (e.g., '/orgs/list/', '/workspace/{workspace_id}')\nbody (object, optional) -- Request body (form-encoded for post/put, JSON for postJson)\nparams (object, optional) -- Query parameters appended to the URL\ntimeout_ms (number, optional) -- Timeout in ms (default 30000, max 60000)\nResponse Handling\n\nThe execute tool handles three response types automatically:\n\nJSON (most endpoints) -- parsed as standard Fast.io API envelope\nText (markdown, plain text, etc.) -- returned as { content, content_type, http_status }\nBinary (images, PDFs, etc.) -- returns metadata with guidance to use download:// MCP resource\nReading Notes in Code Mode\n\nUse /readnote/ (returns JSON) instead of /read/ (returns raw binary):\n\nexecute method=\"get\" path=\"/workspace/{workspace_id}/storage/{node_id}/readnote/\"\n\n\nFor reading uploaded files (non-notes), use the download:// MCP resource:\n\nresources/read uri=\"download://workspace/{workspace_id}/{node_id}\""
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/dbalve/fast-io",
    "publisherUrl": "https://clawhub.ai/dbalve/fast-io",
    "owner": "dbalve",
    "version": "1.123.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/fast-io",
    "downloadUrl": "https://openagent3.xyz/downloads/fast-io",
    "agentUrl": "https://openagent3.xyz/skills/fast-io/agent",
    "manifestUrl": "https://openagent3.xyz/skills/fast-io/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/fast-io/agent.md"
  }
}