Sutram MCP Server User Guide
Connect Sutram to Claude (and other MCP-compatible clients) so you can query, summarize, edit, and organize your project content — documents, records, comments, team chat, and a typed knowledge graph — all in natural language.
This is the complete reference. If you just want to get connected, read At a glance and Path A, then jump to Try a starter prompt. Everything after Available tools is reference material you can skim as needed.
Overview
Sutram's MCP integration lets AI assistants and automation tools connect to your projects through the Model Context Protocol (MCP). Once configured, your assistant can browse folders, upload files, add web/video/audio links, manage structured records, work the file-versioning lifecycle, read and write document comments, post to the team chat, and build a wiki/knowledge graph — all with proper authentication and per-role permissions.
How it works
AI Assistant (Claude, Cursor, etc.)
|
| MCP protocol (Streamable HTTP, spec 2025-06-18)
v
Sutram MCP endpoint
https://app.sutram.io/mcp/v2
|
| OAuth 2.0 (or dual-key bridge)
v
Your project (folders, files, records, comments, chat, wiki)
Each connector session is bound to one project. There are two ways to authenticate:
| Method | Best for | How the project is chosen |
|---|---|---|
| OAuth Custom Connector | Claude.ai (web), Claude Desktop with Custom Connectors | You pick the project on the consent screen; the token is scoped to it |
| Dual-key bridge | Claude Code (CLI), Cursor, older Claude Desktop builds | The project key (sk_proj_…) identifies the project |
Both paths talk to the same server and expose the same tools.
At a glance
| You're using | Use this path |
|---|---|
| Claude.ai (web) or Claude Desktop with Custom Connectors | OAuth Custom Connector — one click, no API keys |
| Claude Code (CLI), Cursor, or older Claude Desktop builds | API key bridge — paste a config file with two keys |
| Any other MCP-capable client / automation | Raw Streamable HTTP — JSON-RPC against /mcp/v2 |
Plan requirement: MCP access requires a Sutram subscription on the Pro plan or higher. The Basic plan does not include MCP. Some tool groups have their own plan gates — see each section.
Path A — OAuth Custom Connector (recommended)
1. Open the Connectors panel in Claude
In Claude.ai (or Claude Desktop with Custom Connector support):
- Open Settings (gear icon) → Connectors
- Click Add custom connector
2. Add the Sutram URL
- Name:
Sutram(or any label you like) - URL:
https://app.sutram.io/mcp/v2
Click Add.
3. Connect and authorize
Click Connect. Claude opens a browser window to https://app.sutram.io/mcp/v2/oauth/authorize.
- If you're already logged into Sutram, you go straight to the consent screen.
- Otherwise, sign in to Sutram first; you land on the consent screen automatically.
The consent screen asks you to pick the project the connector should reach. The OAuth token is scoped to that single project — pick carefully.
Click Authorize.
You're redirected back to Claude with the connector showing as connected.
4. Allow the network (one-time, until directory listing is live)
Claude.ai keeps an outbound network allowlist. MCP traffic to app.sutram.io is allowed by default, but file downloads come from a CDN and file uploads go straight to S3 — both need explicit authorization once:
- Settings → Capabilities → Code Execution and File Creation (section names vary by Claude build; look for the outbound network allowlist)
- Under Additional allowed domains, add all three:
app.sutram.io— MCP endpoint, OAuth, discoveryfiles.sutram.io— file downloads (CloudFront edge)s3.amazonaws.com— direct file uploads (presigned URL endpoint)
Once Sutram is listed in the Anthropic Connectors Directory, these three hosts are declared in the listing and clients authorize them automatically.
5. (Optional) Apply the Sutram Assistant Preset
Without the preset, Claude works — but it may occasionally ask you to "attach a file" or "connect a folder" when you mean a Sutram document, because it hasn't been told what context to assume.
To make Claude Sutram-aware by default, copy the System Prompt from the Sutram Assistant Preset page and paste it into your Claude project's Custom Instructions (Personalization / Project System Prompt — name varies by client).
After this, prompts like "Summarize my latest cardiology exam" go straight to the Sutram connector instead of asking you to upload anything.
6. Try a starter prompt
Open a new conversation and ask:
Show me an overview of my project and what's in it.
Claude calls sutram_project_info and sutram_get_folder in sequence and returns a structured summary of your project root.
Path B — API key bridge (Claude Code, Cursor, older Claude Desktop)
Use this when your client doesn't yet support Custom Connectors (Claude Code CLI, Cursor, older Claude Desktop builds, or local development against a non-public Sutram instance).
1. Create your personal API key
Settings → Integrations → Claude → click Generate user key.
Your personal key looks like:
sk_user_…
Copy it once — it's not retrievable later.
2. Get the project key
The project owner must first enable MCP access for the project:
Project Settings → Integrations → toggle Enable MCP access ON.
Once enabled, any project member (owner, admin, or member) can copy the project key from the same screen:
sk_proj_…
3. Configure your client
The same JSON block works in all three clients — only the file location changes.
{
"mcpServers": {
"sutram": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://app.sutram.io/mcp/v2",
"--header",
"Authorization: Bearer dualkey:sk_proj_...:sk_user_..."
]
}
}
}
Replace sk_proj_... and sk_user_... with your real keys.
The
Authorizationheader must be a single line — JSON does not allow control characters inside string literals. Thedualkey:prefix tells the server to read the two keys that follow, separated by colons.
One config per project. Because the project key is bound to a single project, keep a dedicated workspace folder (and
.mcp.json) per Sutram project. Your user key (sk_user_…) is the same everywhere — it identifies you; the project key (sk_proj_…) changes per project.
Claude Code (CLI) — recommended
Create the JSON above as .mcp.json in your workspace folder. Start Claude Code from that folder; Sutram tools are scoped to that workspace.
Cursor
Create the JSON above as .cursor/mcp.json in your project folder.
Claude Desktop (older builds)
Edit the global config:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
Add the mcpServers block alongside any existing keys, then restart Claude Desktop. Give each project entry a descriptive name (e.g. sutram-health, sutram-construction) so you can tell them apart.
4. Try a prompt
Show me an overview of my Sutram project.
API key bridge clients don't enforce a host allowlist, so file downloads work without further configuration.
Other MCP clients (raw Streamable HTTP)
Sutram uses the MCP Streamable HTTP transport (JSON-RPC 2.0 over HTTPS). Any MCP client that supports HTTP transport can connect directly:
- Endpoint:
https://app.sutram.io/mcp/v2 - Method:
POST(JSON-RPC 2.0);GETopens the SSE stream for server-initiated messages - Protocol version:
2025-06-18(the server also accepts2025-03-26) - Authentication:
Authorization: Bearer dualkey:<project_key>:<user_key>(the legacyx-project-key+x-user-keyheaders are also accepted for backward compatibility)
For clients that only support stdio, bridge with mcp-remote:
npx -y mcp-remote https://app.sutram.io/mcp/v2 \
--header "Authorization: Bearer dualkey:sk_proj_YOUR_PROJECT_KEY:sk_user_YOUR_USER_KEY"
See Uploading files via script for a full raw-HTTP example, including the initialize → notifications/initialized → tools/call handshake.
Available tools
Once connected, your assistant has access to around 78 tools. You can also fetch the live list programmatically by sending the standard MCP tools/list request to the endpoint.
Quick reference (A–Z)
| Tool | Category | Description |
|---|---|---|
sutram_add_enum_values |
Schema | Add values to an existing enum metadata definition |
sutram_bulk_create_file_links |
File Links | Create file links in bulk from a source folder to a target folder |
sutram_cancel_checkout |
Versioning | Cancel a checkout without uploading changes |
sutram_checkin_file |
Versioning | Release a checked-out file's lock (keeps draft) |
sutram_checkout_file |
Versioning | Check out a draft file for exclusive editing |
sutram_confirm_upload |
Content | Upload step 2: confirm the file reached S3 |
sutram_create_audio_link |
Content | Create an audio link (Spotify, SoundCloud, …) |
sutram_create_comment |
Comments | Create a file-level or markdown-anchored comment |
sutram_create_document |
Document Classes | Create a governed document (first version) in a Document Class |
sutram_create_document_version |
Document Classes | Create a new revision of a governed document |
sutram_create_documents |
Document Classes | Batch-create governed documents (bootstrap/MDR, dry-run) |
sutram_create_file_link |
File Links | Create a symbolic reference to an existing file |
sutram_create_folder |
Folders | Create a folder or a nested path |
sutram_create_new_version |
Versioning | Start a new version from a published file |
sutram_create_record |
Records | Create a record in a category (slug auto-generated) |
sutram_create_video_link |
Content | Create a video link (YouTube, Vimeo, …) |
sutram_create_web_link |
Content | Create a web link with auto-fetched title/favicon |
sutram_create_wiki_node |
Wiki | Create a referenceable concept/entity node |
sutram_delete |
Content | Delete a content item or folder |
sutram_delete_comment |
Comments | Delete a comment and all its replies |
sutram_delete_metadata |
Schema | Delete a metadata definition |
sutram_delete_record |
Records | Delete a record and its contents recursively |
sutram_delete_record_category |
Schema | Delete a record category |
sutram_delete_wiki_node |
Wiki | Soft-delete a wiki node (destructive) |
sutram_disable_versioning |
Versioning | Turn a file back into a read-only reference |
sutram_enable_versioning |
Versioning | Turn a reference file into a versioned, editable file |
sutram_force_release_lock |
Versioning | Force-release another user's checkout (owner only) |
sutram_get_backlinks |
Wiki | List sources that mention an item via [[slug]] |
sutram_get_chat_thread |
Chat | Get a chat message with its reply thread |
sutram_get_chat_unread_count |
Chat | Count unseen team-chat messages |
sutram_get_comment_thread |
Comments | Get one comment with its full reply thread |
sutram_get_folder |
Folders | List a folder's subfolders, files, and links |
sutram_get_item |
Content | Get one item's details + presigned download URL |
sutram_get_item_tag_keys |
Tags | List distinct tag keys used on content items |
sutram_get_metadata_definitions |
Schema | List all metadata field definitions |
sutram_get_outgoing_mentions |
Wiki | List a source's [[slug]] links (resolved/pending) |
sutram_get_record_categories |
Schema | List all record categories |
sutram_get_record_category_detail |
Schema | Get a category with fully resolved metadata |
sutram_get_tag_keys |
Tags | List distinct tag keys used on folders |
sutram_get_wiki_node |
Wiki | Read one wiki node (synthesis + full source text) |
sutram_graduate_document_class |
Document Classes | Turn a record category into a governed Document Class |
sutram_list_chat_messages |
Chat | List team-chat messages (paginated, searchable) |
sutram_list_comments |
Comments | List top-level comments on a content item |
sutram_list_document_classes |
Document Classes | List the Document Classes you can access |
sutram_list_file_links_for_source |
File Links | List all file links pointing at a source file |
sutram_list_file_links_in_folder |
File Links | List file links in a folder, enriched with source detail |
sutram_list_governed_documents |
Document Classes | List governed documents of a class (need-to-know) |
sutram_list_versions |
Versioning | List all versions of a file with download URLs |
sutram_mark_chat_visited |
Chat | Mark the team chat as read |
sutram_move_contents |
Folders | Move all contents from one folder to another |
sutram_move_item |
Content | Move a single content item to another folder |
sutram_patch_record_metadata |
Records | Merge specific metadata keys on a record |
sutram_project_info |
Project | Return the current project's name, description, settings |
sutram_publish_version |
Versioning | Publish a draft file, creating a version snapshot |
sutram_remove_enum_values |
Schema | Remove values from an enum definition by code |
sutram_rename |
Content | Rename a content item or folder |
sutram_reply_to_chat_message |
Chat | Reply to a top-level chat message |
sutram_reply_to_comment |
Comments | Reply to a top-level comment |
sutram_request_upload |
Content | Upload step 1: return a presigned S3 PUT URL |
sutram_resolve_comment |
Comments | Resolve or reopen a comment thread |
sutram_resolve_slug |
Wiki | Resolve a [[slug]] to the item it points at |
sutram_revert_document_class |
Document Classes | Revert a Document Class back to a plain category |
sutram_search_folders |
Tags | Search folders by tag (single or AND conditions) |
sutram_search_items |
Tags | Search content items by tag |
sutram_search_wiki |
Wiki | Full-text search over the wiki's content |
sutram_search_wiki_nodes |
Wiki | Browse wiki nodes by name/category |
sutram_send_chat_message |
Chat | Post a new message to the team chat |
sutram_set_document_class_lifecycle |
Document Classes | Replace a class's lifecycle (states/roles/permissions) |
sutram_set_folder_tags |
Tags | Set key-value tags on a folder (replaces all) |
sutram_set_item_tags |
Tags | Set key-value tags on a content item (replaces all) |
sutram_set_wiki_relation_labels |
Wiki | Set the project's passive→active relation vocabulary |
sutram_sync_wiki_source |
Wiki | Fill a node's source_text from a linked record's markdown |
sutram_undo_checkin |
Versioning | Undo the last checkin, restoring the previous version |
sutram_update_record |
Records | Replace a record's metadata (recomputes slug) |
sutram_update_wiki_node |
Wiki | Update a wiki node's body, metadata, or typed edges |
sutram_upload_modified_file |
Versioning | Replace file content during a checkout |
sutram_upsert_metadata |
Schema | Create or update a metadata field definition |
sutram_upsert_record_category |
Schema | Create or update a record category |
By category: Project (1) · Folders (3) · Content (9) · File Links (4) · Tags (6) · Versioning (11) · Schema (9) · Records (4) · Document Classes (8) · Comments (6) · Chat (6) · Wiki (11)
Read-only tools may be auto-approved by your client. Destructive tools (sutram_delete, sutram_delete_record, sutram_delete_record_category, sutram_delete_metadata, sutram_delete_comment, sutram_delete_wiki_node, sutram_force_release_lock) always ask for explicit confirmation per call.
The sections below describe each tool in detail, organized by capability.
Project & discovery
sutram_project_info
Returns information about the current project. Often the first call in a session.
Parameters: none
Example response:
{
"project": {
"id": "a1b2c3d4-...",
"name": "Construction Site Alpha",
"description": "Main project documentation",
"your_role": "member",
"created_at": "2026-01-15T10:00:00Z"
}
}
sutram_get_folder
Browse a folder's contents (subfolders, files, and links). Omit folder_id to list the project root. Each file in the response includes a ready-to-fetch download_url (valid ~15 min) — no need to call sutram_get_item per file just to get URLs.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID. Omit for the root. |
Example response:
{
"folder": { "id": null, "name": "Root", "path": "/" },
"contents": [
{ "type": "folder", "id": "f1a2b3c4-...", "name": "Reports",
"tags": {"category": "monthly", "department": "engineering"} },
{ "type": "file", "id": "d5e6f7a8-...", "name": "site-plan.pdf",
"content_type": "application/pdf", "size": 2450000,
"download_url": "https://files.sutram.io/...?Expires=..." },
{ "type": "web_link", "id": "a1b2c3d4-...", "name": "Project Wiki",
"url": "https://wiki.example.com/project" },
{ "type": "video_link", "id": "e5f6a7b8-...", "name": "Site walkthrough",
"url": "https://www.youtube.com/watch?v=abc123", "platform": "youtube" }
]
}
sutram_get_item
Get full details of one content item by ID. For files, returns metadata plus a presigned download URL. For links (web, video, audio, file_link), returns the URL, platform info, and metadata.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | UUID of the content item |
Example response (file):
{
"id": "d5e6f7a8-...",
"type": "file",
"name": "site-plan",
"tags": {"category": "plan", "year": "2024"},
"folder_id": "f1a2b3c4-...",
"filename": "site-plan.pdf",
"file_size": 2450000,
"content_type": "application/pdf",
"version": 1,
"download_url": "https://files.sutram.io/...?Expires=..."
}
sutram_resolve_slug
Resolves a wiki slug (the token inside a [[slug]] mention) to the item it points at, returning its kind (content_item or folder), id, and name. Use it to check whether a [[mention]] resolves, or to find an item's id from its slug before linking to it. An unresolved slug means a pending mention — the target doesn't exist yet.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
slug |
string | Yes | The slug to resolve (e.g., rdc-753-2022) |
Folders
sutram_create_folder
Create a new folder. Supports creating nested hierarchies in a single call.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes* | Folder name (single folder) |
path |
string | Yes* | Slash-separated path for nested creation (e.g. "A/B/C") |
parent_folder_id |
string | No | Parent folder UUID. Omit for the root. |
tags |
object | No | Free-form key-value tags. With path, tags apply only to the deepest (leaf) folder. |
*Use name (single folder) or path (nested hierarchy), not both.
Nested creation: With path, intermediate folders are created automatically. If any folder on the path already exists, it is reused — the operation is idempotent.
Example — nested hierarchy with tags:
{
"path": "Dr. Decio Mion/USG ABDOME TOTAL/2024-12-12",
"tags": {"patient": "João Silva", "exam_type": "USG ABDOME TOTAL", "year": "2024"}
}
This creates three folders in one call and returns the deepest (2024-12-12) with the specified tags.
sutram_move_contents
Move all contents (subfolders and files) from a source folder to a target folder. The source is emptied but not deleted. Name conflicts are handled automatically.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_folder_id |
string | Yes | UUID of the folder to empty |
target_folder_id |
string | Yes | UUID of the folder that receives the contents |
Name-conflict handling: if a subfolder or file with the same name already exists in the target, Sutram appends a numeric suffix: Exams → Exams (1), report.pdf → report (1).pdf.
Validation rules: source and target must differ; the target cannot be a subfolder of the source (prevents circular moves); both folders must exist in the current project.
Example response:
{
"moved": { "folders": 3, "content_items": 12 },
"renamed": { "folders": ["Exams (1)"], "files": ["report (1).pdf"] }
}
Content (files & links)
sutram_request_upload
Step 1 of the direct-upload flow. Validates the file against plan limits and returns a presigned S3 PUT URL. The file is uploaded straight to S3 by the client — no bytes pass through Sutram's web servers. The URL expires in 15 minutes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
filename |
string | Yes | Filename with extension (e.g. report.pdf) |
file_size |
integer | Yes | File size in bytes |
content_type |
string | No | MIME type. Auto-detected from the extension if omitted. |
folder_id |
string | No | Target folder UUID. Omit for the root. |
Example response:
{
"upload_url": "https://s3.amazonaws.com/.../files/abc123.pdf?X-Amz-...",
"s3_key": "projects/a1b2c3d4-.../files/abc123.pdf",
"file_id": "abc123-...",
"expires_in": 900
}
sutram_confirm_upload
Step 2 of the direct-upload flow. Call after the bytes have been PUT to the presigned URL. Verifies the S3 object exists, creates the file record, updates storage usage, and enqueues compression if applicable.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
file_id |
string | Yes | File UUID from sutram_request_upload |
s3_key |
string | Yes | S3 key from sutram_request_upload |
filename |
string | Yes | Original filename with extension |
content_type |
string | Yes | MIME type |
file_size |
integer | Yes | File size in bytes |
folder_id |
string | No | Target folder UUID (must match the request) |
Full upload flow:
# 1. sutram_request_upload (MCP tool call) → upload_url, s3_key, file_id
# 2. PUT the bytes directly to S3
curl -X PUT -H "Content-Type: application/pdf" \
--data-binary @report.pdf \
"https://s3.amazonaws.com/.../files/abc123.pdf?X-Amz-..."
# 3. sutram_confirm_upload (MCP tool call) → file record created
sutram_create_web_link
Create a web link. Sutram auto-fetches the page title and favicon from the URL.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Page URL (http or https) |
name |
string | No | Display name. Auto-fetched from the page title if omitted. |
folder_id |
string | No | Target folder UUID. Omit for the root. |
sutram_create_video_link
Create a video link. Supports YouTube, Vimeo, DailyMotion, Wistia, Loom, and TikTok. The platform is auto-detected and the video ID extracted from the URL; thumbnails are fetched when available.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Video URL (e.g. https://www.youtube.com/watch?v=...) |
name |
string | No | Display name. Defaults to the URL if omitted. |
folder_id |
string | No | Target folder UUID. Omit for the root. |
sutram_create_audio_link
Create an audio link. Supports Spotify, SoundCloud, Apple Podcasts, Anchor, and others. The platform is auto-detected from the URL.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | Audio URL (e.g. https://open.spotify.com/track/...) |
name |
string | No | Display name. Defaults to the URL if omitted. |
folder_id |
string | No | Target folder UUID. Omit for the root. |
sutram_get_item
See Project & discovery above — it serves both as the discovery entry point and the canonical read for a single content item.
sutram_delete
Delete a content item (file, web/video/audio link) or a folder. Destructive — always confirmed per call.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
item_id |
string | Yes | UUID of the content item or folder |
item_type |
string | Yes | "content_item" or "folder". Use "content_item" for any content type. |
sutram_rename
Rename a content item or folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
item_id |
string | Yes | UUID of the content item or folder |
item_type |
string | Yes | "content_item" or "folder" |
new_name |
string | Yes | New name (for files, include the extension) |
sutram_move_item
Move a single content item (file or link) to another folder. Name conflicts are handled automatically with numeric suffixes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | UUID of the content item to move |
target_folder_id |
string/null | No | Target folder UUID (null for the root) |
Example response (with rename):
{
"moved": true,
"renamed": true,
"new_filename": "report (1).pdf",
"content_item": { "id": "abc123-...", "name": "report (1)", "folder_id": "def456-..." }
}
File links
A file link is a symbolic reference to an existing file. It appears as a read-only reference without duplicating storage or versioning. The source must be a file (not a link or another file link). If the source file is deleted, all of its file links are removed automatically.
sutram_create_file_link
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_content_item_id |
string | Yes | UUID of the source file to link |
name |
string | No | Display name (defaults to the source filename) |
folder_id |
string | No | Target folder UUID (omit for the root) |
description |
string | No | File link description |
sutram_bulk_create_file_links
Create file links for all files (or a filtered subset) in a source folder, placing them in a target folder. Files that already have a link in the target are skipped automatically (deduplication), so re-running is safe.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_folder_id |
string | Yes | Source folder UUID containing the files to link |
target_folder_id |
string | Yes | Target folder UUID where the links are created |
name_pattern |
string | No | Case-insensitive substring filter on source filenames |
recursive |
boolean | No | Include files in subfolders of the source (default: false) |
Example response:
{ "created": 5, "skipped": 2, "file_links": [ { "id": "f1a2b3c4-...", "name": "laudo-hemograma.pdf" } ] }
sutram_list_file_links_for_source
List all file links pointing at a given source file — "where is this file referenced?" Returns each link with its folder path.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_content_item_id |
string | Yes | UUID of the source file |
sutram_list_file_links_in_folder
List file links in a folder, enriched with the source file's details (name, content type, size, folder path). Unlike sutram_get_folder, this resolves the source each link points at.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID (omit for the root) |
Tags & search
Tags are free-form key-value pairs you can attach to folders and content items, then search. All matching is case-insensitive for keys and values; values support substring matching (e.g. "orto" matches "Ortopedia").
sutram_set_folder_tags
Set key-value tags on a folder. Replaces all existing tags. Send {} to clear all tags.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | Yes | Folder UUID |
tags |
object | Yes | Key-value tags to set. Send {} to clear. |
Limits: max 50 tags per folder; key ≤ 100 chars, value ≤ 500 chars.
Semantics: this is a PUT — it replaces all existing tags. To add one tag without removing the others, first read the current tags (via sutram_get_folder), merge your change, and call this with the full set.
sutram_set_item_tags
Set key-value tags on a content item. Same PUT semantics and limits as sutram_set_folder_tags. Read current tags via sutram_get_item before merging.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | Content item UUID |
tags |
object | Yes | Key-value tags to set. Send {} to clear. |
sutram_get_tag_keys
Return all distinct tag keys used on folders in the project. Useful for discovering available tags before a search. Use folder_id to scope to a folder's descendants.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Scope to descendants of this folder |
Example response:
{ "keys": ["exam_type", "patient", "specialty", "year"], "count": 4 }
sutram_get_item_tag_keys
Return all distinct tag keys used on content items. Use folder_id to scope, and type to filter by content type.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Scope to a folder |
type |
string | No | "file", "file_link", "web_link", "video_link", "audio_link" |
sutram_search_folders
Search folders by tag. Supports a single condition or multiple AND conditions. Use folder_id to restrict the search to a folder's descendants.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tag_name |
string | No* | Tag key to search (single-condition mode). Case-insensitive. |
tag_value |
string | No | Value to match (single-condition mode). Substring, case-insensitive. |
conditions |
array | No* | Multiple AND conditions. Each object has key (required) and value (optional). |
folder_id |
string | No | Restrict to descendants of this folder |
*Use tag_name (single condition) or conditions (multiple AND conditions).
Behavior: key match is exact (case-insensitive); value match is substring (case-insensitive); omitting the value matches any folder that has the key; multiple conditions all must match (AND).
Example — AND search:
{
"conditions": [
{ "key": "patient", "value": "joão" },
{ "key": "exam_type", "value": "USG" }
]
}
sutram_search_items
Search content items by tag. Same single/AND semantics as sutram_search_folders, plus a type filter.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tag_name |
string | No* | Tag key (single-condition mode) |
tag_value |
string | No | Value to match (substring, case-insensitive) |
conditions |
array | No* | Multiple AND conditions (key + optional value) |
folder_id |
string | No | Restrict the search to a folder |
type |
string | No | "file", "file_link", "web_link", "video_link", "audio_link" |
File versioning
Sutram supports a full version-control lifecycle for files via MCP: enable versioning, check out for exclusive editing, upload modifications, check in, and publish.
Workflow
1. Enable versioning → sutram_enable_versioning
2. Check out file → sutram_checkout_file
3. Upload modification → sutram_request_upload + PUT to S3 + sutram_upload_modified_file
4. Check in file → sutram_checkin_file
5. Publish version → sutram_publish_version
6. New version → sutram_create_new_version (returns to step 2)
Versioning tools
| Tool | Description | Permission |
|---|---|---|
sutram_enable_versioning |
Turn a reference file into an editable, versioned file | Owner, Member |
sutram_disable_versioning |
Turn a file back into a read-only reference | Owner, Member |
sutram_checkout_file |
Check out a draft file for exclusive editing | Owner, Admin, Member |
sutram_checkin_file |
Release the checkout lock (keeps draft) | Checkout user |
sutram_cancel_checkout |
Cancel the checkout, discarding pending changes | Checkout user |
sutram_force_release_lock |
Force-release another user's checkout | Owner only |
sutram_publish_version |
Publish a draft, creating a version snapshot | Owner only |
sutram_create_new_version |
Start a new version from a published file | Owner only |
sutram_undo_checkin |
Undo the last checkin, restoring the prior version | Last-checkin user |
sutram_list_versions |
List all published versions with download URLs | Any member |
sutram_upload_modified_file |
Replace file content during a checkout | Checkout user |
Parameters
All versioning tools require content_item_id (the content item UUID). sutram_upload_modified_file additionally requires:
| Parameter | Type | Description |
|---|---|---|
s3_key |
string | S3 key from sutram_request_upload |
file_name |
string | Filename with extension |
file_size |
integer | File size in bytes |
content_type |
string | MIME type |
Lifecycle note: only draft files can be checked out. To amend a published file, call
sutram_create_new_versionfirst — it transitions the file back to draft with an incremented version number, preserving the previous published snapshot.
Example: full versioning flow
// 1. Enable versioning
→ sutram_enable_versioning { "content_item_id": "abc-123" }
← { "file": { "file_type": "editable", "lifecycle_status": "draft", "version": 1 } }
// 2. Check out
→ sutram_checkout_file { "content_item_id": "abc-123" }
// 3. Get a presigned URL, then PUT the new bytes to S3
→ sutram_request_upload { "filename": "report_v2.pdf", "file_size": 5000 }
// 4. Register the modification
→ sutram_upload_modified_file {
"content_item_id": "abc-123", "s3_key": "projects/.../file.pdf",
"file_name": "report_v2.pdf", "file_size": 5000, "content_type": "application/pdf" }
// 5. Check in (stays draft) — then publish (owner only)
→ sutram_checkin_file { "content_item_id": "abc-123" }
→ sutram_publish_version { "content_item_id": "abc-123" }
← { "file": { "lifecycle_status": "published", "version": 1 } }
// 6. List versions
→ sutram_list_versions { "content_item_id": "abc-123" }
Record categories & records
Sutram supports structured records with metadata schemas and auto-generated slugs. AI assistants can define metadata fields, create record categories, and manage records programmatically.
Plan requirement: record/schema management tools require a plan with the Records feature enabled. The read-only tools (
sutram_get_metadata_definitions,sutram_get_record_categories,sutram_get_record_category_detail) are available on every plan.
Concepts
- Metadata definitions — field schemas that define the type, label, and allowed values of a metadata field (e.g. "language" as an enum with values PT, EN, ES).
- Record categories — templates that define which metadata fields a record uses, their order, how the numeric base is computed (
computed_from), and how the slug (record name) is composed (slug_from). - Records — folders created with a category, validated metadata, and an auto-generated slug.
Slug generation
Each record gets an auto-generated slug (used as the record name), built in two stages:
- Numeric base — determined by the
computed_fromentries on a computed metadata tag. Defines which field values form the uniqueness key for sequential numbering. - Slug composition — determined by the
slug_fromentries on the category. Defines which field values (including the computed tag) make up the final slug.
- Without
slug_from(backward compatible): slug =number_base+separator+sequence_number(e.g.CARDIO-001). - With
slug_from: slug is composed from the referenced fields in order (e.g.MD-3010.95-0000-000-SWA-001).
Slug trap: a record's computed slug key stores the full slug, not the raw sequence.
sutram_update_recordre-numbers;sutram_patch_record_metadatapreserves the slug when you patch a non-slug field.
Schema tools
| Tool | Description | Permission |
|---|---|---|
sutram_get_metadata_definitions |
List all metadata definitions | Any member |
sutram_get_record_categories |
List all record categories | Any member |
sutram_get_record_category_detail |
Category with resolved metadata (labels, types, allowed values) | Any member |
sutram_upsert_metadata |
Create or update a metadata definition | Owner only |
sutram_delete_metadata |
Delete a metadata definition (fails if in use) | Owner only |
sutram_add_enum_values |
Add values to an enum (merges, dedupes, sorts) | Owner only |
sutram_remove_enum_values |
Remove enum values by code | Owner only |
sutram_upsert_record_category |
Create or update a record category | Owner only |
sutram_delete_record_category |
Delete a record category | Owner only |
Record CRUD tools
| Tool | Description | Permission |
|---|---|---|
sutram_create_record |
Create a record (category + metadata + auto slug) | Owner, Admin, Member |
sutram_update_record |
Replace a record's metadata (recomputes slug if needed) | Owner, Admin, Member |
sutram_patch_record_metadata |
Merge specific metadata keys (leaves the rest untouched) | Owner, Admin, Member |
sutram_delete_record |
Delete a record and all its contents recursively | Owner, Admin, Member |
sutram_get_metadata_definitions
Returns all metadata definitions. Each has a key plus properties: label, type (text, enum, boolean, date, computed), and optionally values, depends_on, values_map. No parameters.
sutram_get_record_categories
Returns all record categories. Each defines which metadata fields a record uses, slug configuration, and ordering. No parameters.
sutram_get_record_category_detail
Returns a category with fully resolved metadata (labels, types, allowed values). Use this to learn the required fields before creating a record.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Record category id |
sutram_upsert_metadata
Create or update a metadata definition. For enum types, provide the full values array; for large enums prefer sutram_add_enum_values for incremental additions.
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Unique key (snake_case, e.g. specialty) |
definition |
object | Yes | Definition with label, type, and optional fields |
Supported types: text, enum, boolean, date, computed.
Example — simple enum:
{
"key": "language",
"definition": {
"label": "Language", "type": "enum",
"values": [ { "label": "Portuguese", "code": "PT" }, { "label": "English", "code": "EN" } ]
}
}
sutram_add_enum_values / sutram_remove_enum_values
Add or remove enum values without resending the whole array. Additions merge, dedupe by code, and sort.
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Enum definition key |
values |
array | Yes (add) | Array of {label, code} to add |
codes |
array | Yes (remove) | Array of code strings to remove |
sutram_upsert_record_category
Create or update a record category. Metadata must reference existing definitions. Use computed_from on a metadata entry to define the numeric base (uniqueness); use slug_from at the category level to define how the slug is composed.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Unique category id (snake_case) |
category |
object | Yes | Category definition (fields below) |
Category fields: name (string, required), metadata (array, required), slug_separator (string, default "-"), slug_from (array, optional — each entry has key and use: "code" or "label").
Metadata entry fields: key (required), required (bool, default false), order (int, 0-based), computed_from (array — for computed tags; each entry has key and use), sequence_digits (int, 2–4, default 2 — for computed tags).
Example — category with slug_from:
{
"category_id": "doc_tecnico_n1710",
"category": {
"name": "Technical Document N-1710",
"metadata": [
{ "key": "language", "order": 0 },
{ "key": "document_category", "required": true, "order": 1 },
{ "key": "installation", "required": true, "order": 2 },
{ "key": "coded_number", "order": 3,
"computed_from": [
{ "key": "language", "use": "code" },
{ "key": "document_category", "use": "code" },
{ "key": "installation", "use": "label" }
],
"sequence_digits": 3 }
],
"slug_separator": "-",
"slug_from": [
{ "key": "language", "use": "code" },
{ "key": "document_category", "use": "code" },
{ "key": "installation", "use": "label" },
{ "key": "coded_number", "use": "label" }
]
}
}
sutram_create_record
Create a record with a category, validated metadata, and an auto-generated slug. Call sutram_get_record_category_detail first to see the required fields.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Record category id |
metadata |
object | Yes | Key-value pairs matching the category's fields |
parent_folder_id |
string | No | Parent folder UUID (omit for the root) |
name |
string | No | Custom name (defaults to the generated slug) |
sutram_update_record
Replace a record's metadata. Recomputes the numeric base and slug when fields referenced by computed_from or slug_from change.
| Parameter | Type | Required | Description |
|---|---|---|---|
record_id |
string | Yes | Record (folder) UUID |
metadata |
object | Yes | Updated key-value pairs (replaces the whole map) |
name |
string | No | New name (optional) |
sutram_patch_record_metadata
Patch one or more metadata keys, merging them into the existing metadata (unlike sutram_update_record, which replaces the whole map). Pass only the keys you want to change; set a key to null to remove it. Patching a non-slug field leaves the slug and sequence number untouched; patching a slug-determining field recomputes the slug like sutram_update_record.
| Parameter | Type | Required | Description |
|---|---|---|---|
record_id |
string | Yes | Record (folder) UUID |
metadata |
object | Yes | Only the keys to set or remove (null removes a key) |
name |
string | No | New name (by default the name follows the recomputed slug only if it already mirrored the slug) |
Example — change a single field:
{ "record_id": "rec-123", "metadata": { "status": "approved" } }
Example: full records flow
// 1. Define metadata
→ sutram_upsert_metadata { "key": "language", "definition": { "label": "Language", "type": "enum",
"values": [{"label":"PT","code":"PT"}, {"label":"EN","code":"EN"}] } }
→ sutram_upsert_metadata { "key": "area", "definition": { "label": "Area", "type": "enum",
"values": [{"label":"Automação","code":"0100"}] } }
→ sutram_upsert_metadata { "key": "doc_number", "definition": { "label": "Number", "type": "computed" } }
// 2. Create a category with computed_from + slug_from
→ sutram_upsert_record_category { "category_id": "doc_tecnico", "category": { ... } }
// 3. Create a record — slug auto-generated
→ sutram_create_record { "category_id": "doc_tecnico",
"metadata": { "language": "PT", "area": "Automação", "origin": "SWA" } }
← { "record": { "name": "PT-0100-SWA-001", "slug": "PT-0100-SWA-001", ... } }
// 4. Patch a single field later — slug preserved
→ sutram_patch_record_metadata { "record_id": "...", "metadata": { "status": "approved" } }
Document Classes (governed documents)
Document Classes are a Max-plan feature. A Document Class is a Record Category that has been graduated — given a lifecycle: a set of states, class roles, per-state permissions, transitions, and an optional version axis. Documents created in a Document Class are governed: who can read, edit, create versions, and move them between states is decided by the project access level (owner/admin/member/viewer) intersected with the class role matrix.
Concepts
- Document — a family of versions sharing one computed identity (
slug) inside a class. Each version is a floating container (it does not appear in the folder tree; it surfaces through governed listings and dynamic folders). - Lifecycle — the governance block:
states(one isinitial),roles(class roles like author/reviewer),actions(transitionsfrom→towithallowed_roles),state_access(astate → role → "read"|"write"matrix), and an optionalversionaxis. A missing(state, role)pair means no access (need-to-know). - Need-to-know — owners/admins see every governed document; members/viewers see only the classes where they hold a role, and only documents in states their role may read.
Assigning a user to a class role is done in the web UI — there is no MCP tool for role assignment. The MCP surface covers graduating/editing the class, listing, and creating governed documents.
sutram_graduate_document_class
Turns a plain Record Category into a governed Document Class by applying the default lifecycle preset (author → reviewer → approver), fully editable afterwards with sutram_set_document_class_lifecycle. Owner/admin only; requires the Max plan.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Record category id to graduate |
sutram_set_document_class_lifecycle
Replaces the entire lifecycle of a Document Class — the single tool for all governance (states, roles, per-state permissions, transitions, version axis, display). Read-modify-write: call sutram_get_record_category_detail first (it returns the category with its lifecycle), change what you need, then send the whole lifecycle back. Validated server-side (≥1 state, exactly one initial, unique ids, references must exist). Owner/admin only; Max plan.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Document Class id |
lifecycle |
object | Yes | The full lifecycle object (states, roles, actions, state_access, optional version/listing) — replaces the existing one |
sutram_revert_document_class
Reverts a Document Class back to a plain Record Category, removing its governance (lifecycle + per-class role assignments). Blocked while the class still has governed documents — delete them first. Doesn't delete content. Owner/admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Document Class id to revert |
sutram_list_document_classes
Lists the Document Classes you can access. Owner/admin see all governed classes (with volume stats); member/viewer see only the classes where they hold a role. Each item includes uid, category_id, name, your role, and doc_count. Use it to get the uid needed by sutram_list_governed_documents. No arguments.
sutram_list_governed_documents
Lists the governed documents of a class (by its immutable category_uid). Honors need-to-know — only documents in states you may read are returned. Supports state filtering, tag conditions, version mode, and pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_uid |
string | Yes | Immutable uid of the Document Class (from sutram_list_document_classes) |
states |
array | No | State ids to include (intersected with the states you may read — never widens permission) |
tag_conditions |
array | No | {key, value} filters (AND) over each version's metadata; omit value to match key existence |
all_versions |
boolean | No | false (default) = one row per family (last version you may read); true = one row per readable version |
page |
integer | No | Page number (default 1) |
per_page |
integer | No | Page size (default 50, max 200) |
sutram_create_document
Creates a governed document: the family plus its first version (a floating container) in an entry state, with a computed identity (slug). Use it for the first version of a versioned class and for every document of a non-versioned class. Authorized by the PDP: you need :write at the entry state (owner/admin bypass; viewer never). Call sutram_get_record_category_detail first to learn the required metadata fields and the version axis.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Document Class id |
metadata |
object | Yes | Typed metadata that forms the document/slug |
version_values |
object | No | Version-axis values (e.g. {"rev": "A"}); required when the class has a version axis |
lifecycle_state |
string | No | Entry state id (defaults to the class's initial state) |
name |
string | No | Custom name (defaults to the computed slug) |
sutram_create_document_version
Creates a new revision of an existing governed document, from a source version. The new version inherits the family identity (same slug, formative tags copied) and gets a new version_key, born in an entry state. Requires a versioned class.
| Parameter | Type | Required | Description |
|---|---|---|---|
document_id |
string | Yes | The governed family (document) UUID |
version_values |
object | Yes | Values for the new revision's version axis (must not collide with an existing one) |
lifecycle_state |
string | No | Birth state id (defaults to the class's initial state) |
copy_forward |
boolean | No | Clone the source version's files into the new revision (default true; independent copies) |
sutram_create_documents
Batch-creates many governed documents of the same Document Class in one call (bootstrap / Master Document Register). Each entry is the first version of a family; the slug sequence advances correctly across entries.
- Idempotent by slug for deterministic-slug classes (
slug_froma unique number): re-running skips documents whose slug already exists. For auto-sequenced classes each entry always creates a new document. - Dry-run: pass
dry_run: trueto preview (per-entry slug +would_create/skipped) without persisting. Recommended before applying. - Atomic per entry — one bad entry comes back as an
errorwithout failing the rest. Returns a summary{ created, would_create, skipped, errors, total, results }.
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Document Class id (shared by all entries) |
documents |
array | Yes | Entries { metadata, version_values?, lifecycle_state?, name? } (non-empty, max 200) |
dry_run |
boolean | No | Preview only — resolve identities without persisting (default false) |
Example: bootstrap a governed class
// 1. Graduate a category and shape its lifecycle
→ sutram_graduate_document_class { "category_id": "tech_doc" }
→ sutram_get_record_category_detail { "category_id": "tech_doc" } // read lifecycle
→ sutram_set_document_class_lifecycle { "category_id": "tech_doc", "lifecycle": { ... } }
// 2. Preview a batch register, then apply
→ sutram_create_documents { "category_id": "tech_doc", "dry_run": true,
"documents": [ { "metadata": { "title": "Spec A" } }, { "metadata": { "title": "Spec B" } } ] }
← { "dry_run": true, "would_create": 2, "skipped": 0, "errors": 0, ... }
→ sutram_create_documents { "category_id": "tech_doc",
"documents": [ { "metadata": { "title": "Spec A" } }, { "metadata": { "title": "Spec B" } } ] }
← { "created": 2, "skipped": 0, "errors": 0, ... }
// 3. List what you can see (need-to-know)
→ sutram_list_document_classes {}
→ sutram_list_governed_documents { "category_uid": "..." }
Document comments
AI assistants can list, create, reply to, resolve, and delete comments on project files. Comments created via MCP appear in real time in the web UI and vice-versa, via PubSub broadcast.
Position-type restriction: via MCP, the assistant can create only
file_levelcomments (on the whole file) ormarkdowncomments (anchored to text in markdown files). Position types that need GUI coordinates (pdf_page,aps_3d,aps_2d,image) can be read but not created via MCP.
Comment tools
| Tool | Description | Permission |
|---|---|---|
sutram_list_comments |
List top-level comments on a content item | Any member |
sutram_get_comment_thread |
Get one comment with its full reply thread | Any member |
sutram_create_comment |
Create a file-level or markdown comment | Any member |
sutram_reply_to_comment |
Reply to a top-level comment | Any member |
sutram_resolve_comment |
Resolve or reopen a comment thread | Any member |
sutram_delete_comment |
Delete a comment and all its replies | Author, Owner, or Admin |
sutram_list_comments
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | Content item UUID |
include_resolved |
boolean | No | Include resolved comments (default: true) |
sutram_get_comment_thread
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | Comment UUID |
sutram_create_comment
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | Content item UUID |
content |
string | Yes | Comment text |
position_type |
string | No | "file_level" (default) or "markdown" |
text_anchor |
object | No | For markdown: {exact_text, prefix, suffix} |
original_text_snippet |
string | No | For markdown: the selected text snippet |
Example — markdown comment anchored to text:
{
"content_item_id": "abc-123",
"content": "Typo: 'specificaiton' → 'specification'",
"position_type": "markdown",
"text_anchor": { "exact_text": "specificaiton", "prefix": "the latest ", "suffix": " document" },
"original_text_snippet": "specificaiton"
}
sutram_reply_to_comment
Replies cannot be nested (no reply-to-reply).
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | Top-level comment UUID |
content |
string | Yes | Reply text |
sutram_resolve_comment
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | Comment UUID |
action |
string | Yes | "resolve" or "reopen" |
sutram_delete_comment
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | Comment UUID |
Team chat
The team chat is a project-wide, human-to-human message feed (distinct from document comments, which are anchored to a file). Assistants can read the conversation, post updates, and reply in single-level threads. Posting and replying are outward-facing: other members see the message live and receive a push notification.
Don't confuse chat with comments: chat is project-wide discussion (
sutram_*_chat_*); comments are anchored to a specific document (sutram_*_comment*).
Chat tools
| Tool | Description |
|---|---|
sutram_list_chat_messages |
List messages (oldest→newest, excludes deleted), paginated & searchable |
sutram_get_chat_thread |
Get one message with its single-level reply thread |
sutram_send_chat_message |
Post a new message (outward-facing) |
sutram_reply_to_chat_message |
Reply to a top-level message (outward-facing) |
sutram_get_chat_unread_count |
Count messages from others the user hasn't seen |
sutram_mark_chat_visited |
Mark the chat as read (resets the unread count) |
sutram_list_chat_messages
| Parameter | Type | Required | Description |
|---|---|---|---|
before_id |
string | No | Return messages older than this message UUID (pagination cursor) |
limit |
integer | No | Max messages (default 20, capped at 100) |
search |
string | No | Filter by text in the content or the author's name/email |
sutram_get_chat_thread
Returns the message and its replies. If the given message is itself a reply, the parent thread is returned.
| Parameter | Type | Required | Description |
|---|---|---|---|
message_id |
string | Yes | UUID of any message in the thread |
sutram_send_chat_message
Provide content and/or attach a project file/link via content_item_id.
| Parameter | Type | Required | Description |
|---|---|---|---|
content |
string | Yes* | Message text (max 5000 chars) |
content_item_id |
string | No | UUID of a file/link in the project to attach |
*content is required unless content_item_id is given.
sutram_reply_to_chat_message
You cannot reply to your own message, to a reply, or to a deleted message.
| Parameter | Type | Required | Description |
|---|---|---|---|
message_id |
string | Yes | UUID of the top-level message being replied to |
content |
string | Yes* | Reply text (max 5000 chars) |
content_item_id |
string | No | UUID of a file/link to attach |
*content is required unless content_item_id is given.
sutram_get_chat_unread_count / sutram_mark_chat_visited
Both take no parameters. The first returns the unread count; the second clears it by recording the visit.
Wiki & knowledge graph
The wiki turns a project into a typed knowledge graph. WikiNodes are abstract referenceable entities (concepts, themes, synthesis pages) that [[slug]] mentions point at — they are not folders or files. Mentions in markdown become graph edges; edges can carry typed relation labels (e.g. revokes, amends, regulates). Full-text search runs over node names, curated synthesis, and the mirrored document's full text.
Typical answer flow: sutram_search_wiki(question) → read the top nodes with sutram_get_wiki_node → follow [[mentions]] / backlinks → synthesize, anchored in the sources.
Wiki tools
| Tool | Description |
|---|---|
sutram_create_wiki_node |
Create a referenceable concept/entity node (fuzzy-dedupes by name) |
sutram_update_wiki_node |
Update a node's name/body/metadata, or set typed outgoing edges |
sutram_get_wiki_node |
Read one node (synthesis + full source_text) by id or slug |
sutram_delete_wiki_node |
Soft-delete a node (destructive — always confirmed) |
sutram_search_wiki |
Full-text search over the wiki's content (the QA entry point) |
sutram_search_wiki_nodes |
Browse nodes by name substring / category |
sutram_sync_wiki_source |
Fill a node's source_text from a linked record's markdown |
sutram_set_wiki_relation_labels |
Set the project's passive→active relation vocabulary |
sutram_get_backlinks |
List sources that mention an item (the "Mentioned in" panel) |
sutram_get_outgoing_mentions |
List a source's [[slug]] links (resolved/pending) |
sutram_create_wiki_node
Before creating, the name is fuzzy-matched against the project's catalog; if a close-enough node exists, that one is returned (status matched) instead of creating a duplicate.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name (e.g. Bioequivalência) |
slug |
string | No | Explicit slug (auto-generated from the name if omitted) |
category |
string | No | Category id for the node type |
content_markdown |
string | No | Markdown body (the curated synthesis). Omit for a stub. |
source_text |
string | No | Full source text of the mirrored document (indexed by FTS, weight C; returned in full by sutram_get_wiki_node) |
metadata |
object | No | Free-form attributes |
created_autonomously |
boolean | No | Mark as created by the LLM (default false) |
sutram_update_wiki_node
The slug is stable — it is not regenerated on rename.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | WikiNode UUID |
name |
string | No | New display name |
category |
string | No | New category id |
content_markdown |
string | No | New markdown body |
source_text |
string | No | New full source text (FTS substrate) |
metadata |
object | No | Replacement metadata map |
mentions |
array | No | Typed outgoing edges. Each {slug, label} becomes a mention with a relation label, overriding the untyped [[ ]] mentions parsed from content_markdown. |
sutram_get_wiki_node
Returns category, metadata, curated synthesis, and — for nodes mirroring a record — the document's full text in source_text. Provide exactly one of id or slug.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | No* | WikiNode UUID |
slug |
string | No* | WikiNode slug |
*Provide exactly one of id or slug.
sutram_search_wiki
Full-text search over the wiki's content — the way to find material from a question when you don't know slugs or ids. Ranks nodes by how well their name, synthesis, and source_text match (Portuguese stemming) and returns a highlighted snippet per hit.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | Yes | Free-text query. Supports quoted phrases, -exclusion, and or (websearch syntax). |
limit |
integer | No | Max results (default 10, max 50) |
sutram_search_wiki_nodes
Browse the entity/concept catalog by name or category (not full-text).
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | No | Name substring filter |
category |
string | No | Category id filter |
limit |
integer | No | Max results (default 50) |
sutram_sync_wiki_source
Populates a mirror node's source_text from the linked record's extracted markdown (default texto_full.md), read server-side from storage. Use after sutram_create_wiki_node when the document body is too large to pass inline. Resolves the node by id or slug; the record comes from record_folder_id or the node's metadata.record_folder_id. Idempotent.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | No* | WikiNode UUID |
slug |
string | No* | WikiNode slug |
record_folder_id |
string | No | Record (folder) UUID whose markdown feeds source_text |
filename |
string | No | Source file name in the record (default texto_full.md) |
*Provide id or slug.
sutram_set_wiki_relation_labels
Sets the project's relation vocabulary: a map of passive → active labels (e.g. {"revogado_por": "revoga", "alterado_por": "altera"}). The graph collapses inverse edges to the active voice; a node page renders backlinks in the passive voice from the target's perspective. Call once per project after setting typed mentions. Merges with any existing map; idempotent.
| Parameter | Type | Required | Description |
|---|---|---|---|
labels |
object | Yes | Map of passive label → active label |
sutram_get_backlinks
Returns the backlinks of an item — the sources whose markdown mentions it via [[slug]] (the "Mentioned in (N)" panel). Identify the target by slug, or by explicit id + kind.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug |
string | No* | Target slug (resolved automatically) |
id |
string | No* | Target UUID (with kind) |
kind |
string | No | wiki_node | content_item | folder (with id) |
*Provide slug, or id + kind.
sutram_get_outgoing_mentions
Returns the outgoing mentions of a source — the [[slug]] it links to, each flagged resolved or pending (broken). Use to audit a page's links.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug |
string | No* | Source slug |
id |
string | No* | Source UUID (with kind) |
kind |
string | No | wiki_node | content_item (with id) |
*Provide slug, or id + kind.
Limitations
The following operations are not yet available via MCP and must be done in the Sutram web UI:
- Sharing: share links cannot be generated via MCP.
- Positioned comments: comments anchored to PDF pages, CAD coordinates, or image positions require the web UI (they can be read via MCP, but not created).
Permissions
MCP access respects the same permissions as the web UI:
| Role | Browse | Upload/Create | Move | Delete | Versioning | Record schema | Records | Comments / Chat |
|---|---|---|---|---|---|---|---|---|
| Owner | Yes | Yes | Yes | Yes | Full (publish, force-release) | Full (CRUD) | CRUD | Full (incl. delete any) |
| Admin | Yes | Yes | Yes | Yes | Checkout/checkin | Read-only | CRUD | Full (incl. delete any) |
| Member | Yes | Yes | Yes | Yes | Enable/disable, checkout/checkin | Read-only | CRUD | Create/reply/resolve; delete own |
| Viewer | No MCP access | — | — | — | — | — | — | — |
Viewers cannot use MCP. If you need MCP access, ask the project owner to upgrade your role.
Security
- Keys are independent: revoking a user key doesn't affect others; revoking a project key disables MCP access for everyone on that project.
- One project key per project: only one active project key exists at a time. Regenerating it invalidates the previous one.
- Keys are never stored in plaintext: project keys are encrypted; user keys are hashed and cannot be recovered after creation.
- OAuth tokens are scoped & short-lived: an access token is bound to one project, with a 1-hour TTL; clients refresh automatically via the refresh token.
- HTTPS only: all MCP connections are encrypted.
Revoking access
- Your user key: Settings → Integrations → Claude → revoke and regenerate.
- Project MCP access (owner only): Project Settings → Integrations → toggle Enable MCP access off / regenerate the project key.
- An OAuth connector: remove it from your client's Connectors panel.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| "Couldn't reach the MCP server" at first connect | OAuth discovery blocked by the allowlist | Confirm app.sutram.io responds: curl -I https://app.sutram.io/mcp/v2. Then revisit Path A, step 4. |
| Consent screen shows but Authorize returns a 500 | Server-side error on consent persistence | Outage. Contact support@sutram.io with the timestamp. |
| Connector connected, but tool calls return 401 | Access token expired (1-hour TTL) | Retry — Claude refreshes via the refresh token. If it persists, click Reconnect. |
| "Authentication failed" (bridge/raw HTTP) | Wrong or revoked key, or you're a viewer | Verify both keys; confirm you're an active member (not a viewer). |
| "Project key not available" | Project key revoked by the owner | Ask the owner to regenerate it in Project Settings → Integrations. |
| "Storage quota exceeded" | Account storage limit reached | Delete unused files or upgrade your plan. |
| Claude replies "I don't have access to any folder on your computer" | Generic prompt read as a filesystem request | Be explicit ("…on Sutram"), or apply the Assistant Preset (Path A, step 5). |
| File reads fail with "network blocked" | files.sutram.io not allowlisted |
Add files.sutram.io (Path A, step 4). |
| Tools don't appear in Claude Code / Cursor | .mcp.json not found or invalid |
Start the client from the folder holding .mcp.json; validate the JSON; ensure npx is on your PATH. |
| Tools don't appear in Claude Desktop | Config not reloaded | Restart Claude Desktop after editing; validate the JSON (no trailing commas). |
| OAuth loops back to the login page | Browser blocking third-party cookies | Try Firefox/Chrome, or relax strict tracking protection in Safari. |
Supported file types
Sutram auto-detects MIME types from file extensions. Common formats:
| Category | Extensions |
|---|---|
| Images | .jpg, .jpeg, .png, .gif, .webp, .svg |
| Documents | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx |
| Text | .txt, .csv, .json, .xml, .md |
| Media | .mp4, .mp3, .wav |
| Archives | .zip |
| CAD | .dwg, .dxf, .rvt, .ifc |
Files with unrecognized extensions are uploaded as application/octet-stream.
Supported link platforms
- Video: YouTube, Vimeo, DailyMotion, Wistia, Loom, TikTok. Platform auto-detected; thumbnails extracted when available.
- Audio: Spotify, SoundCloud, Apple Podcasts, Anchor, and others. Platform auto-detected.
- Web: any valid HTTP/HTTPS URL. Title, description, and favicon auto-fetched.
Examples
Migrate medical exams from a hospital portal
"Download my ultrasound exam from the hospital portal and organize it in Sutram under the requesting doctor's folder."
The assistant will: access the portal (via browser) → download the PDF report and images → sutram_create_folder with a nested path (Doctor / Exam Type / YYYY-MM-DD) → sutram_request_upload + sutram_confirm_upload for each file → clean up local temp files.
Upload a local file
"Upload
report.pdffrom my desktop to the 'Reports' folder in Sutram."
Claude reads the file, finds the folder via sutram_get_folder, gets a presigned URL with sutram_request_upload, PUTs the bytes to S3, and finalizes with sutram_confirm_upload.
Organize and tag for search
"Organize my exams by patient and exam type, then find all of patient João's folders."
Claude uses sutram_create_folder with path + tags, sutram_set_folder_tags to adjust existing folders, and sutram_search_folders with tag_name: "patient", tag_value: "joão" (substring match also finds "João Pedro", "João Silva").
Tag discovery + AND search
"Find all USG exams for patient João inside Dr. Mion's folder."
Claude uses sutram_get_tag_keys (scoped by folder_id) to discover keys, then sutram_search_folders with AND conditions (patient=joão, exam_type=USG) scoped to that folder.
Answer a question from the wiki
"What does the corpus say about bioequivalence, and which acts regulate generic drug registration?"
Claude runs sutram_search_wiki("bioequivalência"), reads the top nodes with sutram_get_wiki_node, follows [[mentions]] and sutram_get_backlinks, and synthesizes an answer anchored in the source documents.
Post a team update
"Tell the team I uploaded the revised floor plan, and attach it."
Claude finds the file via sutram_get_folder, then sutram_send_chat_message with content + content_item_id. Other members get a push notification.
Uploading files via script
When uploading through an AI assistant, the assistant uses the two-step presigned-URL flow: sutram_request_upload → PUT to S3 → sutram_confirm_upload. This avoids base64 overhead and has no practical file-size limit beyond your plan's storage quota.
For automation or batch uploads outside an assistant, call the MCP endpoint directly over HTTP.
How the HTTP MCP endpoint works
Sutram uses the Streamable HTTP transport (JSON-RPC 2.0 over HTTPS):
- Initialize a session —
POST https://app.sutram.io/mcp/v2with methodinitialize - Capture the session id — from the
mcp-session-idresponse header - Send a notification —
notifications/initialized(required by the MCP protocol) - Call tools —
POSTwith methodtools/call, passing the tool name and arguments
Every request must include the Authorization header; after initialization, include the mcp-session-id header too.
Example: Node.js upload script
import { readFileSync, statSync } from "node:fs";
import { basename, extname } from "node:path";
import { lookup } from "mime-types";
const ENDPOINT = "https://app.sutram.io/mcp/v2";
const HEADERS = {
Authorization: "Bearer dualkey:sk_proj_YOUR_PROJECT_KEY:sk_user_YOUR_USER_KEY",
};
let sessionId = null;
let requestId = 0;
async function mcpRequest(method, params = {}) {
const headers = {
"Content-Type": "application/json",
Accept: "application/json, text/event-stream",
...HEADERS,
};
if (sessionId) headers["mcp-session-id"] = sessionId;
const response = await fetch(ENDPOINT, {
method: "POST",
headers,
body: JSON.stringify({ jsonrpc: "2.0", method, params, id: ++requestId }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const sid = response.headers.get("mcp-session-id");
if (sid) sessionId = sid;
// The response may be JSON or an SSE stream depending on processing time.
const contentType = response.headers.get("content-type") || "";
if (contentType.includes("text/event-stream")) {
const text = await response.text();
for (const event of text.split("\n\n").filter(Boolean).reverse()) {
const dataLine = event.split("\n").find((l) => l.startsWith("data: "));
if (dataLine) return JSON.parse(dataLine.slice(6));
}
}
return response.json();
}
async function mcpNotify(method, params = {}) {
const headers = { "Content-Type": "application/json", ...HEADERS };
if (sessionId) headers["mcp-session-id"] = sessionId;
await fetch(ENDPOINT, {
method: "POST",
headers,
body: JSON.stringify({ jsonrpc: "2.0", method, params }),
});
}
async function main() {
// 1. Initialize the MCP session
await mcpRequest("initialize", {
protocolVersion: "2025-06-18",
capabilities: {},
clientInfo: { name: "my-upload-script", version: "1.0.0" },
});
await mcpNotify("notifications/initialized");
// 2. Request a presigned upload URL
const filePath = process.argv[2];
const folderId = process.argv[3] || null;
const filename = basename(filePath);
const fileSize = statSync(filePath).size;
const contentType = lookup(extname(filePath)) || "application/octet-stream";
const reqResult = await mcpRequest("tools/call", {
name: "sutram_request_upload",
arguments: { filename, file_size: fileSize, content_type: contentType, folder_id: folderId },
});
const { upload_url, s3_key, file_id } = JSON.parse(reqResult.result.content[0].text);
// 3. Upload the file directly to S3
const putResponse = await fetch(upload_url, {
method: "PUT",
headers: { "Content-Type": contentType },
body: readFileSync(filePath),
});
if (!putResponse.ok) throw new Error(`S3 upload failed: ${putResponse.status}`);
// 4. Confirm the upload
const confirmResult = await mcpRequest("tools/call", {
name: "sutram_confirm_upload",
arguments: { file_id, s3_key, filename, content_type: contentType, file_size: fileSize, folder_id: folderId },
});
console.log(JSON.stringify(confirmResult, null, 2));
}
main();
Save as upload.mjs and run:
node upload.mjs /path/to/report.pdf "target-folder-uuid"
Key points:
- No file-size limit beyond your plan's storage quota.
- Files go straight to S3 via the presigned URL — no base64, no bytes through the web server.
- The script performs the full MCP handshake (initialize → notify → tool call).
- Responses arrive as JSON or SSE depending on processing time — the script handles both.
- Credentials can be read from your
.mcp.jsoninstead of being hardcoded.
REST API
Besides the MCP tools, Sutram provides a read-only REST API for consuming project content. It uses the same dual-key authentication and is ideal for external apps, dashboards, and scripts.
Base URL: https://app.sutram.io/api/v1
| Endpoint | Description |
|---|---|
GET /api/v1/project |
Project information |
GET /api/v1/folders |
List root folders |
GET /api/v1/folders/:id |
Folder detail with subfolders and items |
GET /api/v1/content |
List content items with filtering, tag search, and pagination |
GET /api/v1/content/:id |
Content item detail with presigned download URLs |
Resources
- Sutram Assistant Preset — system prompt + starter prompts to make Claude Sutram-aware by default
- Privacy Policy · Terms
- Support:
support@sutram.io