Repository navigation
Conversation
…hipments Adds partyRoles, addPartyRole, removePartyRole and clearCustomField to the container and shipment managers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lets an agent assign a party (such as the drayage carrier) or set an account custom field on up to 50 containers or shipments, reporting per-record updated, unchanged and failed results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const workers = Array.from( | ||
| { length: Math.min(CONCURRENCY, queue.length) }, | ||
| async () => { | ||
| for (let id = queue.shift(); id; id = queue.shift()) { | ||
| try { | ||
| result[await change(id)].push(id); | ||
| } catch (error) { | ||
| result.failed.push({ id, error: describeError(error) }); | ||
| } | ||
| } | ||
| }, | ||
| ); | ||
| await Promise.all(workers); |
There was a problem hiding this comment.
A 50-record call needs up to 100 API requests, with only five records running at once. If each read and write takes two seconds, the call takes about 40 seconds, but the hosted endpoint stops after 30 seconds. Some records will already be changed when the caller loses the response.
Give applyEach a call-wide time budget, stop starting records before it runs out, and return which records were completed or not attempted.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/mcp/src/tools/record-writes.ts
Line: 140-152
Comment:
**Bulk edits lose their result**
A 50-record call needs up to 100 API requests, with only five records running at once. If each read and write takes two seconds, the call takes about 40 seconds, but the hosted endpoint stops after 30 seconds. Some records will already be changed when the caller loses the response.
Give `applyEach` a call-wide time budget, stop starting records before it runs out, and return which records were completed or not attempted.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| value: z | ||
| .union([z.string().max(1000), z.number(), z.boolean(), z.null()]) |
There was a problem hiding this comment.
Multi-select fields cannot be changed
set_custom_field rejects the array needed to set a multi-select field. The API supports enum_multi fields whose values are string[], but this union rejects arrays before any record is read or changed. Accept arrays of strings and add a test that sets and repeats a multi-select value.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/mcp/src/tools/record-writes.ts
Line: 80-81
Comment:
**Multi-select fields cannot be changed**
`set_custom_field` rejects the array needed to set a multi-select field. The API supports `enum_multi` fields whose values are `string[]`, but this union rejects arrays before any record is read or changed. Accept arrays of strings and add a test that sets and repeats a multi-select value.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
sinankeskin
left a comment
There was a problem hiding this comment.
Some comments but no blocker
| }; | ||
| } | ||
|
|
||
| export function mapPartyRoles(doc: any): PartyRoleAssignment[] { |
There was a problem hiding this comment.
Just an idea. Maybe instead of writing your own JSON_API compliant client you might wanna use one of these: https://jsonapi.org/implementations/#server-libraries-node-js
ARCA asked Ask T49 to "set drayage carrier to Manzo Transport" for the containers on screen, and to work with a "Sales Rep" custom field (Braintrust, 10/6); the agent had no way to change records. This adds the first two record edits to the MCP (DEV-13423).
Tools
set_party_role:{ container_ids? | shipment_ids?, role, party_id, action: 'add' | 'remove' }. Containers take onlypickup_dray_carrier; shipments take every party role.set_custom_field:{ entity: 'container' | 'shipment', ids, api_slug, value }.nullclears the field.Both take 1 to 50 records and return
{ updated, unchanged, failed, summary }. Each record's current value is read first, so a repeat call reportsunchanged, and one failing record doesn't stop the rest. Both are marked as non-read-only, idempotent, non-destructive writes.They use the existing Rails endpoints:
GET/POST/DELETE /v2/{containers,shipments}/:id/party_roles,POST /v2/{…}/:id/custom_fields(Rails upserts byapi_slug), andDELETE /v2/{…}/:id/custom_fields/:api_slug. Rails enforces permissions.update_pathwayisn't sent: the t49 side sets attribution from the request's auth channel.For review: these tools are also listed in the public Claude and ChatGPT connector manifests (
claude-connector-submission.json,chatgpt-app-submission.json). The tests require those manifests to match the live tools. In Ask T49, approval before each call happens on the agent side.Changes
Testing
npm test --workspace @terminal49/mcp: 23 files, 402 tests pass.npm test --workspace @terminal49/sdk: 251 pass (1 skipped).npm run check: clean.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmith-botwith what you need.Fix the bulk-write time budget and multi-select field support before merging.
Fix with agent prompt
Summary
Adds
set_party_roleandset_custom_fieldto MCP, backed by new SDK helpers.Approval before each call remains on the agent side, as author
alosecexplicitly states.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD A[MCP write call] --> B[Check arguments] B --> C[Take up to 50 unique records] C --> D[Run five records at once] D --> E[Read current value] E --> F{Already matches?} F -->|Yes| G[Record unchanged] F -->|No| H[Send write through SDK] H --> I[Record updated or failed] G --> J[Wait for all records] I --> J J --> K[Return results and summary]Reviews (1) · Last reviewed commit: "docs(mcp): document set_party_role and s..." · Reviewed by Greptile