aps_submittals_request
Execute any ACC Submittals API call with full control. Use for pagination, POST/PATCH, or endpoints like metadata, settings, item types. Returns raw JSON.
Instructions
Call any ACC Submittals API endpoint. This is the raw / power‑user tool – it returns the full JSON response. Prefer the simplified tools (aps_list_submittal_items, aps_list_submittal_packages, etc.) for everyday use. Use this tool when you need full control: pagination, POST/PATCH, or endpoints not covered by simplified tools (e.g. metadata, settings/mappings, users/me, item-types, responses).
The base path is: construction/submittals/v2/projects/{projectId}/ You only need to provide the sub‑path after 'projects/{projectId}/' (e.g. 'items', 'packages', 'specs').
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_id | Yes | Project ID – UUID format (e.g. 'abc12345-6789-…'). If you have a DM project ID with 'b.' prefix, it will be stripped automatically. | |
| method | No | HTTP method. Default: GET. | |
| path | Yes | Sub‑path relative to 'projects/{projectId}/' (e.g. 'items', 'packages', 'specs', 'items/{itemId}', 'metadata', 'responses', 'item-types'). | |
| query | No | Optional query parameters as key/value pairs (e.g. { "limit": "50", "offset": "0", "filter[statusId]": "2" }). | |
| body | No | Optional JSON body for POST requests. |
Implementation Reference
- src/index.ts:800-844 (schema)Schema (inputSchema) definition for the aps_submittals_request tool. Defines project_id, method, path, query, and body parameters.
// 19 ── aps_submittals_request (raw / power‑user) { name: "aps_submittals_request", description: "Call any ACC Submittals API endpoint. " + "This is the raw / power‑user tool – it returns the full JSON response. " + "Prefer the simplified tools (aps_list_submittal_items, aps_list_submittal_packages, etc.) for everyday use. " + "Use this tool when you need full control: pagination, POST/PATCH, or endpoints not covered by simplified tools " + "(e.g. metadata, settings/mappings, users/me, item-types, responses).\n\n" + "The base path is: construction/submittals/v2/projects/{projectId}/\n" + "You only need to provide the sub‑path after 'projects/{projectId}/' (e.g. 'items', 'packages', 'specs').", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – UUID format (e.g. 'abc12345-6789-…'). " + "If you have a DM project ID with 'b.' prefix, it will be stripped automatically.", }, method: { type: "string", enum: ["GET", "POST"], description: "HTTP method. Default: GET.", }, path: { type: "string", description: "Sub‑path relative to 'projects/{projectId}/' " + "(e.g. 'items', 'packages', 'specs', 'items/{itemId}', 'metadata', 'responses', 'item-types').", }, query: { type: "object", description: "Optional query parameters as key/value pairs (e.g. { \"limit\": \"50\", \"offset\": \"0\", \"filter[statusId]\": \"2\" }).", additionalProperties: { type: "string" }, }, body: { type: "object", description: "Optional JSON body for POST requests.", }, }, required: ["project_id", "path"], }, }, - src/index.ts:1452-1473 (handler)Handler logic for aps_submittals_request. Validates project ID and path via validateSubmittalProjectId/validateSubmittalPath, constructs the full Submittals API path via submittalPath(), then dispatches the request via apsDmRequest() and returns the raw JSON response.
// ── aps_submittals_request ────────────────────────────────── if (name === "aps_submittals_request") { const projectId = args.project_id as string; const e1 = validateSubmittalProjectId(projectId); if (e1) return fail(e1); const subPath = args.path as string; const pathErr = validateSubmittalPath(subPath); if (pathErr) return fail(pathErr); const method = (args.method as string) ?? "GET"; const query = args.query as Record<string, string> | undefined; const body = args.body as Record<string, unknown> | undefined; const t = await token(); const fullPath = submittalPath(projectId, subPath); const data = await apsDmRequest( method as "GET" | "POST" | "PATCH" | "DELETE", fullPath, t, { query, body, headers: { "Content-Type": "application/json" } }, ); return json(data); } - src/index.ts:141-994 (registration)Registration of aps_submittals_request in the TOOLS array (line 800-844), which is exposed via ListToolsRequestSchema at line 1588. The tool is also routed in handleTool() at line 1452.
const TOOLS = [ // 0a ── aps_login (3‑legged OAuth) { name: "aps_login", description: "Start a 3‑legged OAuth login for APS (user context). " + "Opens the user's browser to the Autodesk sign‑in page. " + "After the user logs in and grants consent, the token is cached to disk " + "and auto‑refreshed. All subsequent API calls use the 3LO token " + "(with the user's own permissions) until aps_logout is called. " + "The OAuth scope is determined by the APS_SCOPE setting configured by the user.", inputSchema: { type: "object" as const, properties: {}, }, }, // 0b ── aps_logout (clear 3LO session) { name: "aps_logout", description: "Clear the cached 3‑legged OAuth token. " + "After this, API calls fall back to the 2‑legged (app‑context) token.", inputSchema: { type: "object" as const, properties: {} }, }, // 1 ── aps_get_token { name: "aps_get_token", description: "Get a 2‑legged access token for Autodesk Platform Services (APS). " + "Use this to verify that credentials are configured correctly. " + "The token is cached and auto‑refreshed by all other tools, so you rarely need to call this explicitly.", inputSchema: { type: "object" as const, properties: {} }, }, // 2 ── aps_dm_request (raw / power‑user) { name: "aps_dm_request", description: "Call any APS Data Management API endpoint (project/v1, data/v1). " + "This is the raw / power‑user tool – it returns the full JSON:API response which can be very large (100 K+ tokens for folder listings). " + "Prefer the simplified tools (aps_list_hubs, aps_list_projects, aps_get_folder_contents, etc.) for everyday browsing. " + "Use this tool when you need full control: pagination, POST/PATCH/DELETE, or endpoints not covered by simplified tools.\n\n" + "Response guidance – when summarising large responses focus on:\n" + "• Folders: name, id, item count\n" + "• Files: name, type/extension, size, last modified, version info\n" + "• Ignore: relationship links, JSON:API meta, and extended attributes unless specifically needed.", inputSchema: { type: "object" as const, properties: { method: { type: "string", enum: ["GET", "POST", "PATCH", "DELETE"], description: "HTTP method.", }, path: { type: "string", description: "API path relative to developer.api.autodesk.com (e.g. 'project/v1/hubs' or " + "'data/v1/projects/b.xxx/folders/urn:adsk.wipprod:fs.folder:co.xxx/contents'). " + "Must include the version prefix (project/v1 or data/v1).", }, query: { type: "object", description: "Optional query parameters as key/value pairs (e.g. { \"page[limit]\": \"200\", \"includeHidden\": \"true\" }).", additionalProperties: { type: "string" }, }, body: { type: "object", description: "Optional JSON body for POST/PATCH requests.", }, }, required: ["method", "path"], }, }, // 3 ── aps_list_hubs { name: "aps_list_hubs", description: "List all ACC / BIM 360 hubs (accounts) accessible to this app. " + "Returns a compact summary: hub name, id, type, and region. " + "Use the returned hub id (e.g. 'b.abc123…') in subsequent calls to aps_list_projects.", inputSchema: { type: "object" as const, properties: {} }, }, // 4 ── aps_list_projects { name: "aps_list_projects", description: "List projects in an ACC / BIM 360 hub. " + "Returns a compact summary: project name, id, platform (ACC / BIM 360), and last modified date. " + "Use the returned project id with aps_get_top_folders or aps_get_folder_contents.", inputSchema: { type: "object" as const, properties: { hub_id: { type: "string", description: "Hub (account) ID – starts with 'b.' (e.g. 'b.abc12345-6789-…'). Get this from aps_list_hubs.", }, }, required: ["hub_id"], }, }, // 5 ── aps_get_top_folders { name: "aps_get_top_folders", description: "Get the root / top‑level folders for an ACC / BIM 360 project. " + "Common root folders: 'Project Files', 'Plans', 'Shared', 'Recycle Bin'. " + "Returns folder name, id, and item count. Use the folder id with aps_get_folder_contents.", inputSchema: { type: "object" as const, properties: { hub_id: { type: "string", description: "Hub (account) ID – starts with 'b.'.", }, project_id: { type: "string", description: "Project ID – starts with 'b.'.", }, }, required: ["hub_id", "project_id"], }, }, // 6 ── aps_get_folder_contents { name: "aps_get_folder_contents", description: "Get a summarised listing of a folder's contents. " + "Returns a compact JSON with: summary (item counts, file type breakdown, total size), " + "folders (name, id, item count), and files (name, id, type, size, version, dates). " + "This is ~95 % smaller than the raw API response.\n\n" + "Supports optional filtering by file extension and hiding hidden items. " + "For the full raw response, use aps_dm_request instead.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – starts with 'b.'.", }, folder_id: { type: "string", description: "Folder URN – starts with 'urn:'.", }, filter_extensions: { type: "array", items: { type: "string" }, description: "Optional list of file extensions to include (e.g. [\".rvt\", \".nwd\", \".ifc\"]). " + "Omit to return all file types.", }, exclude_hidden: { type: "boolean", description: "When true, exclude hidden items. Defaults to false.", }, page_limit: { type: "number", description: "Max items per page (1‑200). Defaults to 200.", }, }, required: ["project_id", "folder_id"], }, }, // 7 ── aps_get_item_details { name: "aps_get_item_details", description: "Get summarised metadata for a single file / item: name, type, size, version number, dates. " + "Much smaller than the raw JSON:API response. " + "Use for quick file lookups when you already have the item_id from a folder listing.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – starts with 'b.'.", }, item_id: { type: "string", description: "Item (lineage) URN – starts with 'urn:'.", }, }, required: ["project_id", "item_id"], }, }, // 8 ── aps_get_folder_tree { name: "aps_get_folder_tree", description: "Build a recursive folder‑tree structure showing subfolder hierarchy and file counts per folder. " + "Useful for understanding a project's organisation at a glance. " + "⚠️ Each level makes an API call, so keep max_depth low (default 3) to avoid rate limits.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – starts with 'b.'.", }, folder_id: { type: "string", description: "Root folder URN – starts with 'urn:'.", }, max_depth: { type: "number", description: "Maximum recursion depth (1‑5). Default 3.", }, }, required: ["project_id", "folder_id"], }, }, // 9 ── aps_docs { name: "aps_docs", description: "Return APS Data Management quick‑reference documentation: " + "common ID formats, typical browsing workflow, raw API paths, query parameters, " + "BIM file extensions, and error troubleshooting. " + "Call this before your first APS interaction or when unsure about ID formats or API paths.", inputSchema: { type: "object" as const, properties: {} }, }, // ═══════════════════════════════════════════════════════════════ // ACC Issues Tools // ═══════════════════════════════════════════════════════════════ // 10 ── aps_issues_request (raw / power‑user) { name: "aps_issues_request", description: "Call any ACC Issues API endpoint (construction/issues/v1). " + "This is the raw / power‑user tool – it returns the full API response. " + "Prefer the simplified tools (aps_issues_list, aps_issues_get, etc.) for everyday use. " + "Use this when you need full control: custom filters, attribute definitions, attribute mappings, " + "or endpoints not covered by simplified tools.\n\n" + "⚠️ Project IDs for the Issues API must NOT have the 'b.' prefix. " + "If you have a Data Management project ID like 'b.abc123', use 'abc123'.", inputSchema: { type: "object" as const, properties: { method: { type: "string", enum: ["GET", "POST", "PATCH", "DELETE"], description: "HTTP method.", }, path: { type: "string", description: "API path relative to developer.api.autodesk.com " + "(e.g. 'construction/issues/v1/projects/{projectId}/issues'). " + "Must include the version prefix (construction/issues/v1).", }, query: { type: "object", description: "Optional query parameters as key/value pairs " + "(e.g. { \"filter[status]\": \"open\", \"limit\": \"50\" }).", additionalProperties: { type: "string" }, }, body: { type: "object", description: "Optional JSON body for POST/PATCH requests.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region (x-ads-region header). Defaults to US.", }, }, required: ["method", "path"], }, }, // 11 ── aps_issues_get_types { name: "aps_issues_get_types", description: "Get issue categories (types) and their types (subtypes) for a project. " + "Returns a compact summary: category id, title, active status, and subtypes with code. " + "Use the returned subtype id when creating issues (issueSubtypeId).", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – accepts with or without 'b.' prefix (e.g. 'b.abc123' or 'abc123'). " + "Get this from aps_list_projects.", }, include_subtypes: { type: "boolean", description: "Include subtypes for each category. Defaults to true.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id"], }, }, // 12 ── aps_issues_list { name: "aps_issues_list", description: "List and search issues in a project with optional filtering. " + "Returns a compact summary per issue: id, displayId, title, status, assignee, dates, comment count. " + "Supports filtering by status, assignee, type, date, search text, and more. " + "This is much smaller than the raw API response.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – accepts with or without 'b.' prefix.", }, filter_status: { type: "string", description: "Filter by status. Comma‑separated. " + "Values: draft, open, pending, in_progress, in_review, completed, not_approved, in_dispute, closed.", }, filter_assigned_to: { type: "string", description: "Filter by assignee Autodesk ID. Comma‑separated for multiple.", }, filter_issue_type_id: { type: "string", description: "Filter by category (type) UUID. Comma‑separated for multiple.", }, filter_issue_subtype_id: { type: "string", description: "Filter by type (subtype) UUID. Comma‑separated for multiple.", }, filter_due_date: { type: "string", description: "Filter by due date (YYYY‑MM‑DD). Comma‑separated for range.", }, filter_created_at: { type: "string", description: "Filter by creation date (YYYY‑MM‑DD or YYYY‑MM‑DDThh:mm:ss.sz).", }, filter_search: { type: "string", description: "Search by title or display ID (e.g. '300' or 'wall crack').", }, filter_root_cause_id: { type: "string", description: "Filter by root cause UUID. Comma‑separated for multiple.", }, filter_location_id: { type: "string", description: "Filter by LBS location UUID. Comma‑separated for multiple.", }, limit: { type: "number", description: "Max issues to return (1‑100). Default 100.", }, offset: { type: "number", description: "Pagination offset. Default 0.", }, sort_by: { type: "string", description: "Sort field(s). Comma‑separated. Prefix with '-' for descending. " + "Values: createdAt, updatedAt, displayId, title, status, assignedTo, dueDate, startDate, closedAt.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id"], }, }, // 13 ── aps_issues_get { name: "aps_issues_get", description: "Get detailed information about a single issue. " + "Returns a compact summary with: id, title, description, status, assignee, dates, location, " + "custom attributes, linked document count, permitted statuses, and more.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – accepts with or without 'b.' prefix.", }, issue_id: { type: "string", description: "Issue UUID. Get this from aps_issues_list.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id", "issue_id"], }, }, // 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"], }, }, // 15 ── aps_issues_update { name: "aps_issues_update", description: "Update an existing issue. Only include the fields you want to change. " + "⚠️ Requires 'data:write' in APS_SCOPE. " + "To see which fields the current user can update, check permittedAttributes in the issue detail.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – accepts with or without 'b.' prefix.", }, issue_id: { type: "string", description: "Issue UUID to update.", }, title: { type: "string", description: "New title. Optional." }, description: { type: "string", description: "New description. Optional." }, status: { type: "string", enum: ["draft", "open", "pending", "in_progress", "in_review", "completed", "not_approved", "in_dispute", "closed"], description: "New status. Optional.", }, assigned_to: { type: "string", description: "New assignee Autodesk ID. Optional." }, assigned_to_type: { type: "string", enum: ["user", "company", "role"], description: "Assignee type. Required if assigned_to is set.", }, due_date: { type: "string", description: "New due date (ISO8601). Optional." }, start_date: { type: "string", description: "New start date (ISO8601). Optional." }, location_id: { type: "string", description: "New LBS location UUID. Optional." }, location_details: { type: "string", description: "New location text. Optional." }, root_cause_id: { type: "string", description: "New root cause UUID. Optional." }, published: { type: "boolean", description: "Set published state. Optional." }, watchers: { type: "array", items: { type: "string" }, description: "New watcher list. Optional.", }, custom_attributes: { type: "array", items: { type: "object", properties: { attributeDefinitionId: { type: "string" }, value: {}, }, required: ["attributeDefinitionId", "value"], }, description: "Custom attribute values to update. Optional.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id", "issue_id"], }, }, // 16 ── aps_issues_get_comments { name: "aps_issues_get_comments", description: "Get all comments for a specific issue. " + "Returns a compact list: comment id, body, author, date.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – accepts with or without 'b.' prefix.", }, issue_id: { type: "string", description: "Issue UUID.", }, limit: { type: "number", description: "Max comments to return. Optional.", }, offset: { type: "number", description: "Pagination offset. Optional.", }, sort_by: { type: "string", description: "Sort field (e.g. 'createdAt' or '-createdAt'). Optional.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id", "issue_id"], }, }, // 17 ── aps_issues_create_comment { name: "aps_issues_create_comment", description: "Add a comment to an issue. " + "⚠️ 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.", }, issue_id: { type: "string", description: "Issue UUID.", }, body: { type: "string", description: "Comment text (max 10,000 chars). Use \\n for newlines.", }, region: { type: "string", enum: ["US", "EMEA", "AUS", "CAN", "DEU", "IND", "JPN", "GBR"], description: "Data centre region. Defaults to US.", }, }, required: ["project_id", "issue_id", "body"], }, }, // 18 ── aps_issues_docs { name: "aps_issues_docs", description: "Return ACC Issues API quick‑reference documentation: " + "project ID format, statuses, typical workflow, raw API paths, " + "common filters, sort options, and error troubleshooting. " + "Call this before your first Issues interaction.", inputSchema: { type: "object" as const, properties: {} }, }, // ═══════════════════════════════════════════════════════════════ // ── ACC Submittals tools ─────────────────────────────────────── // ═══════════════════════════════════════════════════════════════ // 19 ── aps_submittals_request (raw / power‑user) { name: "aps_submittals_request", description: "Call any ACC Submittals API endpoint. " + "This is the raw / power‑user tool – it returns the full JSON response. " + "Prefer the simplified tools (aps_list_submittal_items, aps_list_submittal_packages, etc.) for everyday use. " + "Use this tool when you need full control: pagination, POST/PATCH, or endpoints not covered by simplified tools " + "(e.g. metadata, settings/mappings, users/me, item-types, responses).\n\n" + "The base path is: construction/submittals/v2/projects/{projectId}/\n" + "You only need to provide the sub‑path after 'projects/{projectId}/' (e.g. 'items', 'packages', 'specs').", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID – UUID format (e.g. 'abc12345-6789-…'). " + "If you have a DM project ID with 'b.' prefix, it will be stripped automatically.", }, method: { type: "string", enum: ["GET", "POST"], description: "HTTP method. Default: GET.", }, path: { type: "string", description: "Sub‑path relative to 'projects/{projectId}/' " + "(e.g. 'items', 'packages', 'specs', 'items/{itemId}', 'metadata', 'responses', 'item-types').", }, query: { type: "object", description: "Optional query parameters as key/value pairs (e.g. { \"limit\": \"50\", \"offset\": \"0\", \"filter[statusId]\": \"2\" }).", additionalProperties: { type: "string" }, }, body: { type: "object", description: "Optional JSON body for POST requests.", }, }, required: ["project_id", "path"], }, }, // 20 ── aps_list_submittal_items { name: "aps_list_submittal_items", description: "List submittal items in an ACC project. " + "Returns a compact summary: title, number, spec section, type, status, priority, revision, dates. " + "Supports filtering by status, package, spec section, and review response.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID (UUID or 'b.' prefixed – auto‑converted).", }, filter_status: { type: "string", description: "Filter by status ID: 1=Required, 2=Open, 3=Closed, 4=Void, 5=Empty, 6=Draft. " + "Omit to return all statuses.", }, filter_package_id: { type: "string", description: "Filter by package UUID. Omit to return items from all packages.", }, filter_spec_id: { type: "string", description: "Filter by spec section UUID. Omit to return all spec sections.", }, limit: { type: "number", description: "Max items per page (1–200). Default 20.", }, offset: { type: "number", description: "Pagination offset. Default 0.", }, }, required: ["project_id"], }, }, // 21 ── aps_get_submittal_item { name: "aps_get_submittal_item", description: "Get full details for a single submittal item by ID. " + "Returns the complete item object from the 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"], }, }, // 22 ── aps_list_submittal_packages { name: "aps_list_submittal_packages", description: "List submittal packages in an ACC project. " + "Returns a compact summary: title, identifier, spec section, description, dates.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID (UUID or 'b.' prefixed – auto‑converted).", }, limit: { type: "number", description: "Max items per page (1–200). Default 20.", }, offset: { type: "number", description: "Pagination offset. Default 0.", }, }, required: ["project_id"], }, }, // 23 ── aps_list_submittal_specs { name: "aps_list_submittal_specs", description: "List spec sections for submittals in an ACC project. " + "Returns a compact summary: identifier (e.g. '033100'), title, dates. " + "Spec sections are the specification divisions that submittal items are organised under.", inputSchema: { type: "object" as const, properties: { project_id: { type: "string", description: "Project ID (UUID or 'b.' prefixed – auto‑converted).", }, limit: { type: "number", description: "Max items per page (1–200). Default 20.", }, offset: { type: "number", description: "Pagination offset. Default 0.", }, }, required: ["project_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"], }, }, // 25 ── aps_submittals_docs { name: "aps_submittals_docs", description: "Return ACC Submittals API quick‑reference documentation: " + "endpoints, query parameters, statuses, custom numbering, typical workflow, and key concepts. " + "Call this before your first Submittals interaction or when unsure about Submittals API usage.", inputSchema: { type: "object" as const, properties: {} }, }, ]; - src/aps-submittals-helpers.ts:66-79 (helper)Helper functions used by aps_submittals_request: toAccProjectId() strips 'b.' prefix from project IDs, submittalPath() builds the full API path (construction/submittals/v2/projects/{projectId}/{subPath}).
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}`; } - Validation helpers used by aps_submittals_request: validateSubmittalProjectId() ensures the project ID is a valid UUID (optionally with 'b.' prefix), validateSubmittalPath() ensures the sub-path is non-empty and doesn't contain path traversal.
export function validateSubmittalProjectId(id: string): string | null { if (!id) return "project_id is required."; if (containsTraversalTokens(id)) return "project_id contains disallowed characters ('/', '\\', '%2F', or '..')."; // Accept 'b.<uuid>' (DM format) or plain UUID (ACC format) const bare = id.startsWith("b.") ? id.slice(2) : id; if (!UUID_RE.test(bare)) return "project_id must be a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) optionally prefixed with 'b.'."; return null; } export function validateSubmittalItemId(id: string): string | null { if (!id) return "item_id is required."; if (containsTraversalTokens(id)) return "item_id contains disallowed characters ('/', '\\', '%2F', or '..')."; if (!UUID_RE.test(id)) return "item_id must be a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)."; return null; } export function validateSubmittalPath(path: string): string | null { if (!path || typeof path !== "string") return "path is required and must be a non‑empty string."; if (path.includes("..")) return "path must not contain '..'."; return null; }