Sutram MCP Server User Guide
Version: 0.111.0 Date: 2026-03-14 Status: In development
Overview
Sutram Remote Access lets AI assistants and automation tools connect to your projects through the Model Context Protocol (MCP). Once configured, your AI assistant can browse folders, upload files, add web/video/audio links, manage content, and interact with document comments in your Sutram projects — all with proper authentication and permissions.
How it works
AI Assistant (Claude, Cursor, etc.)
|
| MCP Protocol (HTTPS)
v
Sutram MCP Endpoint
https://app.sutram.io/mcp
|
| Dual Key Authentication
v
Your Project (folders, files, content)
Two API keys are required for every connection:
| Key | Purpose | Who creates it | Where to find it |
|---|---|---|---|
Project Key (sk_proj_...) |
Identifies the project | Project owner | Project page or project settings |
User Key (sk_user_...) |
Identifies you | Each user creates their own | User Settings > API Key |
Both keys must be valid, and you must be an active member of the project (not a viewer) to connect.
Getting Started
Step 1: Create your personal API Key
- Go to Settings (gear icon in the top-right menu)
- Click the API Key card
- Click Create Key
- Copy the key immediately — it will only be shown once
Your personal key looks like: sk_user_zQD0BjH56nQhOgX3uxni...
Important: Store your key securely. If you lose it, you can revoke the old one and create a new key from the same settings page.
Step 2: Get the project key
The project owner must first enable remote access for the project:
- Go to Settings > Projects tab
- Open the dropdown menu (three dots) next to the project
- Click Enable Remote Access
- Copy the project key that appears
Once remote access is enabled, any project member (owner, admin, or member) can copy the project key:
- Open the project
- Click the green signal icon next to the role badge in the header
- A modal will show the project key — click the copy button
The project key looks like: sk_proj_ej8NWMisd2rJgMwAJ22T...
Configuring Your AI Client
Each Sutram project should have its own local MCP configuration. Since the project key is tied to a specific project, the recommended approach is to create a dedicated workspace folder for each integration and place the .mcp.json file there.
Example: If you use Sutram to store medical exams, create a local folder for that workflow:
~/projects/medical-exams/
└── .mcp.json ← Sutram keys for your health project
This keeps credentials scoped to the right context and avoids mixing unrelated projects.
Claude Code (CLI) — Recommended
Create a .mcp.json file in your workspace folder:
{
"mcpServers": {
"sutram": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://app.sutram.io/mcp",
"--header",
"x-project-key: sk_proj_YOUR_PROJECT_KEY",
"--header",
"x-user-key: sk_user_YOUR_USER_KEY"
]
}
}
}
Note: Claude Code does not yet support
type: "url"natively. The configuration above usesmcp-remoteas a bridge to connect via stdio. This requires Node.js (npx) to be installed. Themcp-remotepackage is downloaded automatically on first use.
Then start Claude Code from that folder. Sutram tools will be available only in that context.
Cursor
Create a .cursor/mcp.json file in your workspace folder:
{
"mcpServers": {
"sutram": {
"type": "url",
"url": "https://app.sutram.io/mcp",
"headers": {
"x-project-key": "sk_proj_YOUR_PROJECT_KEY",
"x-user-key": "sk_user_YOUR_USER_KEY"
}
}
}
}
Claude Desktop
Claude Desktop uses a global configuration file. Add an entry for each Sutram project, using a descriptive name to distinguish them:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
If your version of Claude Desktop supports type: "url":
{
"mcpServers": {
"sutram-medical-exams": {
"type": "url",
"url": "https://app.sutram.io/mcp",
"headers": {
"x-project-key": "sk_proj_HEALTH_PROJECT_KEY",
"x-user-key": "sk_user_YOUR_USER_KEY"
}
},
"sutram-construction": {
"type": "url",
"url": "https://app.sutram.io/mcp",
"headers": {
"x-project-key": "sk_proj_WORK_PROJECT_KEY",
"x-user-key": "sk_user_YOUR_USER_KEY"
}
}
}
}
If type: "url" is not recognized, use the mcp-remote bridge instead:
{
"mcpServers": {
"sutram-medical-exams": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://app.sutram.io/mcp",
"--header",
"x-project-key: sk_proj_HEALTH_PROJECT_KEY",
"--header",
"x-user-key: sk_user_YOUR_USER_KEY"
]
}
}
}
Restart Claude Desktop after saving the file.
Tip: The user key (
sk_user_...) is the same across all entries — it identifies you. The project key (sk_proj_...) changes per project.
Other MCP Clients
Sutram uses the MCP Streamable HTTP transport. Any MCP-compatible client that supports HTTP transport can connect using:
- Endpoint:
https://app.sutram.io/mcp - Method: POST (JSON-RPC 2.0)
- Authentication: Custom headers
x-project-keyandx-user-key - Protocol version: 2024-11-05
For clients that only support stdio transport, use mcp-remote as a bridge:
npx -y mcp-remote https://app.sutram.io/mcp \
--header "x-project-key: sk_proj_YOUR_PROJECT_KEY" \
--header "x-user-key: sk_user_YOUR_USER_KEY"
Available Tools
Once connected, your AI assistant has access to these tools. You can also retrieve this list programmatically by sending the standard MCP tools/list request to the server endpoint.
Quick Reference (A–Z)
| # | Tool | Category | Description |
|---|---|---|---|
| 1 | sutram_add_enum_values |
Schema | Adds new values to an existing enum metadata definition |
| 2 | sutram_cancel_checkout |
Versioning | Cancels checkout without uploading changes |
| 3 | sutram_checkin_file |
Versioning | Releases a file from checkout (check-in) |
| 4 | sutram_checkout_file |
Versioning | Checks out a file for exclusive editing |
| 5 | sutram_confirm_upload |
Content | Step 2 of upload: confirms file was uploaded to S3 |
| 6 | sutram_bulk_create_file_links |
File Links | Bulk-creates file links from a source folder to a target folder |
| 7 | sutram_cancel_checkout |
Versioning | Cancels checkout without uploading changes |
| 8 | sutram_checkin_file |
Versioning | Releases a file from checkout (check-in) |
| 9 | sutram_checkout_file |
Versioning | Checks out a file for exclusive editing |
| 10 | sutram_confirm_upload |
Content | Step 2 of upload: confirms file was uploaded to S3 |
| 11 | sutram_create_audio_link |
Content | Creates an audio link (Spotify, SoundCloud, etc.) |
| 12 | sutram_create_comment |
Comments | Creates a file-level or markdown comment on a content item |
| 13 | sutram_create_file_link |
File Links | Creates a file link (symbolic reference) to an existing file |
| 14 | sutram_create_folder |
Folders | Creates a new folder or nested path |
| 15 | sutram_create_new_version |
Versioning | Creates a new version from a published file |
| 16 | sutram_create_record |
Records | Creates a new record in a category |
| 17 | sutram_create_video_link |
Content | Creates a video link (YouTube, Vimeo, etc.) |
| 18 | sutram_create_web_link |
Content | Creates a web link with auto-fetched title |
| 19 | sutram_delete |
Content | Deletes a content item or folder |
| 20 | sutram_delete_comment |
Comments | Deletes a comment and all its replies |
| 21 | sutram_delete_metadata |
Schema | Deletes a metadata definition |
| 22 | sutram_delete_record |
Records | Deletes a record |
| 23 | sutram_delete_record_category |
Schema | Deletes a record category |
| 24 | sutram_disable_versioning |
Versioning | Converts file back to reference (read-only) |
| 25 | sutram_enable_versioning |
Versioning | Converts file from reference to editable |
| 26 | sutram_force_release_lock |
Versioning | Force releases another user's checkout (owner only) |
| 27 | sutram_get_comment_thread |
Comments | Gets a comment with its full thread of replies |
| 28 | sutram_get_folder |
Folders | Returns contents of a folder |
| 29 | sutram_get_item |
Content | Gets full details and download URL of a content item |
| 30 | sutram_get_item_tag_keys |
Tags | Returns all distinct tag keys used on content items |
| 31 | sutram_get_metadata_definitions |
Schema | Returns all metadata field definitions |
| 32 | sutram_get_record_categories |
Schema | Returns all record categories |
| 33 | sutram_get_record_category_detail |
Schema | Returns a category with fully resolved metadata |
| 34 | sutram_get_tag_keys |
Tags | Returns all distinct tag keys used on folders |
| 35 | sutram_list_comments |
Comments | Lists all top-level comments on a content item |
| 36 | sutram_list_file_links_for_source |
File Links | Lists all file links pointing to a source file |
| 37 | sutram_list_file_links_in_folder |
File Links | Lists file links in a folder with source file details |
| 38 | sutram_list_versions |
Versioning | Lists all versions of a file |
| 39 | sutram_move_contents |
Folders | Moves all contents from one folder to another |
| 40 | sutram_move_item |
Content | Moves a single content item to another folder |
| 41 | sutram_project_info |
Project | Returns project name, description, and settings |
| 42 | sutram_publish_version |
Versioning | Publishes a draft file, creating a version snapshot |
| 43 | sutram_remove_enum_values |
Schema | Removes values from an enum metadata definition |
| 44 | sutram_rename |
Content | Renames a content item or folder |
| 45 | sutram_reply_to_comment |
Comments | Replies to an existing top-level comment |
| 46 | sutram_request_upload |
Content | Step 1 of upload: returns a presigned S3 PUT URL |
| 47 | sutram_resolve_comment |
Comments | Resolves or reopens a comment thread |
| 48 | sutram_search_folders |
Tags | Searches folders by tag (single or AND conditions) |
| 49 | sutram_search_items |
Tags | Searches content items by tag |
| 50 | sutram_set_folder_tags |
Tags | Sets key-value tags on a folder |
| 51 | sutram_set_item_tags |
Tags | Sets key-value tags on a content item |
| 52 | sutram_undo_checkin |
Versioning | Undoes the last check-in, restoring previous version |
| 53 | sutram_update_record |
Records | Updates a record's metadata |
| 54 | sutram_upload_modified_file |
Versioning | Replaces file content during checkout |
| 55 | sutram_upsert_metadata |
Schema | Creates or updates a metadata field definition |
| 56 | sutram_upsert_record_category |
Schema | Creates or updates a record category |
Categories: Project (1) · Folders (3) · Content (8) · File Links (4) · Tags (6) · Versioning (12) · Comments (6) · Schema (8) · Records (4)
The sections below describe each tool in detail, organized by functionality.
sutram_project_info
Returns information about the current project.
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
Browses the contents of a folder (subfolders, files, and links). Omit folder_id to list root contents.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID. Omit for 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,
"filename": "site-plan.pdf"
},
{
"type": "web_link",
"id": "a1b2c3d4-...",
"name": "Project Wiki",
"url": "https://wiki.example.com/project",
"favicon_url": "https://wiki.example.com/favicon.ico"
},
{
"type": "video_link",
"id": "e5f6a7b8-...",
"name": "Site walkthrough",
"url": "https://www.youtube.com/watch?v=abc123",
"platform": "youtube",
"thumbnail_url": "https://img.youtube.com/vi/abc123/hqdefault.jpg"
},
{
"type": "audio_link",
"id": "c9d0e1f2-...",
"name": "Meeting recording",
"url": "https://open.spotify.com/episode/xyz",
"platform": "spotify",
"artist_or_author": "Team Alpha"
}
]
}
sutram_create_folder
Creates a new folder. Supports creating nested hierarchies in a single call.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes* | Folder name (for creating a 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 root level. |
tags |
object | No | Free-form key-value tags (e.g., {"patient": "John", "exam_type": "USG"}). When using path, tags are applied only to the leaf (deepest) folder. |
*Use either name (single folder) or path (nested hierarchy), not both.
Nested creation: When using path, intermediate folders are created automatically. If any folder in the path already exists, it is reused — the operation is idempotent.
Example — single folder:
{ "name": "Reports", "parent_folder_id": "f1a2b3c4-..." }
Example — nested hierarchy with tags:
{
"path": "Dr. Decio Mion Junior/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 one (2024-12-12) with the specified tags.
sutram_request_upload
Step 1 of the direct upload flow. Validates the file and returns a presigned S3 PUT URL. The file is uploaded directly to S3 by the client — no data passes through the Sutram web servers.
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 extension if omitted. |
folder_id |
string | No | Target folder UUID. Omit for root. |
Example response:
{
"upload_url": "https://eikon-storage.s3.amazonaws.com/projects/.../files/abc123.pdf?X-Amz-...",
"s3_key": "projects/a1b2c3d4-.../files/abc123.pdf",
"file_id": "abc123-...",
"folder_id": null,
"expires_in": 900
}
sutram_confirm_upload
Step 2 of the direct upload flow. Call this after the file has been uploaded 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 of the file |
file_size |
integer | Yes | File size in bytes |
folder_id |
string | No | Target folder UUID (must match request) |
Example response:
{
"file": {
"id": "abc123-...",
"name": "report.pdf",
"size": 2450000,
"content_type": "application/pdf",
"created_at": "2026-02-27T10:00:00Z"
}
}
Complete upload flow example:
# 1. Request upload (via MCP tool call)
# → Returns upload_url, s3_key, file_id
# 2. Upload file directly to S3
curl -X PUT \
-H "Content-Type: application/pdf" \
--data-binary @report.pdf \
"https://eikon-storage.s3.amazonaws.com/projects/.../files/abc123.pdf?X-Amz-..."
# 3. Confirm upload (via MCP tool call)
# → File record created, storage updated, web UI updates in real-time
sutram_create_web_link
Creates a web link in the project. Sutram automatically fetches the page title and favicon from the URL.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | URL of the web page (must be http or https) |
name |
string | No | Display name. Auto-fetched from page title if omitted. |
folder_id |
string | No | Target folder UUID. Omit for root. |
Example response:
{
"web_link": {
"id": "a1b2c3d4-...",
"name": "Sutram Documentation",
"url": "https://docs.sutram.io",
"favicon_url": "https://docs.sutram.io/favicon.ico",
"fetched_title": "Sutram Documentation",
"created_at": "2026-02-09T14:30:00Z"
}
}
sutram_create_video_link
Creates a video link in the project. Supports YouTube, Vimeo, DailyMotion, Wistia, Loom, and TikTok. Automatically detects the platform and extracts the video ID from the URL.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | URL of the video (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 root. |
Example response:
{
"video_link": {
"id": "e5f6a7b8-...",
"name": "Project overview",
"url": "https://www.youtube.com/watch?v=abc123",
"platform": "youtube",
"video_id": "abc123",
"thumbnail_url": "https://img.youtube.com/vi/abc123/hqdefault.jpg",
"created_at": "2026-02-09T14:30:00Z"
}
}
sutram_create_audio_link
Creates an audio link in the project. Supports Spotify, SoundCloud, Apple Podcasts, and more. Automatically detects the platform and extracts the audio ID from the URL.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
url |
string | Yes | URL of the audio content (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 root. |
Example response:
{
"audio_link": {
"id": "c9d0e1f2-...",
"name": "Weekly standup recap",
"url": "https://open.spotify.com/episode/xyz789",
"platform": "spotify",
"artist_or_author": "Team Alpha",
"thumbnail_url": "https://i.scdn.co/image/abc",
"created_at": "2026-02-09T14:30:00Z"
}
}
sutram_create_file_link
Creates a file link (symbolic reference) to an existing file in the project. The link appears as a read-only reference without duplicating storage or versioning. Source must be a file (not a link or another file link). If the source file is deleted, all its file links are automatically removed.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_content_item_id |
string | Yes | UUID of the source file content item to link to |
name |
string | No | Display name (defaults to source file name) |
folder_id |
string | No | Target folder UUID (omit for root) |
description |
string | No | Description of the file link |
Example request:
{
"source_content_item_id": "d5e6f7a8-...",
"folder_id": "b2c3d4e5-...",
"name": "Lab results (link)"
}
Example response:
{
"file_link": {
"id": "f1a2b3c4-...",
"name": "Lab results (link)",
"source_content_item_id": "d5e6f7a8-...",
"folder_id": "b2c3d4e5-...",
"created_at": "2026-03-14T10:00:00Z"
}
}
sutram_bulk_create_file_links
Bulk-creates file links for all files (or a filtered subset) in a source folder, placing them in a target folder. Automatically skips files that already have a link in the target folder (deduplication). Ideal for workflows like linking multiple exam files to a centralized reports folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_folder_id |
string | Yes | UUID of the source folder containing the files to link |
target_folder_id |
string | Yes | UUID of the target folder where file links will be created |
name_pattern |
string | No | Substring filter (case-insensitive) on source file names. Only matching files are linked. |
recursive |
boolean | No | Include files from subfolders of the source folder (default: false) |
Example request:
{
"source_folder_id": "a1b2c3d4-...",
"target_folder_id": "e5f6a7b8-...",
"name_pattern": "laudo",
"recursive": true
}
Example response:
{
"created": 5,
"skipped": 2,
"file_links": [
{
"id": "f1a2b3c4-...",
"name": "laudo-hemograma.pdf",
"source_content_item_id": "d5e6f7a8-...",
"folder_id": "e5f6a7b8-..."
},
{
"id": "f2b3c4d5-...",
"name": "laudo-raio-x.pdf",
"source_content_item_id": "c4d5e6f7-...",
"folder_id": "e5f6a7b8-..."
}
]
}
Tip: Running the same command again will skip all previously linked files (
"created": 0, "skipped": 7), making it safe to re-run.
sutram_list_file_links_for_source
Lists all file links that point to a given source file. Answers the question: "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 content item |
Example request:
{
"source_content_item_id": "d5e6f7a8-..."
}
Example response:
{
"source": {
"id": "d5e6f7a8-...",
"name": "hemograma-completo.pdf",
"type": "file"
},
"file_links": [
{
"id": "f1a2b3c4-...",
"name": "hemograma-completo.pdf",
"folder_id": "b2c3d4e5-...",
"folder_path": "Pacientes/João Silva/Laudos",
"created_at": "2026-03-14T10:00:00Z"
},
{
"id": "f2b3c4d5-...",
"name": "hemograma-completo.pdf",
"folder_id": "c3d4e5f6-...",
"folder_path": "Relatórios/Março 2026",
"created_at": "2026-03-14T10:05:00Z"
}
],
"count": 2
}
sutram_list_file_links_in_folder
Lists all file links in a folder, enriched with source file details (name, content type, file size, folder path). Unlike sutram_get_folder, this provides full information about the source file each link points to.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID (omit for root) |
Example request:
{
"folder_id": "e5f6a7b8-..."
}
Example response:
{
"folder_id": "e5f6a7b8-...",
"file_links": [
{
"id": "f1a2b3c4-...",
"name": "hemograma-completo.pdf",
"created_at": "2026-03-14T10:00:00Z",
"source": {
"id": "d5e6f7a8-...",
"name": "hemograma-completo.pdf",
"content_type": "application/pdf",
"file_size": 245760,
"folder_path": "Exames/Laboratório"
}
},
{
"id": "f2b3c4d5-...",
"name": "raio-x-torax.dcm",
"created_at": "2026-03-14T10:05:00Z",
"source": {
"id": "c4d5e6f7-...",
"name": "raio-x-torax.dcm",
"content_type": "application/dicom",
"file_size": 5242880,
"folder_path": "Exames/Imagem"
}
}
],
"count": 2
}
sutram_get_item
Gets full details of a content item by ID. For files, returns metadata and 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",
"description": null,
"tags": {"category": "planta", "year": "2024"},
"folder_id": "f1a2b3c4-...",
"created_at": "2026-01-20T10:00:00Z",
"filename": "site-plan.pdf",
"file_size": 2450000,
"content_type": "application/pdf",
"version": 1,
"download_url": "https://storage.example.com/projects/.../site-plan.pdf?X-Amz-..."
}
Example response (web link):
{
"id": "a1b2c3d4-...",
"type": "web_link",
"name": "Project Wiki",
"description": null,
"tags": {},
"folder_id": null,
"created_at": "2026-02-01T08:00:00Z",
"url": "https://wiki.example.com/project",
"fetched_title": "Project Wiki - Home",
"fetched_description": "Documentation for the project",
"favicon_url": "https://wiki.example.com/favicon.ico"
}
Example response (video link):
{
"id": "e5f6a7b8-...",
"type": "video_link",
"name": "Site walkthrough",
"description": null,
"tags": {"topic": "neurologia"},
"folder_id": "f1a2b3c4-...",
"created_at": "2026-02-05T16:00:00Z",
"url": "https://www.youtube.com/watch?v=abc123",
"platform": "youtube",
"video_id": "abc123",
"thumbnail_url": "https://img.youtube.com/vi/abc123/hqdefault.jpg",
"duration_seconds": null,
"fetched_title": "Construction Site Alpha - Full Tour"
}
sutram_delete
Deletes a content item (file, web link, video link, audio link) or folder from the project.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
item_id |
string | Yes | Content item or folder UUID |
item_type |
string | Yes | "content_item" or "folder". Use "content_item" for any content type (files, web links, video links, audio links). |
sutram_rename
Renames a content item (file, web link, video link, audio link) or folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
item_id |
string | Yes | Content item or folder UUID |
item_type |
string | Yes | "content_item" or "folder". Use "content_item" for any content type (files, web links, video links, audio links). |
new_name |
string | Yes | New name (for files, include the extension) |
sutram_move_contents
Moves all contents (subfolders and files) from a source folder to a target folder. The source folder is emptied but not deleted. Name conflicts are handled automatically.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
source_folder_id |
string | Yes | UUID of the source folder to empty |
target_folder_id |
string | Yes | UUID of the target folder to receive contents |
Name conflict handling: If a subfolder or file with the same name already exists in the target folder, Sutram automatically renames the moved item by adding a numeric suffix: Exams becomes Exams (1), report.pdf becomes report (1).pdf, and so on.
Validation rules:
- Source and target must be different folders
- Target cannot be a subfolder of 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"]
},
"source_folder_id": "abc123-...",
"target_folder_id": "def456-..."
}
sutram_move_item
Moves a single content item (file or link) to another folder. Name conflicts are handled automatically.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | UUID of the content item to move |
target_folder_id |
string/null | No | UUID of the target folder (null for root) |
Name conflict handling: If a file with the same name already exists in the target folder, Sutram automatically renames the moved file by adding a numeric suffix: report.pdf becomes report (1).pdf, and so on.
Example response (no conflict):
{
"moved": true,
"renamed": false,
"new_filename": null,
"content_item": {
"id": "abc123-...",
"name": "report",
"folder_id": "def456-..."
}
}
Example response (with rename):
{
"moved": true,
"renamed": true,
"new_filename": "report (1).pdf",
"content_item": {
"id": "abc123-...",
"name": "report (1)",
"folder_id": "def456-..."
}
}
sutram_set_folder_tags
Sets free-form 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 all tags. |
Limits: Maximum 50 tags per folder. Key max 100 characters, value max 500 characters.
Semantics: This is a PUT operation — it replaces all existing tags. To add a tag without removing others, first read the current tags (via sutram_get_folder), merge your changes, then call sutram_set_folder_tags with the full set.
Example — set tags:
{
"folder_id": "f1a2b3c4-...",
"tags": {"patient": "João Silva", "exam_type": "USG", "year": "2024"}
}
Example — clear all tags:
{
"folder_id": "f1a2b3c4-...",
"tags": {}
}
Example response:
{
"id": "f1a2b3c4-...",
"name": "2024-12-12",
"tags": {"patient": "João Silva", "exam_type": "USG", "year": "2024"}
}
sutram_search_folders
Searches folders by tag. Supports single or multiple AND conditions. All matching is case-insensitive for both keys and values. Values support substring matching (e.g., "orto" matches "Ortopedia"). Use folder_id to restrict the search to descendants of a specific folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tag_name |
string | No* | Tag key to search for (single condition mode). Case-insensitive. |
tag_value |
string | No | Value to match (single condition mode). Substring match, case-insensitive. |
conditions |
array | No* | Multiple AND conditions. Each object has key (required) and value (optional). |
folder_id |
string | No | Folder UUID to scope search. Only searches descendants of this folder. |
*Use either tag_name (single condition) or conditions (multiple AND conditions).
Search behavior:
- Key matching: Case-insensitive exact match (
"Patient"matches"patient") - Value matching: Case-insensitive substring match (
"orto"matches"Ortopedia","joão"matches"João Silva") - No value: When value is omitted, matches any folder that has the key regardless of value
- Multiple conditions: All conditions must match (AND logic)
Example — find all folders tagged with "patient":
{ "tag_name": "patient" }
Example — find folders for a specific patient (substring match):
{ "tag_name": "patient", "tag_value": "joão" }
This matches folders where the "patient" tag contains "joão" (e.g., "João Silva", "João Pedro").
Example — AND search with multiple conditions:
{
"conditions": [
{ "key": "patient", "value": "joão" },
{ "key": "exam_type", "value": "USG" }
]
}
This returns only folders that match both conditions.
Example — search only within a specific folder hierarchy:
{ "tag_name": "exam_type", "folder_id": "a1b2c3d4-..." }
Example response:
{
"folders": [
{
"id": "f1a2b3c4-...",
"name": "2024-12-12",
"path": "/Dr. Decio Mion Junior/USG ABDOME TOTAL/2024-12-12",
"tags": {"patient": "João Silva", "exam_type": "USG", "year": "2024"}
}
],
"count": 1
}
sutram_get_tag_keys
Returns all distinct tag keys used across folders in the project. Useful for discovering which tags are available before performing a search. Use folder_id to restrict to descendants of a specific folder.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID to scope. Only returns keys from descendants of this folder. |
Example — get all tag keys in the project:
{}
Example — get tag keys within a folder hierarchy:
{ "folder_id": "a1b2c3d4-..." }
Example response:
{
"keys": ["exam_type", "patient", "specialty", "year"],
"count": 4
}
sutram_set_item_tags
Sets free-form key-value tags on a content item. Replaces all existing tags. Send {} to clear all tags.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | Content item UUID |
tags |
object | Yes | Key-value tags to set. Send {} to clear all tags. |
Limits: Maximum 50 tags per item. Key max 100 characters, value max 500 characters.
Semantics: This is a PUT operation — it replaces all existing tags. To add a tag without removing others, first read the current tags (via sutram_get_item), merge your changes, then call sutram_set_item_tags with the full set.
Example — set tags:
{
"content_item_id": "d5e6f7a8-...",
"tags": {"category": "report", "year": "2024", "topic": "neurologia"}
}
Example — clear all tags:
{
"content_item_id": "d5e6f7a8-...",
"tags": {}
}
Example response:
{
"id": "d5e6f7a8-...",
"name": "site-plan",
"tags": {"category": "report", "year": "2024", "topic": "neurologia"}
}
sutram_search_items
Searches content items by tag. Supports single or multiple AND conditions. All matching is case-insensitive for both keys and values. Values support substring matching (e.g., "neuro" matches "Neurologia"). Use folder_id to restrict the search to a specific folder, and type to filter by content type.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
tag_name |
string | No* | Tag key to search for (single condition mode). Case-insensitive. |
tag_value |
string | No | Value to match (single condition mode). Substring match, case-insensitive. |
conditions |
array | No* | Multiple AND conditions. Each object has key (required) and value (optional). |
folder_id |
string | No | Folder UUID to scope search. |
type |
string | No | Content type filter: "file", "file_link", "web_link", "video_link", "audio_link" |
*Use either tag_name (single condition) or conditions (multiple AND conditions).
Example — find all items tagged with "topic":
{ "tag_name": "topic" }
Example — find items for a specific topic (substring match):
{ "tag_name": "topic", "tag_value": "neuro" }
Example — AND search with multiple conditions:
{
"conditions": [
{ "key": "topic", "value": "neuro" },
{ "key": "year", "value": "2024" }
]
}
Example — search only video links in a specific folder:
{ "tag_name": "topic", "folder_id": "f1a2b3c4-...", "type": "video_link" }
Example response:
{
"items": [
{
"id": "d5e6f7a8-...",
"type": "file",
"name": "site-plan",
"tags": {"topic": "neurologia", "year": "2024"},
"folder_id": "f1a2b3c4-..."
}
],
"count": 1
}
sutram_get_item_tag_keys
Returns all distinct tag keys used across content items in the project. Useful for discovering which tags are available before performing a search. Use folder_id to restrict to a specific folder, and type to filter by content type.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
folder_id |
string | No | Folder UUID to scope. |
type |
string | No | Content type filter: "file", "file_link", "web_link", "video_link", "audio_link" |
Example — get all content tag keys in the project:
{}
Example — get tag keys for video links only:
{ "type": "video_link" }
Example response:
{
"keys": ["category", "format", "topic", "year"],
"count": 4
}
File Versioning
Sutram supports a full versioning workflow for files via MCP. This allows AI assistants to enable version control, check out files for exclusive editing, upload modifications, and publish versions.
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. Create new version → sutram_create_new_version (starts new cycle at step 2)
Versioning Tools
| Tool | Description | Permission |
|---|---|---|
sutram_enable_versioning |
Convert file from reference to editable (start versioning) | Owner, Member |
sutram_disable_versioning |
Convert file back to reference (stop versioning) | Owner, Member |
sutram_checkout_file |
Check out file for exclusive editing | Owner, Admin, Member |
sutram_checkin_file |
Release checkout lock | Checkout user |
sutram_cancel_checkout |
Cancel checkout without changes | Checkout user |
sutram_force_release_lock |
Force release another user's checkout | Owner only |
sutram_publish_version |
Publish a draft file, creating a version snapshot | Owner only |
sutram_create_new_version |
Start new version from published file | Owner only |
sutram_undo_checkin |
Undo last check-in, restore previous version | Last checkin user |
sutram_list_versions |
List all published versions with download URLs | Any member |
sutram_upload_modified_file |
Replace file content during checkout | Checkout user |
Parameters
All versioning tools require content_item_id (UUID of the content item).
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 |
Example: Full Versioning Flow
// 1. Enable versioning on a file
→ sutram_enable_versioning { "content_item_id": "abc-123" }
← { "file": { "file_type": "editable", "lifecycle_status": "draft", "version": 1 } }
// 2. Check out the file
→ sutram_checkout_file { "content_item_id": "abc-123" }
← { "file": { "checked_out_by": "Alice", ... } }
// 3. Get presigned URL for the modified file
→ sutram_request_upload { "filename": "report_v2.pdf", "file_size": 5000 }
← { "upload_url": "https://s3...", "s3_key": "projects/.../file.pdf" }
// 4. PUT modified file to S3 (HTTP PUT to upload_url)
// 5. Upload 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"
}
// 6. Check in the file
→ sutram_checkin_file { "content_item_id": "abc-123" }
// 7. Publish the version (owner only)
→ sutram_publish_version { "content_item_id": "abc-123" }
← { "file": { "lifecycle_status": "published", "version": 1 } }
// 8. List versions
→ sutram_list_versions { "content_item_id": "abc-123" }
← { "versions": [{ "version_number": 1, "download_url": "...", ... }], "count": 1 }
Record Categories & Records
Sutram supports structured records with metadata schemas and auto-generated slugs. This allows AI assistants to define metadata fields, create record categories, and manage records programmatically.
Plan requirement: Record and schema management tools require a plan with the Records feature enabled (Plus or higher). Read-only tools (
sutram_get_metadata_definitions,sutram_get_record_categories,sutram_get_record_category_detail) are available on all plans.
Concepts
- Metadata definitions — Field schemas that define the types, labels, and allowed values for metadata fields (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 number 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
Records have an auto-generated slug (used as the record name). The slug is built in two steps:
- Number base — Determined by the
computed_fromentries on a computed metadata tag. This defines which field values form the uniqueness key for sequential numbering. - Slug composition — Determined by the
slug_fromentries on the category. This defines which field values (including the computed tag) compose the final slug.
Without slug_from (backward compatible): slug = number_base + separator + sequence_number (e.g., 0100-200-001).
With slug_from: slug is composed from the referenced fields in order (e.g., MD-3010.95-0000-000-SWA-001).
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 definition (merge, deduplicate, sort) | Owner only |
sutram_remove_enum_values |
Remove values from an enum definition 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 with category, metadata, and auto-generated slug | Owner, Admin, Member |
sutram_update_record |
Update record metadata (recomputes slug if needed) | 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 for the project. Each definition has a key and properties: label, type (text, enum, boolean, date, computed), and optional values, depends_on, values_map.
Parameters: None
sutram_get_record_categories
Returns all record categories for the project. Each category defines which metadata fields a record uses, slug configuration, and ordering.
Parameters: None
sutram_get_record_category_detail
Returns a record category with fully resolved metadata (labels, types, allowed values from the definitions). Use this to understand what fields are needed before creating a record.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Record category ID |
sutram_upsert_metadata
Creates or updates a metadata definition (field schema). For enum types, provide the full values array. For large enums, prefer sutram_add_enum_values for incremental additions.
Parameters:
| 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 — create a simple enum:
{
"key": "language",
"definition": {
"label": "Language",
"type": "enum",
"values": [
{ "label": "Portuguese", "code": "PT" },
{ "label": "English", "code": "EN" }
]
}
}
sutram_delete_metadata
Deletes a metadata definition. Fails if the definition is currently in use by any record category.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Key of the definition to delete |
sutram_add_enum_values
Adds values to an existing enum metadata definition. New values are merged with existing ones — duplicates (by code) are skipped. Values are sorted by code after merging. Use this instead of sutram_upsert_metadata when working with large enums to avoid sending the entire values array.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Key of the enum definition |
values |
array | Yes | Array of {label, code} objects to add |
Example — add values to an existing enum with 800+ items:
{
"key": "area_atividade",
"values": [
{ "label": "Automação Industrial", "code": "0999" },
{ "label": "Telecomunicações", "code": "1050" }
]
}
Example response:
{
"key": "area_atividade",
"added": 2,
"skipped_duplicates": 0,
"total_values": 886
}
sutram_remove_enum_values
Removes values from an existing enum metadata definition by their codes.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Key of the enum definition |
codes |
array | Yes | Array of code strings to remove |
Example:
{
"key": "area_atividade",
"codes": ["0999", "1050"]
}
Example response:
{
"key": "area_atividade",
"removed": 2,
"not_found": 0,
"total_values": 884
}
sutram_upsert_record_category
Creates or updates a record category. Metadata must reference existing definitions. Use computed_from on a metadata entry to define the number base (uniqueness). Use slug_from at the category level to define how the slug (record name) is composed.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Unique category ID (snake_case) |
category |
object | Yes | Category definition (see fields below) |
Category fields:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name for the category |
metadata |
array | Yes | Array of metadata field references (see below) |
slug_separator |
string | No | Separator between slug parts (default: "-") |
slug_from |
array | No | Defines slug composition. Each entry has key and use ("code" or "label"). If omitted, slug = number_base + separator + sequence_number |
Metadata entry fields:
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Key of an existing metadata definition |
required |
boolean | No | Whether this field is required (default: false) |
order |
integer | No | Display order (0-based) |
computed_from |
array | No | For computed tags only. Defines the number base. Each entry has key and use ("code" or "label") |
sequence_digits |
integer | No | For computed tags only. Digits for the sequence number (2-4, default: 2) |
Example — category with slug_from (N-1710 style):
{
"category_id": "doc_tecnico_n1710",
"category": {
"name": "Technical Document N-1710",
"metadata": [
{ "key": "language", "required": false, "order": 0 },
{ "key": "document_category", "required": true, "order": 1 },
{ "key": "installation", "required": true, "order": 2 },
{ "key": "activity_area", "required": true, "order": 3 },
{ "key": "service_class", "required": true, "order": 4 },
{ "key": "document_origin", "required": true, "order": 5 },
{
"key": "coded_number", "required": false, "order": 6,
"computed_from": [
{ "key": "language", "use": "code" },
{ "key": "document_category", "use": "code" },
{ "key": "installation", "use": "label" },
{ "key": "activity_area", "use": "label" },
{ "key": "service_class", "use": "label" }
],
"sequence_digits": 3
}
],
"slug_separator": "-",
"slug_from": [
{ "key": "language", "use": "code" },
{ "key": "document_category", "use": "code" },
{ "key": "installation", "use": "label" },
{ "key": "activity_area", "use": "label" },
{ "key": "service_class", "use": "label" },
{ "key": "document_origin", "use": "label" },
{ "key": "coded_number", "use": "label" }
]
}
}
In this example:
- Number base (from
computed_from):MD-3010.95-0000-000— determines sequential uniqueness - Coded number:
001(next available sequence) - Slug (from
slug_from):MD-3010.95-0000-000-SWA-001— includesdocument_origin+ sequence
Example — simple category without slug_from (backward compatible):
{
"category_id": "exam",
"category": {
"name": "Medical Exam",
"metadata": [
{ "key": "specialty", "required": true, "order": 0 },
{
"key": "exam_number", "order": 1,
"computed_from": [
{ "key": "specialty", "use": "code" }
],
"sequence_digits": 3
}
],
"slug_separator": "-"
}
}
Without slug_from, the slug is automatically: {number_base}{separator}{sequence} (e.g., CARDIO-001).
sutram_delete_record_category
Deletes a record category.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | ID of the category to delete |
sutram_create_record
Creates a record with a category, validated metadata, and auto-generated slug. The slug is computed from the category's slug_from definition, or from computed_from (number base) + separator + sequence number. Use sutram_get_record_category_detail first to see required fields.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category_id |
string | Yes | Record category ID |
metadata |
object | Yes | Key-value pairs matching the category's metadata fields |
parent_folder_id |
string | No | Parent folder UUID (omit for root) |
name |
string | No | Custom name (defaults to auto-generated slug) |
Example:
{
"category_id": "doc_tecnico_n1710",
"metadata": {
"language": "PT",
"document_category": "Especificação",
"installation": "3010.95",
"activity_area": "0000",
"service_class": "000",
"document_origin": "SWA"
}
}
The response includes the computed slug and sequence number:
{
"record": {
"id": "...",
"name": "MD-3010.95-0000-000-SWA-001",
"slug": "MD-3010.95-0000-000-SWA-001",
"category": "doc_tecnico_n1710",
"metadata": {
"language": "PT",
"document_category": "Especificação",
"coded_number": "001",
"slug": "MD-3010.95-0000-000-SWA-001",
...
}
}
}
sutram_update_record
Updates a record's metadata. Recomputes the number base and slug when metadata fields referenced by computed_from or slug_from change.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
record_id |
string | Yes | Record (folder) UUID |
metadata |
object | Yes | Updated key-value pairs |
name |
string | No | New name (optional) |
sutram_delete_record
Deletes a record and all its contents (subfolders and files) recursively. This action cannot be undone.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
record_id |
string | Yes | Record (folder) UUID to delete |
Example: Full Record Workflow
// 1. Create metadata definitions
→ 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"}, {"label": "Civil", "code": "0200"}] } }
→ sutram_upsert_metadata { "key": "origin", "definition": { "label": "Origin", "type": "text" } }
→ sutram_upsert_metadata { "key": "doc_number", "definition": { "label": "Number", "type": "computed" } }
// 2. Add more values to a large enum incrementally
→ sutram_add_enum_values { "key": "area", "values": [{"label": "Elétrica", "code": "0300"}] }
// 3. Create a record category with computed_from and slug_from
→ sutram_upsert_record_category {
"category_id": "doc_tecnico",
"category": {
"name": "Technical Doc",
"metadata": [
{ "key": "language", "order": 0 },
{ "key": "area", "required": true, "order": 1 },
{ "key": "origin", "required": true, "order": 2 },
{ "key": "doc_number", "order": 3,
"computed_from": [
{ "key": "language", "use": "code" },
{ "key": "area", "use": "code" }
],
"sequence_digits": 3 }
],
"slug_separator": "-",
"slug_from": [
{ "key": "language", "use": "code" },
{ "key": "area", "use": "code" },
{ "key": "origin", "use": "label" },
{ "key": "doc_number", "use": "label" }
]
}
}
// 4. Check what fields are needed
→ sutram_get_record_category_detail { "category_id": "doc_tecnico" }
// 5. Create a record — slug is auto-generated from slug_from
→ sutram_create_record { "category_id": "doc_tecnico",
"metadata": { "language": "PT", "area": "Automação", "origin": "SWA" } }
← { "record": { "id": "...", "name": "PT-0100-SWA-001", "slug": "PT-0100-SWA-001",
"metadata": { "language": "PT", "area": "Automação", "origin": "SWA",
"doc_number": "001", "slug": "PT-0100-SWA-001" } } }
// 6. Create another record with same number base → sequence increments
→ sutram_create_record { "category_id": "doc_tecnico",
"metadata": { "language": "PT", "area": "Automação", "origin": "PPC" } }
← { "record": { "name": "PT-0100-PPC-002", "slug": "PT-0100-PPC-002", ... } }
Note how:
- The number base
PT-0100(fromcomputed_from: language + area) determines sequential uniqueness - The slug
PT-0100-SWA-001(fromslug_from) includesorigin+ the sequence number - The second record gets sequence
002because it shares the same number basePT-0100
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 interface and vice versa, thanks to PubSub broadcasting.
Position type restriction: Via MCP, AI can only create
file_level(comment on the whole file) ormarkdown(anchored to text in markdown files) comments. Position types that require 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 all top-level comments on a content item | Any member |
sutram_get_comment_thread |
Get a comment with its full thread of replies | 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
Lists all top-level comments on a content item. Returns comment content, author, position type, resolved status, and reply count.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | UUID of the content item |
include_resolved |
boolean | No | Whether to include resolved comments (default: true) |
Example:
{
"content_item_id": "abc-123"
}
Response:
{
"comments": [
{
"id": "comment-1",
"content": "This section needs review",
"position_type": "file_level",
"resolved": false,
"replies_count": 2,
"user": { "id": "...", "name": "Alice", "email": "alice@example.com" },
"created_at": "2026-03-10T14:30:00Z"
}
],
"total": 1
}
sutram_get_comment_thread
Gets a single comment with its full thread of replies, resolution status, and author details.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | UUID of the comment |
Response:
{
"comment": {
"id": "comment-1",
"content": "This section needs review",
"position_type": "file_level",
"resolved": false,
"resolved_at": null,
"resolved_by": null,
"replies_count": 1,
"user": { "id": "...", "name": "Alice", "email": "alice@example.com" },
"created_at": "2026-03-10T14:30:00Z",
"replies": [
{
"id": "reply-1",
"content": "I'll take care of it",
"user": { "id": "...", "name": "Bob", "email": "bob@example.com" },
"created_at": "2026-03-10T15:00:00Z"
}
]
}
}
sutram_create_comment
Creates a comment on a content item. AI can create file_level (default) or markdown comments.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content_item_id |
string | Yes | UUID of the content item |
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 — file-level comment:
{
"content_item_id": "abc-123",
"content": "This file needs to be updated with the latest specifications."
}
Example — markdown comment anchored to text:
{
"content_item_id": "abc-123",
"content": "Typo: should be 'specification' not 'specificaiton'",
"position_type": "markdown",
"text_anchor": {
"exact_text": "specificaiton",
"prefix": "the latest ",
"suffix": " document"
},
"original_text_snippet": "specificaiton"
}
sutram_reply_to_comment
Replies to an existing top-level comment. Replies cannot be nested (no reply-to-reply).
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | UUID of the top-level comment |
content |
string | Yes | Reply text |
Example:
{
"comment_id": "comment-1",
"content": "Good catch, I've fixed the typo."
}
sutram_resolve_comment
Resolves or reopens a comment thread. Resolved comments indicate the issue has been addressed.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | UUID of the comment |
action |
string | Yes | "resolve" or "reopen" |
Example:
{
"comment_id": "comment-1",
"action": "resolve"
}
sutram_delete_comment
Deletes a comment and all its replies. Only the comment author or project owner/admin can delete.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
comment_id |
string | Yes | UUID of the comment |
Example: Full Comment Workflow
// 1. List comments on a file
→ sutram_list_comments { "content_item_id": "abc-123" }
← { "comments": [...], "total": 3 }
// 2. Read a specific comment thread
→ sutram_get_comment_thread { "comment_id": "comment-1" }
← { "comment": { "content": "Needs review", "replies": [...] } }
// 3. Create a new comment
→ sutram_create_comment {
"content_item_id": "abc-123",
"content": "Section 3.2 references an outdated standard."
}
← { "comment": { "id": "comment-4", "content": "Section 3.2 references...", ... } }
// 4. Reply to it
→ sutram_reply_to_comment {
"comment_id": "comment-4",
"content": "Updated to reference ISO 9001:2025."
}
← { "reply": { "id": "reply-1", "content": "Updated to reference...", ... } }
// 5. Resolve the comment
→ sutram_resolve_comment { "comment_id": "comment-4", "action": "resolve" }
← { "comment": { "id": "comment-4", "resolved": true, ... } }
All comment changes broadcast in real-time to users viewing the same document in the web interface.
Limitations
The following operations are not yet available via MCP and must be done through the Sutram web interface. They will be added in future versions:
- Share: Sharing links cannot be generated
- Positioned comments: Creating comments anchored to PDF pages, CAD coordinates, or image positions requires the web GUI
Permissions
Your MCP access respects the same permissions as the web interface:
| Role | Browse | Upload/Create | Move | Delete | Versioning | Record Schema | Records | Comments |
|---|---|---|---|---|---|---|---|---|
| Owner | Yes | Yes | Yes | Yes | Full (publish, force release) | Full (CRUD definitions & categories) | CRUD | Full (list, create, reply, resolve, delete any) |
| Admin | Yes | Yes | Yes | Yes | Checkout/checkin | Read only | CRUD | Full (list, create, reply, resolve, delete any) |
| Member | Yes | Yes | Yes | Yes | Enable/disable, checkout/checkin | Read only | CRUD | List, create, reply, resolve, delete own |
| Viewer | No MCP access | — | — | — | — | — | — | — |
Viewers cannot use remote access. If you need MCP access, ask the project owner to upgrade your role.
Security
- Keys are independent: Revoking a user key doesn't affect other users. Revoking a project key disables remote 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 plain text: Project keys are encrypted. User keys are hashed — they cannot be retrieved after creation.
- Activity tracking: Every key records when it was last used.
- HTTPS only: All MCP connections use encrypted HTTPS.
Revoking access
To revoke your personal key:
- Go to Settings > API Key
- Click "Revoke Key"
- Create a new one if needed
To disable remote access for a project (owner only):
- Go to Settings > Projects
- Open the project dropdown
- Click "Remote Access"
- Click "Revoke Key"
Troubleshooting
"Authentication failed"
- Verify both keys are correct and haven't been revoked
- Ensure you are an active member of the project
- Viewers cannot use remote access — check your role on the project page
"Project key not available"
- The project key may have been revoked by the owner
- Ask the project owner to regenerate it from project settings
"Storage quota exceeded"
- Your account's storage limit has been reached
- Delete unused files or upgrade your plan
Tools not appearing in Claude Code
- Claude Code does not support
type: "url"yet — use themcp-remotebridge configuration (see Claude Code setup) - Make sure Node.js is installed (
npxmust be available in your PATH) - Check that the
.mcp.jsonfile is in the folder where you start Claude Code
Tools not appearing in Claude Desktop
- Restart Claude Desktop after editing the configuration file
- Check the JSON syntax is valid (no trailing commas, proper quoting)
- Verify the endpoint URL is correct
- If
type: "url"doesn't work, try themcp-remotebridge configuration (see Claude Desktop setup)
Connection timeout
- Check your internet connection
- Verify the Sutram service is accessible at
https://sutram.io
Supported File Types
Sutram auto-detects MIME types from file extensions. Common supported 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 platforms
YouTube, Vimeo, DailyMotion, Wistia, Loom, and TikTok. Platform is auto-detected from the URL, and thumbnails are extracted when available.
Audio platforms
Spotify, SoundCloud, Apple Podcasts, Anchor, and others. Platform is auto-detected from the URL.
Web links
Any valid HTTP/HTTPS URL. Page title, description, and favicon are fetched automatically.
Examples
Migrate medical exams from hospital portals
"Download my ultrasound exam from the hospital portal and organize it in Sutram under the requesting doctor's folder."
The AI assistant will:
- Access the hospital portal (via browser)
- Download the PDF report and image files
- Use
sutram_create_folderto build the folder structure in one call:Doctor Name / Exam Type / YYYY-MM-DD - Use
sutram_request_upload+sutram_confirm_uploadto upload each file directly to S3 - Clean up temporary local files
This workflow ensures medical data is properly organized and no sensitive files remain on the local computer.
Upload a local file
"Upload the file
report.pdffrom my desktop to the 'Reports' folder in Sutram."
Claude will read the file, use sutram_get_folder to find the "Reports" folder, then sutram_request_upload to get a presigned URL, upload the file directly to S3 via HTTP PUT, and call sutram_confirm_upload to finalize.
Organize project content
"Create a folder structure for our construction project: Plans, Reports, and Photos. Then upload these site photos."
Claude will use sutram_create_folder for each top-level folder, then sutram_request_upload + sutram_confirm_upload to upload each photo to the right folder.
Clean up old files
"Delete all files in the 'Temp' folder."
Claude will use sutram_get_folder to list the folder contents, then sutram_delete for each file.
Reorganize folder structure
"Move all contents from the '2024' folder into '2024-Archive' to free up space in the main view."
Claude will use sutram_move_contents to transfer all subfolders and files from the source to the target folder in a single operation. If any items have conflicting names, they are automatically renamed with numeric suffixes.
Move a specific file
"Move the 'contract.pdf' file to the 'Legal' folder."
Claude will use sutram_get_folder to find the file and target folder, then sutram_move_item to move the file. If a file with the same name already exists in the target folder, it will be automatically renamed (e.g., contract (1).pdf).
Save a web link
"Save this article to my project: https://example.com/building-codes-2026"
Claude will use sutram_create_web_link with the URL. Sutram automatically fetches the page title and favicon, so the link appears with its proper name in the project.
Organize video references
"Add these YouTube videos to the 'Training' folder: [video1 URL], [video2 URL]."
Claude will use sutram_get_folder to find the "Training" folder, then call sutram_create_video_link for each URL. Sutram detects that they are YouTube videos and extracts thumbnails automatically.
Download a file
"Get me the download link for the 'site-plan.pdf' file."
Claude will use sutram_get_folder to find the file, then sutram_get_item to retrieve a presigned download URL. The URL is temporary and can be used to download the file directly.
Tag and search folders
"Organize my medical exams by patient and exam type, then find all folders for patient João."
Claude will:
- Use
sutram_create_folderwithpathandtagsto create structured folders with metadata - Use
sutram_set_folder_tagsto add or update tags on existing folders - Use
sutram_search_folderswithtag_name: "patient"andtag_value: "João"to find all matching folders (substring match — also finds "João Pedro", "João Silva")
Tags enable AI assistants to create rich, searchable organizational structures without relying solely on folder names.
Discover tags and perform AND searches
"Find all USG exams for patient João within the Dr. Mion folder."
Claude will:
- Use
sutram_get_tag_keyswith the folder ID to discover available tag keys in that scope - Use
sutram_search_folderswith multiple AND conditions:{ "conditions": [ { "key": "patient", "value": "João" }, { "key": "exam_type", "value": "USG" } ], "folder_id": "dr-mion-folder-id" } - Return only folders that match both conditions within the specified hierarchy
Uploading Files via Script
When uploading files through an AI assistant, the assistant uses the two-step presigned URL flow: sutram_request_upload to get a presigned S3 PUT URL, then uploads the file directly to S3, and finally calls sutram_confirm_upload to create the file record. This approach avoids base64 encoding overhead and has no practical file size limit beyond your plan's storage quota.
For automation or batch uploads outside the AI assistant context, you can call the MCP endpoint directly via HTTP.
How the MCP HTTP endpoint works
The Sutram MCP server uses the Streamable HTTP transport (JSON-RPC 2.0 over HTTPS):
- Initialize a session —
POST https://app.sutram.io/mcpwith 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
All requests must include the authentication headers (x-project-key and x-user-key) and, after initialization, the mcp-session-id header.
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";
const HEADERS = {
"x-project-key": "sk_proj_YOUR_PROJECT_KEY",
"x-user-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;
const contentType = response.headers.get("content-type") || "";
if (contentType.includes("text/event-stream")) {
// Parse SSE: find the last "data:" line with a JSON-RPC response
const text = await response.text();
const events = text.split("\n\n").filter(Boolean);
for (const event of events.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 }),
});
}
// ── Usage ──
async function main() {
// 1. Initialize MCP session
await mcpRequest("initialize", {
protocolVersion: "2024-11-05",
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 file directly to S3
const fileContent = readFileSync(filePath);
const putResponse = await fetch(upload_url, {
method: "PUT",
headers: { "Content-Type": contentType },
body: fileContent,
});
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"
Claude Code skill integration
If you use Claude Code, you can wrap this script as a skill so the assistant can invoke it automatically when it needs to upload files. Place the script in .claude/skills/sutram-upload/scripts/upload.mjs and create a SKILL.md that instructs Claude how to call it. This way, when the assistant encounters a file to upload, it delegates the heavy I/O to the external script while keeping orchestration in the conversation.
Key points
- No file size limit beyond your Sutram plan's storage quota
- Files are uploaded directly to S3 via presigned URL — no base64 encoding, no data through the web server
- The script handles the full MCP handshake (initialize → notify → tool call)
- The response may come as JSON or Server-Sent Events (SSE) depending on processing time — the script handles both
- Credentials can be read from
.mcp.jsonto avoid hardcoding
REST API
In addition to MCP tools, Sutram provides a REST API for read-only consumption of project content. It uses the same dual-key authentication and is ideal for external apps, dashboards, and scripts.
Base URL: https://sutram.io/api/v1
Endpoints:
| Endpoint | Description |
|---|---|
GET /api/v1/project |
Project info |
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 |
Full documentation: REST API v1 Reference