Write, share, and carry your context everywhere. Create your free account today.

05 Team Accounts

Raw

Team Accounts

A Team account is a shared MDflow tenant: its own members, roles, workspaces, folders and markdown documents, billed separately from anyone's personal plan at €9.99 per active member each month with a 7-day trial.

Team accounts are available to every signed-in MDflow user. There is no waitlist, allowlist or eligibility flag — open the Teams icon in the source rail, or go to /teams, and create one. Access to a specific Team account is governed only by membership, role, and that account's billing state.

The one thing to understand first

A Team account is not a shared personal workspace. Team content lives in a separate tenant domain with its own storage and its own authorization rules.

Consequences that surprise people:

  • Creating a Team account changes nothing about your personal workspaces. They stay private and stay on whatever plan you personally pay for.
  • Your personal Pro subscription grants you nothing inside a Team, and a Team seat grants you nothing in your personal workspaces. The two are completely independent.
  • A Team seat grants Pro-equivalent entitlement for Team content. Every active member gets autosave and version history on Team documents without anyone buying personal Pro.
  • Personal tokens (mdf_…) are rejected on Team API routes, and Team tokens (mdt_…) are rejected on personal routes. They are not interchangeable.

1. Creating a Team and inviting people

Create: open Teams from the source rail. If you are not yet a member of any Team, you get a create-or-join entry point. One profile can belong to at most 10 Team accounts.

Invite: from Team settings, invite by email as admin or member, setting each workspace permission before sending. Invitation rules:

RuleValue
Invitation lifetime7 days
Resend cooldown60 seconds
Sends per invitation per 24 hours5
Pending invitations per account50
Members per account50

The invitee must accept while signed in to an MDflow account whose confirmed email matches the invitation. Failed deliveries are visible in Team settings and can be retried.

Invitations are never billed. Only an accepted invitation creates a membership, and only a membership creates a seat.

2. Roles

CapabilityOwnerAdminMember
Read and write Team contentYesYesPer workspace
Access to every workspaceYesYesOnly where granted
Create / rename / describe / delete workspacesYesYesNo
Invite, remove and manage membersYesYesNo
Assign per-member workspace accessYesYesNo
Create Team access tokensYesYesYes
See and revoke everyone's tokensYesYesOwn only
Rename the Team accountYesNoNo
Billing: subscribe, portal, recoverYesNoNo
Transfer ownershipYesNoNo
Leave the TeamNoYesYes
Delete the Team accountYesNoNo

There is exactly one owner, and the owner cannot leave or be removed — ownership must be transferred first. Only the owner can see or touch billing; admins cannot.

3. Workspaces and per-member access

Owners and admins reach every Team workspace implicitly. Regular members reach only what they are granted, set from the workspace actions menu:

LevelWhat the member can do
No accessThe workspace is hidden completely
Read onlyView, quick open, copy, download, export, import into a personal workspace, present — no Team-content changes
Read, write & deleteEverything above, plus create, organize, edit, share, encrypt, restore versions, duplicate and delete

