Skip to main content
Glama

aps_issues_create

Create a new issue in a project with required title, issue subtype, and status. Optionally include description, assignee, dates, location, root cause, custom attributes, and watchers.

Instructions

Create a new issue in a project. Requires: title, issueSubtypeId (get from aps_issues_get_types), and status. Optional: description, assignee, dates, location, root cause, custom attributes, watchers. ⚠️ Requires 'data:write' in APS_SCOPE.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesProject ID – accepts with or without 'b.' prefix.
titleYesIssue title (max 10,000 chars).
issue_subtype_idYesType (subtype) UUID – get from aps_issues_get_types.
statusYesInitial status (e.g. 'open').
descriptionNoIssue description (max 10,000 chars). Optional.
assigned_toNoAutodesk ID of assignee (user, company, or role). Optional.
assigned_to_typeNoType of assignee. Required if assigned_to is set.
due_dateNoDue date in ISO8601 format (e.g. '2025‑12‑31'). Optional.
start_dateNoStart date in ISO8601 format. Optional.
location_idNoLBS (Location Breakdown Structure) UUID. Optional.
location_detailsNoLocation as plain text (max 8,300 chars). Optional.
root_cause_idNoRoot cause UUID. Optional.
publishedNoWhether the issue is published. Default false.
watchersNoArray of Autodesk IDs to add as watchers. Optional.
custom_attributesNoCustom attribute values. Optional.
regionNoData centre region. Defaults to US.

