Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcp-lasuite-docs

An MCP server that gives an AI model access to your own La Suite Docs account: list, read, create, update, organize, and share documents.

Runs locally over stdio (e.g. launched by Claude Code / Claude Desktop), acting as you — it's not a hosted multi-user service.

How it works

  • Auth: login happens via a real, visible browser window (Firefox, controlled by Playwright) that drives your Docs instance's own /api/v1.0/authenticate/ flow — the same OIDC/SSO login you'd use normally, including MFA. The resulting Django session cookie is stored locally (encrypted) and reused for API calls; no separate OAuth client registration is needed.
  • Content: document bodies are stored server-side as a base64-encoded Yjs CRDT blob (BlockNote's editor format), not plain Markdown. This server converts transparently in both directions using @blocknote/core + @blocknote/server-util — the same library La Suite Docs' own backend uses for this — so tools speak plain Markdown.

Setup

Prerequisites: Node.js 22+.

npm install
npx playwright install firefox

Create ~/.config/mcp-lasuite-docs/config.json:

{
  "docsBaseUrl": "https://docs.example.org"
}

Log in (opens a Firefox window — complete your normal login there, including any SSO/MFA):

npm run login

Check who's linked, or clear the stored session:

npm run whoami
npm run logout

Using it from Claude Code / Claude Desktop

Add to .mcp.json:

{
  "mcpServers": {
    "lasuite-docs": {
      "type": "stdio",
      "command": "npx",
      "args": ["tsx", "src/server.ts"]
    }
  }
}

Note: this spawns a long-lived subprocess. If you edit the server's source, reconnect/restart it (e.g. /mcp reconnect in Claude Code) to pick up the changes — it won't hot-reload.

Tools

Account

  • whoami — the currently linked Docs account
  • search_users — search users by email (≥5 chars), to find a user_id before sharing

Documents

  • list_documents — list documents visible to you (filter by title/favorite/creator, sort, paginate)
  • get_document — metadata + body content (decoded to Markdown)
  • create_document — create a document, optionally with Markdown content and/or a parent (sub-document)
  • update_document — update title and/or body content
  • delete_document / restore_document — soft-delete (trash) / restore
  • list_trash — recoverable soft-deleted documents
  • list_favorites / set_favorite
  • get_document_tree — ancestors + children (breadcrumb view)
  • move_document — reposition in the document tree

Sharing

  • get_document_sharing — link-sharing config + direct accesses + invitations
  • set_link_sharing — configure link_reach / link_role
  • share_document — grant a user direct access
  • update_document_access / revoke_document_access

Versions

  • list_document_versions — version history
  • get_document_version — a specific historical version, decoded to Markdown where available

Not built yet: duplicating documents, listing full descendant subtrees, deleting a specific version, email invitations for users without accounts yet, file attachments, templates, AI transform/translate passthroughs.

Project layout

src/
├── server.ts        # FastMCP app + tool registration
├── config.ts         # config.json loading (docsBaseUrl)
├── auth.ts           # Playwright login flow, encrypted session-cookie storage
├── docsClient.ts      # REST client: cookie/CSRF auth, pagination, error mapping
├── content.ts         # Markdown <-> Yjs conversion (@blocknote/server-util)
├── tools/             # tool implementations (documents, sharing, versions, users)
└── cli.ts             # `login` / `logout` / `whoami` commands

Known quirks of this API surface

Some things differ from the general La Suite Docs API documentation and were found by probing a real instance:

  • Document body content is not embedded in the main documents/{id}/ response. It lives at a separate GET/PATCH documents/{id}/content/ endpoint, returned as raw text/plain base64 (not JSON) on GET, and written as PATCH with JSON body {"content": "<base64>"}.
  • The Yjs XML fragment holding the document body is named document-store (not BlockNote's own default of prosemirror).
  • documents/{id}/versions/ uses S3-style cursor pagination ({count, is_truncated, next_version_id_marker, versions}), not the standard DRF paginated envelope.
  • State-changing requests need X-CSRFToken plus Origin/Referer headers matching the instance, in addition to the session cookie (Django's CSRF protection).

Security notes

  • Your actual Docs username/password never touch this tool — you log in directly against your identity provider's own page in the Playwright-controlled browser.
  • The session cookie is stored AES-256-GCM encrypted at ~/.config/mcp-lasuite-docs/session.enc, with the key at ~/.config/mcp-lasuite-docs/key (both 0600). As with most local CLI credential stores, the real protection boundary is OS file permissions on your home directory, not the encryption itself.
  • There's no refresh mechanism for the session (unlike OAuth tokens) — once the Django session cookie expires, tools will fail with an auth error and you'll need to npm run login again.

About

An MCP server for La Suite Docs

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages