Skip to main content
Glama

aps_get_submittal_item_attachments

Retrieve attachments for a submittal item by project ID and item ID. Returns file names, URNs, revision numbers, and categories for each attachment. Use the URN to download the file via the Data Management API.

Instructions

Get attachments for a specific submittal item. Returns file names, URNs, revision numbers, and categories. Use the URN to download the attachment via the Data Management API.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_idYesProject ID (UUID or 'b.' prefixed – auto‑converted).
item_idYesSubmittal item UUID.

Implementation Reference

  • src/index.ts:962-983 (registration)
    Tool registration (schema/definition) for aps_get_submittal_item_attachments in the TOOLS array, defining name, description, and inputSchema (project_id, item_id).
    // 24 ── aps_get_submittal_item_attachments
    {
      name: "aps_get_submittal_item_attachments",
      description:
        "Get attachments for a specific submittal item. " +
        "Returns file names, URNs, revision numbers, and categories. " +
        "Use the URN to download the attachment via the Data Management API.",
      inputSchema: {
        type: "object" as const,
        properties: {
          project_id: {
            type: "string",
            description: "Project ID (UUID or 'b.' prefixed – auto‑converted).",
          },
          item_id: {
            type: "string",
            description: "Submittal item UUID.",
          },
        },
        required: ["project_id", "item_id"],
      },
    },
  • Handler function for aps_get_submittal_item_attachments in the handleTool() function. Validates project_id and item_id, then calls the APS API endpoint 'items/{itemId}/attachments' via submittalPath() and summarizes the response with summarizeSubmittalAttachments().
    // ── aps_get_submittal_item_attachments ──────────────────────
    if (name === "aps_get_submittal_item_attachments") {
      const projectId = args.project_id as string;
      const rawItemId = args.item_id as string;
      const e1 = validateSubmittalProjectId(projectId);
      if (e1) return fail(e1);
      const e2 = validateSubmittalItemId(rawItemId);
      if (e2) return fail(e2);
      const itemId = encodeURIComponent(rawItemId);
    
      const t = await token();
      const raw = await apsDmRequest(
        "GET",
        submittalPath(projectId, `items/${itemId}/attachments`),
        t,
        { headers: { "Content-Type": "application/json" } },
      );
      return json(summarizeSubmittalAttachments(raw));
    }
  • Helper function summarizeSubmittalAttachments() that parses the raw API response (items/{itemId}/attachments) into a structured summary with attachment id, name, urn, upload_urn, revision, category, created_at, created_by.
    /** Summarise the response from GET /items/:itemId/attachments. */
    export function summarizeSubmittalAttachments(raw: unknown): {
      attachments: SubmittalAttachmentSummary[];
    } {
      // The response may be { results: [...] } or just an array
      const r = raw as Record<string, unknown> | undefined;
      const results = Array.isArray(r?.results)
        ? (r!.results as Record<string, unknown>[])
        : Array.isArray(raw)
          ? (raw as Record<string, unknown>[])
          : [];
    
      const attachments: SubmittalAttachmentSummary[] = results.map((att) => ({
        id: att.id as string,
        name: (att.name as string) ?? "(unknown)",
        urn: (att.urn as string) ?? undefined,
        upload_urn: (att.uploadUrn as string) ?? undefined,
        revision: (att.revision as number) ?? undefined,
        category: (att.categoryValue as string) ?? (att.category as string) ?? undefined,
        created_at: (att.createdAt as string) ?? undefined,
        created_by: (att.createdBy as string) ?? undefined,
      }));
    
      return { attachments };
    }
  • Helper function toAccProjectId() strips 'b.' prefix from project IDs, and submittalPath() builds the full API path for submittals endpoints.
    // ── ACC project‑ID helper ────────────────────────────────────────
    
    /**
     * Convert a project ID from DM format ('b.uuid') to ACC format ('uuid').
     * If the ID already lacks the 'b.' prefix, it is returned as‑is.
     */
    export function toAccProjectId(projectId: string): string {
      return projectId.replace(/^b\./, "");
    }
    
    // ── Submittal base path builder ──────────────────────────────────
    
    const SUBMITTALS_BASE = "construction/submittals/v2";
    
    /** Build the Submittals API path for a given project. */
    export function submittalPath(projectId: string, subPath: string): string {
      const pid = toAccProjectId(projectId);
      const sub = subPath.replace(/^\//, "");
      return `${SUBMITTALS_BASE}/projects/${pid}/${sub}`;
    }
  • Type definition SubmittalAttachmentSummary interface describing the shape of each attachment object returned by the tool.
    export interface SubmittalAttachmentSummary {
      id: string;
      name: string;
      urn?: string;
      upload_urn?: string;
      revision?: number;
      category?: string;
      created_at?: string;
      created_by?: string;
    }
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions return fields and hints at URN usage for download, but does not disclose authentication requirements, rate limits, or whether the operation is read-only. Minimal additional context beyond the obvious.

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 two sentences long, front-loads the purpose, and every sentence provides useful information. There is no wasted text.

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 no output schema, the description partially explains return values by listing fields, but does not specify types, structure, pagination, error handling, or limits. For a simple getter, this is minimally adequate but leaves gaps for the agent.

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 coverage is 100% with clear descriptions for both 'project_id' and 'item_id'. The tool description does not add any additional meaning or constraints beyond what the schema already provides, so it does not enhance parameter understanding.

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 the action ('Get attachments for a specific submittal item') and specifies the return fields ('file names, URNs, revision numbers, and categories'). This distinguishes it from sibling tools like 'aps_get_submittal_item' which retrieves the item itself.

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 does not provide guidance on when to use this tool vs alternatives. It only mentions using the URN to download via Data Management API, which is a post-retrieval step, not a selection criterion. No when-to-use or when-not-to-use advice is given.

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