Implementation Reference

  • The handler function for aps_issues_create tool. Validates required fields (project_id, title, issue_subtype_id, status), normalizes the project ID, builds the request body from optional fields (description, assignee, dates, location, root cause, published, watchers, custom_attributes), and POSTs to the ACC Issues API. Returns the created issue detail via summarizeIssueDetail().
    // ── aps_issues_create ───────────────────────────────────────
    if (name === "aps_issues_create") {
      const projectId = args.project_id as string;
      const err = validateIssuesProjectId(projectId);
      if (err) return fail(err);
    
      const title = args.title as string;
      if (!title) return fail("title is required.");
      const issueSubtypeId = args.issue_subtype_id as string;
      if (!issueSubtypeId) return fail("issue_subtype_id is required.");
      const status = args.status as string;
      if (!status) return fail("status is required.");
    
      const pid = toIssuesProjectId(projectId);
      const region = args.region as string | undefined;
      const t = await token();
    
      const body: Record<string, unknown> = {
        title,
        issueSubtypeId,
        status,
      };
      if (args.description != null) body.description = args.description;
      if (args.assigned_to && !args.assigned_to_type)
        return fail("assigned_to_type is required when assigned_to is provided.");
      if (args.assigned_to != null && args.assigned_to_type != null) {
        body.assignedTo = args.assigned_to;
        body.assignedToType = args.assigned_to_type;
      } else if (args.assigned_to_type != null) {
        body.assignedToType = args.assigned_to_type;
      }
      if (args.due_date != null) body.dueDate = args.due_date;
      if (args.start_date != null) body.startDate = args.start_date;
      if (args.location_id != null) body.locationId = args.location_id;
      if (args.location_details != null) body.locationDetails = args.location_details;
      if (args.root_cause_id != null) body.rootCauseId = args.root_cause_id;
      if (args.published != null) body.published = args.published;
      if (args.watchers != null) body.watchers = args.watchers;
      if (args.custom_attributes != null) body.customAttributes = args.custom_attributes;
    
      const raw = await apsDmRequest(
        "POST",
        `construction/issues/v1/projects/${pid}/issues`,
        t,
        { body, headers: issuesWriteHeaders(region) },
      );
      return json(summarizeIssueDetail(raw));
    }
  • src/index.ts:559-649 (registration)
    Tool registration for aps_issues_create in the TOOLS array. Defines name, description, and inputSchema with all accepted parameters (project_id, title, issue_subtype_id, status, and optional fields like description, assigned_to, due_date, etc.).
    // 14 ── aps_issues_create
    {
      name: "aps_issues_create",
      description:
        "Create a new issue in a project. " +
        "Requires: title, issueSubtypeId (get from aps_issues_get_types), and status. " +
        "Optional: description, assignee, dates, location, root cause, custom attributes, watchers. " +
        "⚠️ Requires 'data:write' in APS_SCOPE.",
      inputSchema: {
        type: "object" as const,
        properties: {
          project_id: {
            type: "string",
            description: "Project ID – accepts with or without 'b.' prefix.",
          },
          title: {
            type: "string",
            description: "Issue title (max 10,000 chars).",
          },
          issue_subtype_id: {
            type: "string",
            description: "Type (subtype) UUID – get from aps_issues_get_types.",
          },
          status: {
            type: "string",
            enum: ["draft", "open", "pending", "in_progress", "in_review", "completed", "not_approved", "in_dispute", "closed"],
            description: "Initial status (e.g. 'open').",
          },
          description: {
            type: "string",
            description: "Issue description (max 10,000 chars). Optional.",
          },
          assigned_to: {
            type: "string",
            description: "Autodesk ID of assignee (user, company, or role). Optional.",
          },
          assigned_to_type: {
            type: "string",
            enum: ["user", "company", "role"],
            description: "Type of assignee. Required if assigned_to is set.",
          },
          due_date: {
            type: "string",
            description: "Due date in ISO8601 format (e.g. '2025‑12‑31'). Optional.",
          },
          start_date: {
            type: "string",
            description: "Start date in ISO8601 format. Optional.",
          },
          location_id: {
            type: "string",
            description: "LBS (Location Breakdown Structure) UUID. Optional.",
          },
          location_details: {
            type: "string",
            description: "Location as plain text (max 8,300 chars). Optional.",
          },
          root_cause_id: {
            type: "string",
            description: "Root cause UUID. Optional.",
          },
          published: {
            type: "boolean",
            description: "Whether the issue is published. Default false.",
          },
          watchers: {
            type: "array",
            items: { type: "string" },
            description: "Array of Autodesk IDs to add as watchers. Optional.",
          },
          custom_attributes: {
            type: "array",
            items: {
              type: "object",
              properties: {
                attributeDefinitionId: { type: "string" },
                value: {},
              },
              required: ["attributeDefinitionId", "value"],
            },
            description: "Custom attribute values. Optional.",
          },
          region: {
            type: "string",
            enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"],
            description: "Data centre region. Defaults to US.",
          },
        },
        required: ["project_id", "title", "issue_subtype_id", "status"],
      },
    },
  • summarizeIssueDetail() helper function used to format the response from aps_issues_create. Processes the raw API response into a structured IssueDetailSummary with all fields (id, title, description, status, assignee, dates, custom attributes, etc.).
    /** Summarise a single issue response – keeps more detail than the list summary. */
    export function summarizeIssueDetail(raw: unknown): IssueDetailSummary {
      const issue = raw as Record<string, unknown>;
    
      const customAttrs = Array.isArray(issue.customAttributes)
        ? (issue.customAttributes as Record<string, unknown>[]).map((ca) => ({
            id: (ca.attributeDefinitionId as string) ?? "",
            value: ca.value,
            type: (ca.type as string) ?? undefined,
            title: (ca.title as string) ?? undefined,
          }))
        : undefined;
    
      const linkedDocs = Array.isArray(issue.linkedDocuments)
        ? issue.linkedDocuments.length
        : 0;
    
      return {
        id: issue.id as string,
        displayId: (issue.displayId as number) ?? 0,
        title: (issue.title as string) ?? "",
        description: (issue.description as string) ?? undefined,
        status: (issue.status as string) ?? "",
        issueTypeId: (issue.issueTypeId as string) ?? undefined,
        issueSubtypeId: (issue.issueSubtypeId as string) ?? undefined,
        assignedTo: (issue.assignedTo as string) ?? undefined,
        assignedToType: (issue.assignedToType as string) ?? undefined,
        dueDate: (issue.dueDate as string) ?? undefined,
        startDate: (issue.startDate as string) ?? undefined,
        locationId: (issue.locationId as string) ?? undefined,
        locationDetails: (issue.locationDetails as string) ?? undefined,
        rootCauseId: (issue.rootCauseId as string) ?? undefined,
        published: (issue.published as boolean) ?? false,
        commentCount: (issue.commentCount as number) ?? 0,
        createdBy: (issue.createdBy as string) ?? "",
        createdAt: (issue.createdAt as string) ?? "",
        updatedAt: (issue.updatedAt as string) ?? "",
        closedBy: (issue.closedBy as string) ?? undefined,
        closedAt: (issue.closedAt as string) ?? undefined,
        customAttributes: customAttrs,
        linkedDocumentCount: linkedDocs,
        watchers: Array.isArray(issue.watchers)
          ? (issue.watchers as string[])
          : undefined,
        permittedStatuses: Array.isArray(issue.permittedStatuses)
          ? (issue.permittedStatuses as string[])
          : undefined,
      };
    }
  • IssueDetailSummary interface that defines the shape of the response returned by aps_issues_create.
    export interface IssueDetailSummary extends IssueSummary {
      description?: string;
      issueTypeId?: string;
      issueSubtypeId?: string;
      locationId?: string;
      customAttributes?: { id: string; value: unknown; type?: string; title?: string }[];
      linkedDocumentCount: number;
      watchers?: string[];
      permittedStatuses?: string[];
    }
  • toIssuesProjectId() helper used by the handler to strip the 'b.' prefix from project IDs for the Issues API.
    export function toIssuesProjectId(projectId: string): string {
      return projectId.replace(/^b\./, "");
    }
Behavior4/5

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

No annotations provided, so description carries full burden. It discloses the 'data:write' scope requirement and the effect of requiring project_id, title, issue_subtype_id, and status. The create operation's behavioral impact is clear.

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?

Extremely concise: one sentence for purpose, one line for required fields, one line for optional fields, and a warning. No fluff, every sentence adds value.

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

Completeness3/5

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

Given 16 parameters and no output schema, the description is minimal. It does not explain the response structure, error handling, or what happens after successful creation. More detail would improve completeness.

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 baseline is 3. The description adds context for issue_subtype_id (reference to aps_issues_get_types) and the 'data:write' scope, but does not add much beyond the schema.

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

Purpose5/5

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

The description clearly states 'Create a new issue in a project.' with specific required fields (title, issueSubtypeId, status). It distinguishes from sibling tools like aps_issues_list, aps_issues_update, and aps_issues_get.

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

Usage Guidelines4/5

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

Lists required and optional parameters, plus a warning about the required 'data:write' scope. No explicit mention of when not to use or alternatives, but the required fields give clear starting guidance.

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/EverseDevelopment/APS.MCP'

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