Skip to main content
Glama

create_doc

Create documents or reports with specified content, assign editors and subscribers, and organize them in designated folders.

Instructions

Create a new document or report

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
folder_duidYesFolder DUID to create the document in
titleYesTitle of the document
textNoContent of the document
text_markdownNoMarkdown content of the document
report_kindNoKind of report (if creating a report)
editor_duidsNoList of editor DUIDs
subscriber_duidsNoList of subscriber DUIDs

Implementation Reference

  • Handler for the 'create_doc' tool. Validates required parameters (folder_duid, title), generates embedded Python code to create a Doc using Dart's DocCreate, Operation, and transact with TransactionKind.DOC_CREATE, handles optional fields like text, report_kind, editors/subscribers, executes via runDartCommand, and returns the output text.
                    case 'create_doc': {
                        console.error('[Debug] Handling create_doc request');
                        
                        // Validate required fields
                        if (!args.folder_duid) {
                            throw new McpError(ErrorCode.INVALID_PARAMS, "folder_duid is required");
                        }
                        if (!args.title) {
                            throw new McpError(ErrorCode.INVALID_PARAMS, "title is required");
                        }
                        
                        const pythonCode = `    # Create a new document
    print("[Debug] Creating document", file=sys.stderr)
    try:
        from dart import Operation, OperationKind, OperationModelKind, DocCreate, TransactionKind, DocSourceType
        from dart.generated.models.report_kind import ReportKind
        from dart.generated.models.validation_error_response import ValidationErrorResponse
        from dart.dart import _make_duid
        
        folder_duid = "${args.folder_duid}"
        title = '''${args.title.replace(/'/g, "\\'")}'''  # title is validated above
        text = '''${args.text ? args.text.replace(/'/g, "\\'") : ''}'''
        text_markdown = '''${args.text_markdown ? args.text_markdown.replace(/'/g, "\\'") : ''}'''
        report_kind_str = "${args.report_kind || ''}"
        
        print(f"[Debug] Creating document in folder: {folder_duid}", file=sys.stderr)
        print(f"[Debug] Document title: {title}", file=sys.stderr)
        if report_kind_str:
            print(f"[Debug] Report kind: {report_kind_str}", file=sys.stderr)
        
        # Create the document object
        doc = DocCreate(
            duid=_make_duid(),
            folder_duid=folder_duid,
            title=title,
            source_type=DocSourceType.APPLICATION,
            order="0"  # Add order field like in create_folder
        )
        
        # Add optional fields
        if text:
            doc.text = text
        if text_markdown:
            doc.text_markdown = text_markdown
        if report_kind_str:
            doc.report_kind = ReportKind(report_kind_str)
            
        # Add editor and subscriber DUIDs if provided
        editor_duids_json = '''${JSON.stringify(args.editor_duids || [])}'''
        subscriber_duids_json = '''${JSON.stringify(args.subscriber_duids || [])}'''
        editor_duids = json.loads(editor_duids_json)
        subscriber_duids = json.loads(subscriber_duids_json)
        
        if editor_duids:
            doc.editor_duids = editor_duids
        if subscriber_duids:
            doc.subscriber_duids = subscriber_duids
            
        print("[Debug] Document object created:", doc, file=sys.stderr)
        
        # Create the operation
        doc_op = Operation(
            model=OperationModelKind.DOC,
            kind=OperationKind.CREATE,
            data=doc
        )
        print("[Debug] Operation created:", doc_op, file=sys.stderr)
        
        # Execute the transaction
        print("[Debug] Executing transaction", file=sys.stderr)
        response = client.transact([doc_op], TransactionKind.DOC_CREATE)
        print("[Debug] Transaction completed", file=sys.stderr)
        print("[Debug] Response type:", type(response), file=sys.stderr)
        print("[Debug] Response:", response, file=sys.stderr)
        
        if isinstance(response, ValidationErrorResponse):
            print("[Debug] Validation error:", response.items.additional_properties, file=sys.stderr)
            print(f"Validation error: {response.items.additional_properties}")
            sys.exit(1)
        
        if response.results and response.results[0].success:
            doc = response.results[0].models.docs[0]
            print(f"Document created successfully")
            print(f"Title: {doc.title}")
            print(f"DUID: {doc.duid}")
            if hasattr(doc, 'report_kind') and doc.report_kind:
                print(f"Report Kind: {doc.report_kind}")
            print(f"[Debug] Document DUID: {doc.duid}", file=sys.stderr)
        else:
            print("[Debug] Document creation failed", file=sys.stderr)
            if response.results:
                print(f"[Debug] Result: {response.results[0]}", file=sys.stderr)
            sys.exit(1)
    except Exception as e:
        print(f"[Debug] Error creating document: {str(e)}", file=sys.stderr)
        print("[Debug] Error type:", type(e), file=sys.stderr)
        traceback.print_exc(file=sys.stderr)
        sys.exit(1)`;
    
                        // Add proper indentation to the Python code
                        const command = pythonCode.split('\n').map(line => line.length > 0 ? '    ' + line : line).join('\n');
    
                        console.error('[Debug] Running Python command for document creation');
                        const output = await this.runDartCommand(command);
                        console.error('[Debug] Document creation output:', output);
                        const response = {
                            content: [{
                                type: 'text',
                                text: output,
                            }],
                        };
                        return response;
                    }
  • Input schema for the 'create_doc' tool, defining parameters like folder_duid (required), title (required), text, text_markdown, report_kind (enum: Changelog, Standup), editor_duids, subscriber_duids.
        name: 'create_doc',
        description: 'Create a new document or report',
        inputSchema: {
            type: 'object',
            properties: {
                folder_duid: {
                    type: 'string',
                    description: 'Folder DUID to create the document in',
                },
                title: {
                    type: 'string',
                    description: 'Title of the document',
                },
                text: {
                    type: 'string',
                    description: 'Content of the document',
                },
                text_markdown: {
                    type: 'string',
                    description: 'Markdown content of the document',
                },
                report_kind: {
                    type: 'string',
                    description: 'Kind of report (if creating a report)',
                    enum: ['Changelog', 'Standup'],
                },
                editor_duids: {
                    type: 'array',
                    items: {
                        type: 'string',
                    },
                    description: 'List of editor DUIDs',
                },
                subscriber_duids: {
                    type: 'array',
                    items: {
                        type: 'string',
                    },
                    description: 'List of subscriber DUIDs',
                }
            },
            required: ['folder_duid', 'title'],
        },
    },
  • src/index.ts:230-513 (registration)
    Registration of the 'create_doc' tool in the listTools response, including its name, description, and inputSchema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
        console.error('[Debug] Handling listTools request');
        const tools = [
            {
                name: 'get_default_status',
                description: 'Get the default status DUIDs',
                inputSchema: {
                    type: 'object',
                    properties: {},
                    required: [],
                },
            },
            {
                name: 'get_default_space',
                description: 'Get the default space DUID',
                inputSchema: {
                    type: 'object',
                    properties: {},
                    required: [],
                },
            },
            {
                name: 'create_task',
                description: 'Create a new Dart task',
                inputSchema: {
                    type: 'object',
                    properties: {
                        title: {
                            type: 'string',
                            description: 'Title of the task',
                        },
                        description: {
                            type: 'string',
                            description: 'Description of the task',
                        },
                        priority: {
                            type: 'string',
                            description: 'Priority of the task',
                            enum: ['Low', 'Medium', 'High', 'Critical'],
                        },
                        tags: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                            description: 'Tags for the task',
                        },
                        size: {
                            type: 'number',
                            description: 'Size/complexity of the task (1-5)',
                            minimum: 1,
                            maximum: 5,
                        },
                        assignee_duids: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                            description: 'List of assignee DUIDs',
                        },
                        subscriber_duids: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                            description: 'List of subscriber DUIDs',
                        }
                    },
                    required: ['title', 'description'],
                },
            },
            {
                name: 'update_task',
                description: 'Update an existing task',
                inputSchema: {
                    type: 'object',
                    properties: {
                        duid: {
                            type: 'string',
                            description: 'DUID of the task to update',
                        },
                        status_duid: {
                            type: 'string',
                            description: 'New status DUID',
                        },
                        title: {
                            type: 'string',
                            description: 'New title for the task',
                        },
                        description: {
                            type: 'string',
                            description: 'New description for the task',
                        },
                        priority: {
                            type: 'string',
                            description: 'New priority for the task',
                            enum: ['Low', 'Medium', 'High', 'Critical'],
                        }
                    },
                    required: ['duid'],
                },
            },
            {
                name: 'get_dartboards',
                description: 'Get available dartboards',
                inputSchema: {
                    type: 'object',
                    properties: {
                        space_duid: {
                            type: 'string',
                            description: 'Space DUID to get dartboards from',
                        }
                    },
                    required: ['space_duid'],
                },
            },
            {
                name: 'get_folders',
                description: 'Get available folders',
                inputSchema: {
                    type: 'object',
                    properties: {
                        space_duid: {
                            type: 'string',
                            description: 'Space DUID to get folders from',
                        }
                    },
                    required: ['space_duid'],
                },
            },
            {
                name: 'create_folder',
                description: 'Create a new folder in a space',
                inputSchema: {
                    type: 'object',
                    properties: {
                        space_duid: {
                            type: 'string',
                            description: 'Space DUID to create the folder in',
                        },
                        title: {
                            type: 'string',
                            description: 'Title of the folder',
                        },
                        description: {
                            type: 'string',
                            description: 'Description of the folder',
                        },
                        kind: {
                            type: 'string',
                            description: 'Kind of folder',
                            enum: ['Default', 'Reports', 'Other'],
                            default: 'Default'
                        }
                    },
                    required: ['space_duid', 'title'],
                },
            },
            {
                name: 'create_doc',
                description: 'Create a new document or report',
                inputSchema: {
                    type: 'object',
                    properties: {
                        folder_duid: {
                            type: 'string',
                            description: 'Folder DUID to create the document in',
                        },
                        title: {
                            type: 'string',
                            description: 'Title of the document',
                        },
                        text: {
                            type: 'string',
                            description: 'Content of the document',
                        },
                        text_markdown: {
                            type: 'string',
                            description: 'Markdown content of the document',
                        },
                        report_kind: {
                            type: 'string',
                            description: 'Kind of report (if creating a report)',
                            enum: ['Changelog', 'Standup'],
                        },
                        editor_duids: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                            description: 'List of editor DUIDs',
                        },
                        subscriber_duids: {
                            type: 'array',
                            items: {
                                type: 'string',
                            },
                            description: 'List of subscriber DUIDs',
                        }
                    },
                    required: ['folder_duid', 'title'],
                },
            },
            {
                name: 'create_space',
                description: 'Create a new space',
                inputSchema: {
                    type: 'object',
                    properties: {
                        title: {
                            type: 'string',
                            description: 'Title of the space'
                        },
                        description: {
                            type: 'string',
                            description: 'Description of the space'
                        },
                        abrev: {
                            type: 'string',
                            description: 'Short abbreviation for the space'
                        },
                        accessible_by_team: {
                            type: 'boolean',
                            description: 'Whether the space is accessible by the whole team',
                            default: true
                        },
                        accessible_by_user_duids: {
                            type: 'array',
                            items: {
                                type: 'string'
                            },
                            description: 'List of user DUIDs who can access the space'
                        },
                        icon_kind: {
                            type: 'string',
                            enum: ['None', 'Icon', 'Emoji'],
                            description: 'Kind of icon to use',
                            default: 'None'
                        },
                        icon_name_or_emoji: {
                            type: 'string',
                            description: 'Icon name or emoji character'
                        },
                        color_hex: {
                            type: 'string',
                            description: 'Color in hex format (e.g. #FF0000)'
                        },
                        sprint_mode: {
                            type: 'string',
                            enum: ['None', 'ANBA'],
                            description: 'Sprint mode for the space',
                            default: 'None'
                        },
                        sprint_replicate_on_rollover: {
                            type: 'boolean',
                            description: 'Whether to replicate sprints on rollover',
                            default: false
                        },
                        sprint_name_fmt: {
                            type: 'string',
                            description: 'Sprint name format'
                        }
                    },
                    required: ['title']
                }
            },
            {
                name: 'delete_space',
                description: 'Delete a space and all its contents',
                inputSchema: {
                    type: 'object',
                    properties: {
                        space_duid: {
                            type: 'string',
                            description: 'DUID of the space to delete'
                        }
                    },
                    required: ['space_duid']
                }
            }
        ];
        console.error('[Debug] Sending tools response:', JSON.stringify(tools, null, 2));
        return { tools };
    });
  • Helper method runDartCommand used by create_doc (and other tools) to execute the generated Python code interacting with the Dart library via child_process.spawn of Python.
        async runDartCommand(args) {
            return new Promise((resolve, reject) => {
                // Use pyenv Python
                const pythonPath = '/Users/speed/.pyenv/shims/python';
                console.error('[Debug] Running Python command with:', pythonPath);
                
                const command = `import sys
    import os
    import traceback
    import json
    from dart import Dart, Operation, OperationKind, OperationModelKind, TaskCreate, TaskUpdate, TransactionKind, TaskSourceType, SpaceCreate
    from dart.generated.types import UNSET
    from dart.dart import _Session, UserBundle, _make_duid
    from dart.generated.models.icon_kind import IconKind
    from dart.generated.models.sprint_mode import SprintMode
    from dart.generated.models.validation_error_response import ValidationErrorResponse
    
    def initialize():
        print("[Debug] Starting Python execution", file=sys.stderr)
        print("[Debug] Current directory:", os.getcwd(), file=sys.stderr)
        print("[Debug] PYTHONPATH:", os.environ.get('PYTHONPATH'), file=sys.stderr)
        print("[Debug] DART_TOKEN:", os.environ.get('DART_TOKEN'), file=sys.stderr)
        
        session = _Session()
        print("[Debug] Session created", file=sys.stderr)
        bundle = UserBundle(session)
        print("[Debug] UserBundle created", file=sys.stderr)
        dartboard_duid = bundle.default_dartboard["duid"]
        print(f"[Debug] Got dartboard DUID: {dartboard_duid}", file=sys.stderr)
        client = Dart()
        print("[Debug] Dart client created", file=sys.stderr)
        
        return client, bundle, dartboard_duid
    
    def run_command(client, bundle, dartboard_duid):
        ${args}
    
    def main():
        client, bundle, dartboard_duid = initialize()
        run_command(client, bundle, dartboard_duid)
    
    try:
        main()
    except Exception as e:
        print(f"Error: {str(e)}", file=sys.stderr)
        traceback.print_exc(file=sys.stderr)
        sys.exit(1)`;
                
                console.error('[Debug] Python command:', command);
    
                // Create a clean environment without virtual env variables
                const env = { ...process.env };
                delete env.VIRTUAL_ENV;
                delete env.CONDA_PREFIX;
                delete env.CONDA_DEFAULT_ENV;
                delete env.CONDA_PYTHON_EXE;
    
                const childProcess = spawn(pythonPath, ['-c', command], {
                    env: {
                        ...env,
                        PYTHONUNBUFFERED: '1',
                        PYTHONPATH: process.env.PYTHONPATH || process.cwd(),
                        DART_TOKEN: process.env.DART_TOKEN,
                    },
                    stdio: ['pipe', 'pipe', 'pipe'],
                });
    
                let output = '';
                let errorOutput = '';
    
                childProcess.stdout?.on('data', (data) => {
                    const str = data.toString();
                    console.error('[Debug] Python stdout:', str);
                    output += str;
                });
    
                childProcess.stderr?.on('data', (data) => {
                    const str = data.toString();
                    console.error('[Debug] Python stderr:', str);
                    errorOutput += str;
                });
    
                childProcess.on('error', (error) => {
                    console.error('[Debug] Python process error:', error);
                    reject(new Error(`Failed to start Python process: ${error.message}`));
                });
    
                // Add timeout
                const timeout = setTimeout(() => {
                    console.error('[Debug] Python command timed out');
                    childProcess.kill();
                    reject(new Error('Command timed out'));
                }, 30000); // 30 second timeout
    
                childProcess.on('close', (code) => {
                    clearTimeout(timeout);
                    console.error(`[Debug] Python process exited with code ${code}`);
                    if (code === 0) {
                        resolve(output.trim());
                    } else {
                        reject(new Error(errorOutput || `Command failed with exit code ${code}`));
                    }
                });
            });
        }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. 'Create a new document or report' implies a write/mutation operation but reveals nothing about permissions needed, whether creation is reversible, rate limits, or what happens on success/failure. For a mutation tool with zero annotation coverage, this is a significant gap in transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that states the core purpose without any fluff. It's appropriately sized and front-loaded, with every word earning its place. No structural issues or unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation tool with no annotations and no output schema, the description is inadequate. It doesn't explain the relationship between document vs. report creation, what happens when text vs. text_markdown is provided, or what the tool returns. The agent lacks critical context about this write operation's behavior and outcomes.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all parameters are documented in the schema itself. The description adds no additional parameter semantics beyond the basic concept of 'document or report' creation. This meets the baseline of 3 when the schema does the heavy lifting, but the description doesn't compensate with any extra context about parameter relationships or usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Create') and resource ('document or report'), making the purpose immediately understandable. However, it doesn't differentiate between creating documents versus reports or explain how this tool differs from sibling tools like create_folder or create_space, which prevents a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. There's no mention of prerequisites (like needing a folder DUID), when to choose document vs. report creation, or how this differs from sibling tools like create_folder or create_task. The agent must infer usage from parameters alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jmanhype/dart-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server