Add Search v2 endpoint documentation#180
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| "example": { | ||
| "data": [ | ||
| { | ||
| "id": "abc12345-6789-0def-ghij-klmnopqrstuv", |
There was a problem hiding this comment.
The example id values contain non-hexadecimal characters (letters g through s). Valid UUIDs use only hex digits [0-9a-f], but these examples use invalid characters. This may confuse API consumers reading the documentation.
Replace with valid UUID examples using only hexadecimal characters [0-9a-f]. Real Terminal49 resource IDs follow the standard 8-4-4-4-12 hex format.
Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/openapi.json
Line: 7165
Comment:
The example `id` values contain non-hexadecimal characters (letters g through s). Valid UUIDs use only hex digits [0-9a-f], but these examples use invalid characters. This may confuse API consumers reading the documentation.
Replace with valid UUID examples using only hexadecimal characters [0-9a-f]. Real Terminal49 resource IDs follow the standard 8-4-4-4-12 hex format.
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (2)
Either create the missing Prompt To Fix With AIThis is a comment left during a code review.
Path: docs/docs.json
Line: 204
Comment:
The MCP navigation references `"mcp/project-overview"`, but no corresponding `docs/mcp/project-overview.mdx` file exists. This will cause a broken navigation link or build failure in Mintlify.
Either create the missing `docs/mcp/project-overview.mdx` file or remove this entry from the pages array.
How can I resolve this? If you propose a fix, please make it concise.
Add a guard at the start of the method: if (!query || query.trim() === '') {
throw new ValidationError('query is required (/query)');
}Prompt To Fix With AIThis is a comment left during a code review.
Path: sdks/typescript-sdk/src/client.ts
Line: 205-208
Comment:
The `search` method accepts an empty query string and forwards it to the API, which returns a `400 Bad Request`. Unlike other methods in the class (e.g., `inferTrackingNumber` on line 290-293), this lacks early validation and causes an unnecessary network round-trip.
Add a guard at the start of the method:
```typescript
if (!query || query.trim() === '') {
throw new ValidationError('query is required (/query)');
}
```
How can I resolve this? If you propose a fix, please make it concise. |
ae6560e to
66f98f3
Compare
| const response = await fetch(jwksUrl, { | ||
| method: 'GET', | ||
| headers: { Accept: 'application/json' }, | ||
| }); |
There was a problem hiding this comment.
fetchJwks has no request timeout
The fetch call here has no AbortController or timeout, while the sibling verifyViaInternalPrincipal consistently uses a 2-second abort timeout. In a serverless/Vercel environment, if the WorkOS JWKS endpoint is slow or temporarily unreachable, this call will block the function until the platform-level timeout (potentially tens of seconds), rejecting every OAuth token during that window.
Consider adding the same pattern used in verifyViaInternalPrincipal:
| const response = await fetch(jwksUrl, { | |
| method: 'GET', | |
| headers: { Accept: 'application/json' }, | |
| }); | |
| const abortController = new AbortController(); | |
| const timeout = setTimeout(() => abortController.abort(), 3000); | |
| let response: Response; | |
| try { | |
| response = await fetch(jwksUrl, { | |
| method: 'GET', | |
| headers: { Accept: 'application/json' }, | |
| signal: abortController.signal, | |
| }); | |
| } catch { | |
| return []; | |
| } finally { | |
| clearTimeout(timeout); | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/mcp/src/auth/workos-jwt.ts
Line: 125-128
Comment:
`fetchJwks` has no request timeout
The `fetch` call here has no `AbortController` or timeout, while the sibling `verifyViaInternalPrincipal` consistently uses a 2-second abort timeout. In a serverless/Vercel environment, if the WorkOS JWKS endpoint is slow or temporarily unreachable, this call will block the function until the platform-level timeout (potentially tens of seconds), rejecting every OAuth token during that window.
Consider adding the same pattern used in `verifyViaInternalPrincipal`:
```suggestion
const abortController = new AbortController();
const timeout = setTimeout(() => abortController.abort(), 3000);
let response: Response;
try {
response = await fetch(jwksUrl, {
method: 'GET',
headers: { Accept: 'application/json' },
signal: abortController.signal,
});
} catch {
return [];
} finally {
clearTimeout(timeout);
}
```
How can I resolve this? If you propose a fix, please make it concise.| "401": { | ||
| "description": "Unauthorized \u2014 missing or invalid API token" | ||
| } |
There was a problem hiding this comment.
401 response missing body schema
The 400 response is fully documented with a JSON:API error schema and example, but the 401 response only carries a description string with no content entry. API consumers generating client code or running type-safe validation will see an untyped 401. For consistency with the rest of the spec, consider adding a minimal schema:
"401": {
"description": "Unauthorized — missing or invalid API token",
"content": {
"application/vnd.api+json": {
"schema": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": { "type": "object", "properties": { "detail": { "type": "string" } } }
}
}
}
}
}
}Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/openapi.json
Line: 8517-8519
Comment:
`401` response missing body schema
The `400` response is fully documented with a JSON:API error schema and example, but the `401` response only carries a description string with no `content` entry. API consumers generating client code or running type-safe validation will see an untyped `401`. For consistency with the rest of the spec, consider adding a minimal schema:
```json
"401": {
"description": "Unauthorized — missing or invalid API token",
"content": {
"application/vnd.api+json": {
"schema": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": { "type": "object", "properties": { "detail": { "type": "string" } } }
}
}
}
}
}
}
```
How can I resolve this? If you propose a fix, please make it concise.
Additional Comments (1)
The new Add Prompt To Fix With AIThis is a comment left during a code review.
Path: docs/openapi.json
Line: 8524-8537
Comment:
`"Search"` tag not added to `x-tagGroups`
The new `/search` endpoint uses the tag `"Search"`, but the `x-tagGroups` array only lists the tags `"Shipments"`, `"Containers"`, `"Custom Field Definitions"`, `"Custom Field Options"`, `"Custom Fields"`, `"Tracking Requests"`, `"Webhooks"`, `"Webhook Notifications"`, and `"Metro Areas"`. Tools that respect `x-tagGroups` (e.g., Redoc, Stoplight) will not surface the `Search` endpoint under any named group — it would appear ungrouped or be hidden entirely.
Add `"Search"` to the `"End Points"` group:
```suggestion
"x-tagGroups": [
{
"name": "End Points",
"tags": [
"Shipments",
"Containers",
"Custom Field Definitions",
"Custom Field Options",
"Custom Fields",
"Tracking Requests",
"Search",
"Webhooks",
"Webhook Notifications",
"Metro Areas"
]
},
```
How can I resolve this? If you propose a fix, please make it concise. |
Documents the
GET /searchendpoint in the API reference docs.Changes
/searchGET endpoint with full schema, parameters, response examples, error codesDetails
query(required, string)websearch_to_tsquery+ ILIKE fallbackLinear: DEV-8837
Created by Trin 🥷
Greptile Summary
This PR documents the
GET /searchendpoint in the API reference, adding its OpenAPI spec entry, a Mintlify MDX page, and navigation support. It also ships a substantial OAuth 2.1 authentication layer for the hosted MCP endpoint: a newworkos-jwt.tsmodule for local RS256 JWT verification (with JWKS caching), a remote fallback via an internal principal endpoint, RFC-compliantWWW-Authenticatechallenge headers on all 401 responses, and updated MCP documentation covering the new dual-mode auth flow.Key observations:
/searchOpenAPI path is well-structured and consistent with existing JSON:API response shapes, but the"Search"tag is absent from thex-tagGroupsarray, which will leave the endpoint ungrouped in tools like Redoc or Stoplight.fetchJwksinpackages/mcp/src/auth/workos-jwt.tslacks a request timeout, unlikeverifyViaInternalPrincipalwhich enforces a 2-second abort. A slow or unreachable JWKS endpoint could stall the serverless function.401response on/searchis documented with a description only; adding a minimal body schema would keep it consistent with the400entry.sdks/typescript-sdk/src/client.tschange correctly handlesBearer-prefixed tokens passed asapiToken, which is needed for OAuth tokens forwarded from the MCP layer.The documentation additions are accurate and the MCP OAuth implementation is logically sound with good test coverage and proper fallback handling. Two small gaps should be addressed: the missing request timeout on
fetchJwksis a real reliability risk in a serverless environment, and the"Search"tag omission fromx-tagGroupsis a documentation completeness issue.Confidence Score: 4/5
fetchJwksis a real reliability risk in a serverless environment, and the"Search"tag omission fromx-tagGroupsis a documentation completeness issue that affects endpoint discoverability in OpenAPI tools.Sequence Diagram
sequenceDiagram participant Client participant MCP as api/mcp.ts participant WorkOS as workos-jwt.ts participant Internal as Internal Principal API participant T49API as Terminal49 API Client->>MCP: POST /mcp with Authorization Bearer token MCP->>MCP: extractAuthorizationToken → scheme detection alt No token present MCP-->>Client: 401 with WWW-Authenticate challenge else Token has three dot-segments (JWT-like bearer) MCP->>WorkOS: verifyWorkosJwt(token) WorkOS->>WorkOS: fetchJwks cached 10 minutes WorkOS->>WorkOS: verifySignature + validClaims alt Local verification succeeds WorkOS-->>MCP: VerifiedPayload authSource oauth_local MCP->>T49API: Forward with Bearer token T49API-->>MCP: API response MCP-->>Client: 200 MCP response else Local verification returns null WorkOS-->>MCP: null MCP->>Internal: POST token_principal with 2s timeout alt Remote verification active Internal-->>MCP: active true with user and account ids MCP->>T49API: Forward with Bearer token T49API-->>MCP: API response MCP-->>Client: 200 MCP response else Remote verification fails Internal-->>MCP: error or inactive MCP-->>Client: 401 with WWW-Authenticate challenge end end else Legacy token scheme or no dots MCP->>MCP: isMatchingClientSecret check alt Secret matches MCP->>T49API: Forward with configured API token T49API-->>MCP: API response MCP-->>Client: 200 MCP response else Mismatch MCP-->>Client: 401 with WWW-Authenticate challenge end endLast reviewed commit: 66f98f3