Two behaviours worth knowing:

  • A new workspace grants regular members nothing until an owner or admin assigns access.
  • Promoting a member to admin clears their per-workspace access (admins don't need it), and demoting them back to member does not restore it. The promotion asks for confirmation for exactly this reason.

Drag-and-drop moves stay inside one Team workspace; moving content between Team workspaces is not yet supported.

4. Pricing and billing

4.1 Seats are derived, never purchased

billed quantity = number of accepted memberships

There is no seat pool, no allowance, and no "2 seats remaining". You never buy N seats.

  • The owner occupies a seat: a Team of 5 members is quantity 5, not 5 + owner.
  • Adding a member is never blocked or pre-charged by billing.
  • Membership changes are pushed to Stripe by an hourly reconciliation, so the billed quantity catches up within an hour.
Price€9.99 per active member per month
Trial7 days, once per Team account ever
Initial quantityHeadcount at the moment the owner subscribes
Seat changesProrated, settled on the next invoice — never charged or refunded at the moment they happen
Promotion codesAccepted at checkout
PayerThe owner only

Teams is not listed on the public pricing page; the price appears in the Team settings billing card.

Money moves on the billing cycle; access moves immediately. Removing a member ends their access at once and writes a credit for the unused remainder onto the next invoice. Swapping one member for another inside the same hour usually costs nothing at all, because the count never changes by the time Stripe is updated.

4.2 Access states

access_state is the single authority over what a Team can do:

StateReadWriteAccept invitations
setup — created, not yet subscribedYesNoYes
active — paying or in trialYesYesYes
grace — payment lapsed, first 30 daysYesNoNo
read_only — after those 30 daysYesNoNo
deleting — deletion in progressNoNoNo

Members can join and organize themselves in setup before the owner ever subscribes; nothing is billed until checkout, and the first invoice simply covers whoever is there by then.

4.3 When a payment fails

There is only ever one payer, so "a member's payment failed" cannot happen — it is always the Team's payment, and it affects everyone at once.

  1. On the first failed payment the account moves to grace and Team content becomes read-only immediately. There is no tolerance window.
  2. The 30-day clock starts then and does not restart on later retry failures.
  3. Invitations cannot be sent or accepted while lapsed, so the Team cannot grow.
  4. After 30 days the account becomes read_only. For users nothing changes — both states are read-only.

Nothing is ever deleted by a lapse. Reads, exports and existing public share links keep working indefinitely. A lapsed Team loses the ability to change anything and keeps the ability to see and retrieve everything.

MDflow sends no billing email of any kind. The owner learns about a failure from Stripe's own emails and from the in-app banner. Only the owner can fix it — if the owner is unreachable, the escape hatch is transferring ownership, which works in every state except deleting.

4.4 Cancelling and restarting

Cancellation happens in the Stripe billing portal, never in MDflow.

  • Cancel at period end changes nothing until the period actually ends — the Team stays fully writable, and an amber notice appears in settings.
  • Cancel immediately stops writes at once and puts the account into grace.
  • Restarting is offered once the subscription is genuinely cancelled. There is no second trial — the 7 days are once per Team, ever — and the quantity is today's headcount.
  • A past_due or unpaid subscription is not restarted with a new checkout; it is recovered by updating the payment method in the portal.
  • MDflow never issues refunds. Cancelling immediately forfeits the remainder of the paid period.

5. What Team documents can and cannot do

Team documents use the same Monaco editor, split preview, markdown syntax, PDF export, local drafts and conflict-aware saves as personal documents.

Included: nested folders with descriptions, inline rename, duplicate, move, copy path, download .md, PDF export, presentation mode, markdown import (including a dragged folder tree), ⌘K quick open, @mention links between documents in the same workspace, autosave, version history, public share links, client-side encryption, workspace ZIP export, and importing any Team document into your own private workspace.

Deliberately not there yet, pending Team-specific authorization designs:

MissingMissing
CommentsSidebar search (title + body)
Uploaded imagesSort views and the refresh menu
CollectionsFavorites
Private sharing by emailMoving content between Team workspaces
GitHub and Google Drive integrationsCustom domains for Team share links

A few details that behave differently from personal documents:

  • Encryption works identically, and the password travels between people directly — the encrypted body carries everything needed to derive the key, so any teammate who knows the password unlocks it on their own device. MDflow never holds a key.
  • Public share links are always served from the MDflow domain; personal custom domains do not apply to Team content. Links survive grace and read-only and go dark only if the account is deleted.
  • Importing a Team document into your own workspace is a snapshot — editing the copy changes nothing in the Team — and it counts against your personal document limit, not the Team's.
  • Version history follows the Team subscription, so it withdraws in grace and read-only along with the rest of the Pro feature set.

Every account, membership, invitation, workspace, folder, document, restore and export change is recorded in a Team-only audit feed with 365-day retention.

6. Team access tokens (mdt_…)

Team API and Team MCP both authenticate with a Team access token, created from the Team account's API Access page (/teams/{accountId}/api-access).

Any member can create one. There is no Pro gate — eligibility comes from the seat, not from the creator's personal plan.

When creating a token you choose:

  • a name,
  • the workspaces it may reach (checkboxes; only workspaces you can already read),
  • a permission cap: read-only, or read and write.
PropertyBehaviour
Formatmdt_ + 32 random bytes, base64url
StorageSHA-256 hash only — MDflow never stores the plaintext
RevealShown exactly once, at creation
ScopeOne Team account, and only the workspaces selected at creation
Later workspacesNever granted automatically
Expiration / rotationNot yet — revoke and re-create
VisibilityOwners and admins see every token's metadata (creator, workspaces, permission, created and last used); members see their own
RevocationImmediate. Members revoke their own; owners and admins revoke any

Effective access is recomputed on every request

The token only sets an upper bound. Each request recalculates:

token's workspace grant
  ∩ the creator's current membership and role
  ∩ their current per-workspace permission
  ∩ the Team account's access state

So, without touching the token:

  • Downgrading a member from write to read on a workspace revokes that token's write access instantly, and restoring it restores the token too.
  • Removing a member deletes their tokens outright.
  • A lapsed Team (grace or read-only) makes every token read-only, because writes require an active account.
  • A deleting account refuses everything.
  • Workspaces the token cannot reach return 404 — never a hint that they exist.

7. The Team API

A content-only JSON API under /api/team/v1. Authenticate with a bearer header:

Authorization: Bearer mdt_your_token_here

Endpoints

MethodPathPurpose
GET/api/team/v1/workspacesReachable workspaces, each with your effective access_level and the account's state
GET/api/team/v1/foldersList folders; optional ?workspace_id=
POST/api/team/v1/foldersCreate a folder
GET/api/team/v1/folders/{id}Read one folder
PATCH/api/team/v1/folders/{id}Rename, re-describe, or reparent
DELETE/api/team/v1/folders/{id}Delete the folder and everything inside it
GET/api/team/v1/folders/{id}/documentsDocuments directly in a folder
GET/api/team/v1/documentsList documents; optional ?workspace_id=, or ?ids= (up to 10, returns bodies)
POST/api/team/v1/documentsCreate a document
GET/api/team/v1/documents/{id}Read one document, body included
PATCH/api/team/v1/documents/{id}Rename
DELETE/api/team/v1/documents/{id}Delete
PUT/api/team/v1/documents/{id}/bodyReplace the entire body
PUT/api/team/v1/documents/{id}/folderMove to another folder, or to the workspace root

That is 14 operations. Membership, invitations, billing, sharing and workspace administration are deliberately not exposed — the API touches content only.

Rules that catch people out

  • workspace_id is never guessed. A Team token can span several workspaces, so a top-level POST /folders or POST /documents without a parent_id / folder_id must pass workspace_id, or it returns 400. Supplying both is fine as long as they agree.
  • Duplicate names are disambiguated automatically with a numeric suffix, exactly as in the app.
  • Emptying a document requires intent. PUT .../body with an empty string returns 400 Empty body requires confirmEmpty: true.
  • A body replaces the whole document. There is no patch or append.
  • Documents may sit at the workspace root (folder_id: null), which personal documents cannot.
  • Rate limit: 60 requests per minute, the same as the personal API.

Errors

CodeMeaning
400Invalid body, invalid id, missing workspace_id, conflicting workspace_id, empty body without confirmEmpty, or the 10,000-document account limit
401Missing, malformed, unknown, revoked, or personal (mdf_) token
403Write attempted with a read-only token or on a lapsed account; or the account is deleting
404Not found or not reachable by this token — the two are indistinguishable on purpose
429Rate limit exceeded

Example

# 1. Discover what this token can reach
curl -s https://mdflow.cz/api/team/v1/workspaces \
  -H "Authorization: Bearer $MDFLOW_TEAM_TOKEN"

# 2. Create a document at the root of a workspace
curl -s -X POST https://mdflow.cz/api/team/v1/documents \
  -H "Authorization: Bearer $MDFLOW_TEAM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"workspace_id":"<uuid>","title":"Release notes","body":"# Release notes\n"}'

# 3. Replace its body
curl -s -X PUT https://mdflow.cz/api/team/v1/documents/<uuid>/body \
  -H "Authorization: Bearer $MDFLOW_TEAM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"body":"# Release notes\n\n- Shipped Team API\n"}'

Every write is attributed to the token's creator in the Team audit feed — including deletes.

8. The Team MCP server

A hosted MCP server at https://mdflow.cz/api/team/mcp, authenticated with the same mdt_ token, exposing 16 tools:

WorkspacesFoldersDocuments
mdflow_team_list_workspacesmdflow_team_list_foldersmdflow_team_list_documents
mdflow_team_get_foldermdflow_team_get_document
mdflow_team_create_foldermdflow_team_create_document
mdflow_team_rename_foldermdflow_team_rename_document
mdflow_team_update_folder_descriptionmdflow_team_update_document_body
mdflow_team_move_foldermdflow_team_move_document
mdflow_team_delete_foldermdflow_team_delete_document
mdflow_team_get_context

mdflow_team_get_context is the one to reach for first when an agent is looking for information about a topic rather than a known document: it ranks folder descriptions above folder names and document titles, then returns the best-matching bodies. Pass workspaceId to stay in one workspace, or omit it to rank across everything the token can read.

This is why folder descriptions matter so much in a Team. They are the primary signal an agent uses to decide what is relevant.

Connecting a client

The Team MCP works with any client that can send a bearer header — Claude Code, Cursor, Codex, mcp-remote:

{
  "mcpServers": {
    "mdflow-team": {
      "type": "http",
      "url": "https://mdflow.cz/api/team/mcp",
      "headers": { "Authorization": "Bearer mdt_your_token_here" }
    }
  }
}

Not yet supported: hosted connectors that require OAuth, such as the Claude.ai web connector directory and ChatGPT. Those need per-user OAuth, which is a planned later phase for Teams. The endpoint is already built to accept it without any change to the tools. Until then, use a client that lets you set a header.

The personal MCP server at /api/mcp is unchanged and still uses personal tokens — see 03 MCP Servers.

9. Limits

LimitValue
Team accounts per person10
Members per Team account50
Pending invitations per account50
Workspaces per Team account50
Documents per Team account10,000
Document body size500 KiB
API / MCP rate limit60 requests per minute
Audit feed retention365 days
Grace period after a failed payment30 days

10. Leaving, transferring and deleting

  • Members and admins can leave at any time, in any billing state. The owner cannot.
  • Ownership transfer works in every state except deleting and requires a recent sign-in. This is the recovery path when an owner becomes unreachable.
  • Deleting a Team account requires a recent sign-in and exact-name confirmation. It locks ordinary access first, cancels billing, and only then removes data — so data is never deleted while a subscription could still bill.
  • Deleting your personal MDflow account first requires leaving every Team you are a member of and transferring or deleting every Team you own.

See also