Commit f21a7a1
feat(ramp): AI-optimized Ramp actions for MCP (read + write) (#21725)
* feat(ramp): add AI-optimized read/write actions for MCP + eval-driven fixes
Adds 15 AI-optimized Ramp actions (users, transactions, spend limits,
departments, locations, spend programs, transfers) covering list, get, create,
update, and terminate. Iterated against the MCP eval suite
(pd-connect-eval-monster/evals/ramp_sandbox, which exercises these via the Ramp
demo API); suite green on Sonnet 5 (18/18, pass^2). Related to #21692.
- list-users / list-transactions / list-limits / list-spend-programs: return a
compact per-record projection by default + additive `fields` prop; raw
responses overflowed the agent context (25k+ chars) and got truncated. [new 0.0.1]
- list-* / get-*: pageSize bounded to the API's 2-100 range (was unbounded, so
page_size=1 and =1000 both 422'd); pagination behavior documented. [new 0.0.1]
- terminate-limit: POST /limits/{id}/deferred/termination with idempotency_key
(DELETE /limits/{id} returned 405). [new 0.0.1]
- get-* / update-* / create-*: worked examples + list-action cross-references
for reliable id discovery. [new 0.0.1]
- ramp.app.mjs: added the methods these actions call; removed an unused
transactionState prop definition.
App package.json bumped 0.2.2 -> 0.3.0 (minor: additive new actions).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(ramp): bump pre-existing actions and sources for shared-code change
The AI-optimized action set modifies shared ramp.app.mjs and common/constants.mjs,
so every component that imports them is rev'd per the Pipedream versioning standard:
- actions/create-user-invite: 0.0.3 -> 0.0.4
- actions/issue-virtual-card: 0.0.4 -> 0.0.5
- actions/upload-receipt: 0.1.3 -> 0.1.4
- sources/new-transaction-created: 0.0.2 -> 0.0.3
- sources/transaction-status-updated: 0.0.2 -> 0.0.3
- sources/transfer-payment-updated: 0.0.2 -> 0.0.3
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(ramp): apply code-review fixes to AI-optimized actions
Addresses PR review feedback (verified against the Ramp demo API before applying):
- update-user / update-limit: throw ConfigurationError when only the resource id
is given and every mutable field is undefined (no-op update guard).
- list-*: add an optional `start` pagination cursor and forward it; `start` is
Ramp's real cursor (it appears in each response's `page.next`). Verified paging.
- list-transactions: add `ALL` to the state enum (API-verified valid value) so
callers can request every transaction, including declined.
- create-department / create-location / update-limit: expand descriptions
(when-to-use, worked examples, partial-update semantics, entity optionality).
- get-*/update-*/terminate-limit/create-location: add concrete UUID examples to
id-style prop descriptions while keeping their source action.
Skipped (with reasons): moving pageSize/fields into shared propDefinitions
(optional refactor, `fields` varies per resource); UNBUNDLED_* list-users roles
(API rejects them with 422 — current ROLES enum works); PATCH /funds/{id} for
update-limit (/funds requires a funds:read scope the client lacks -> 403; the
existing PATCH /limits/{id} works and is eval-covered).
Suite re-verified 18/18 on Sonnet 5 (evals/ramp_sandbox).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(ramp): DRY list props + fix update-limit restriction schema
Second round of PR-review fixes (both verified against the Ramp demo API):
- Shared pagination/field props: moved pageSize, start, and fields into
ramp.app.mjs propDefinitions and referenced them from all 7 list actions via
propDefinition (fields keeps its per-resource description override). No behavior
change; removes the duplicated inline definitions.
- update-limit: corrected the spending-restriction contract. The API requires
spending_restrictions.limit.{amount,currency_code} plus spending_restrictions.
interval (verified: the previous flat {interval, {amount,currency}} body 422s;
the nested body returns 200, and limit+interval are required together). Replaced
the free-form spendingRestrictions object and top-level interval with amount +
currencyCode + interval inputs; rename (display_name only) still works. Guards
reject an amount-without-interval (or vice-versa) and a no-op update.
Suite re-verified 18/18 on Sonnet 5 (evals/ramp_sandbox; eval 11 is model-choice
flaky on page size and passes 2/2 on re-run).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(ramp): reject currency code without a full spending restriction in update-limit
Follow-up review fix: currencyCode was only consumed when both amount and
interval were provided, so passing it otherwise (e.g. display name + currency)
silently dropped it. Add a ConfigurationError guard rejecting currencyCode
unless both amount and interval are present. Rename path unaffected (eval 16
passes 2/2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(ramp): add status filter options to list-users
Add the four Ramp user-status enum values (USER_ACTIVE, USER_DRAFT,
USER_INACTIVE, USER_SUSPENDED) as a USER_STATUSES constant and wire them to the
list-users `status` prop as selectable options, with an example in the
description. API-verified: all four are accepted by GET /users?status=; an
unknown value returns 422.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(ramp): consolidate shared props into propDefinitions (PR review)
Addresses maintainer review comments on shared-prop reuse and ID formatting:
- Add a `name` propDefinition to ramp.app.mjs; reference it from create-department
and create-location (with per-action example overrides) instead of duplicating
the inline schema.
- Reference the existing departmentId/locationId/role propDefinitions from
list-transactions, list-users, and update-user (they were redefined inline,
unlike create-user-invite which already referenced them). Component-specific
descriptions are kept as overrides.
- Put the UUID format + a concrete example into the departmentId/locationId
descriptions (both the shared propDefinitions and the filter-action overrides)
so callers pass an ID, not a department/location name.
- Drop the now-unused constants import from update-user.
Suite re-verified 18/18 on Sonnet 5 (evals/ramp_sandbox).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(ramp): move spend-limit reads/writes to the documented /funds endpoints
The limit list/get/update/terminate actions targeted the undocumented /limits
surface. With funds:read/funds:write scopes granted, switch them to Ramp's
documented Funds API (spend limits are served by /developer/v1/funds):
- listLimits -> GET /funds
- getLimit -> GET /funds/{id}
- updateLimit -> PATCH /funds/{id} (same nested spending_restrictions body)
- terminateLimit -> DELETE /funds/{id} (synchronous; the old undocumented
/limits/{id}/deferred/termination is replaced, so terminate-limit no longer
sends an idempotency_key and its description reflects immediate termination)
createLimit stays on /limits/deferred: it is the deferred-create used only by
the pre-existing issue-virtual-card action (out of scope), and the documented
POST /funds is a different, direct-create operation.
User-facing naming stays "Limits" (Ramp's product term and the more discoverable
name); "funds" is the API path only. Verified against the live demo API: /funds
list/get/patch/delete all 200, same page/data + start-cursor pagination, same
2-100 page_size bound, compact-projection fields all present. Updated the
list-limits `fields` example to the /funds field names (members,
spending_restrictions). Suite 18/18 on Sonnet 5.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(ramp): sharpen update-limit currency validation + list-departments example
Addresses PR review comments:
- update-limit: reject a blank currencyCode with ConfigurationError before the
API call (an omitted currency is still allowed and defaults to USD), and build
the limit with nullish defaulting (`currencyCode ?? "USD"`) so an explicit
value is preserved and only an omitted one defaults.
- list-departments: show both id and name in the returned-record example using a
concrete department UUID, so the id can be passed to Update User.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: vetrivigneshwaran <vicky@pipedream.com>1 parent ea0e712 commit f21a7a1
25 files changed
Lines changed: 965 additions & 17 deletions
File tree
- components/ramp
- actions
- create-department
- create-location
- create-user-invite
- get-limit
- get-transaction
- get-user
- issue-virtual-card
- list-departments
- list-limits
- list-locations
- list-spend-programs
- list-transactions
- list-transfers
- list-users
- terminate-limit
- update-limit
- update-user
- upload-receipt
- common
- sources
- new-transaction-created
- transaction-status-updated
- transfer-payment-updated
Lines changed: 34 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
Lines changed: 41 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
Lines changed: 30 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
Lines changed: 40 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
Lines changed: 40 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
0 commit comments