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}`));
                    }
                });
            });
        }

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