Skip to main content
Glama
create_project_field.ts5.41 kB
import { GitHubConfig, ToolResponse } from '../../shared/types.js'; interface CreateProjectFieldArgs { project_number?: number; project_id?: string; name: string; data_type: 'TEXT' | 'NUMBER' | 'DATE' | 'SINGLE_SELECT' | 'ITERATION'; description?: string; options?: string[]; // For SINGLE_SELECT fields default_value?: string; required?: boolean; } /** * Create custom fields for GitHub Projects v2 * Uses GraphQL mutation createProjectV2Field */ export async function createProjectField(config: GitHubConfig, args: CreateProjectFieldArgs): Promise<ToolResponse> { const { graphqlWithAuth, owner } = config; if (!owner) { throw new Error('GITHUB_OWNER environment variable is required for project operations'); } try { let projectId = args.project_id; // If project_number is provided instead of project_id, get the project ID if (!projectId && args.project_number) { const projectQuery = ` query($owner: String!, $number: Int!) { user(login: $owner) { projectV2(number: $number) { id title } } organization(login: $owner) { projectV2(number: $number) { id title } } } `; const projectResult = await graphqlWithAuth(projectQuery, { owner, number: args.project_number }); const project = projectResult.user?.projectV2 || projectResult.organization?.projectV2; if (!project) { throw new Error(`Project #${args.project_number} not found`); } projectId = project.id; } if (!projectId) { throw new Error('Either project_number or project_id must be provided'); } // Validate field type and options if (args.data_type === 'SINGLE_SELECT' && (!args.options || args.options.length === 0)) { throw new Error('SINGLE_SELECT fields require options to be provided'); } // Create the field using GraphQL mutation const createFieldMutation = ` mutation($input: CreateProjectV2FieldInput!) { createProjectV2Field(input: $input) { projectV2Field { ... on ProjectV2Field { id name dataType createdAt updatedAt } ... on ProjectV2SingleSelectField { id name dataType options { id name nameHTML } createdAt updatedAt } ... on ProjectV2IterationField { id name dataType configuration { iterations { id title duration startDate } completedIterations { id title duration startDate } } createdAt updatedAt } } } } `; const input: any = { projectId, name: args.name, dataType: args.data_type }; // Add options for SINGLE_SELECT fields if (args.data_type === 'SINGLE_SELECT' && args.options) { input.singleSelectOptions = args.options.map(option => ({ name: option })); } const result = await graphqlWithAuth(createFieldMutation, { input }); const field = result.createProjectV2Field.projectV2Field; let response = `✅ **Project field created successfully!**\n\n`; response += `**Name:** ${field.name}\n`; response += `**ID:** ${field.id}\n`; response += `**Type:** ${field.dataType}\n`; response += `**Created:** ${new Date(field.createdAt).toLocaleDateString()}\n`; // Add field-specific information if (field.dataType === 'SINGLE_SELECT' && field.options) { response += `**Options:** ${field.options.map((opt: any) => opt.name).join(', ')}\n`; } if (field.dataType === 'ITERATION' && field.configuration) { const totalIterations = field.configuration.iterations.length + field.configuration.completedIterations.length; response += `**Iterations:** ${totalIterations} configured\n`; } response += `\n💡 **Next Steps:**\n`; response += `• Use 'list_project_fields' to see all project fields\n`; response += `• Use 'update_project_field' to modify field settings\n`; response += `• Use field in project views and item configurations\n`; response += `• Set field values on project items using the project interface`; return { content: [{ type: "text", text: response }] }; } catch (error: any) { if (error.message?.includes('insufficient permission')) { throw new Error('Insufficient permissions to create project fields. Ensure your GitHub token has "project" scope.'); } if (error.message?.includes('already exists')) { throw new Error(`Field with name "${args.name}" already exists in this project.`); } if (error.message?.includes('Field limit exceeded')) { throw new Error('Project has reached the maximum number of custom fields (50 per project).'); } throw new Error(`Failed to create project field: ${error.message}`); } }

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/Faresabdelghany/github-project-manager-mcp'

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