Skip to content

feat: add Stripe connector - #35

Closed
sdhilip200 wants to merge 2 commits into
cabinetai:mainfrom
sdhilip200:feat/stripe-connector
Closed

feat: add Stripe connector#35
sdhilip200 wants to merge 2 commits into
cabinetai:mainfrom
sdhilip200:feat/stripe-connector

Conversation

@sdhilip200

@sdhilip200 sdhilip200 commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Adds a Stripe connector that pulls revenue, subscription health, and payment operations metrics from the Stripe REST API and writes a daily markdown report to data/reports/.

  • server/connectors/stripe.ts — fetches charges, refunds, balance transactions, subscriptions, products, disputes, and payouts across a rolling 14-day window; renders a three-section report (Revenue Snapshot, Subscription Health, Payment Operations) with auto-generated insights including failure-spike detection
  • server/connectors/README.md — adds the general connector pattern documentation and full Stripe setup, env vars, and troubleshooting reference
  • server/connectors/stripe-sample-output.md — example output with sanitized data
  • data/.agents/stripe/ — Stripe Reporter agent with a daily 07:00 cron job
  • .env.example — STRIPE_SECRET_KEY and optional window override vars
  • .gitignore — whitelist data/.agents/stripe/ for tracking

Tested end-to-end with a synthetic data fixture covering revenue aggregation, MRR normalization, operations rollups, and insights generation. All edge case validation paths exercised locally (missing creds, invalid date format, mismatched date range, lookback out of range).

Summary by CodeRabbit

  • New Features

    • Stripe financial reporting connector generates daily reports tracking revenue, subscription metrics, and payment operations.
    • Reports automatically appear in the knowledge base, making data searchable and available as context for other agents.
    • Flexible configuration supports custom date ranges or rolling lookback periods.
  • Documentation

    • Added comprehensive connector documentation describing architecture and integration patterns.

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a36242bc-6e0c-4fd7-8208-b789c1aa87b3

📥 Commits

Reviewing files that changed from the base of the PR and between 59f68bb and c4c4470.

📒 Files selected for processing (1)
  • .env.example
🚧 Files skipped from review as they are similar to previous changes (1)
  • .env.example

📝 Walkthrough

Walkthrough

This PR introduces a new Stripe connector that integrates with Cabinet's agent framework to fetch daily revenue, subscription, and payment operation metrics from Stripe and generate markdown reports. It includes the connector script, configuration variables, agent scheduling, persona definition, comprehensive documentation, and example output.

Changes

Stripe Connector Integration

Layer / File(s) Summary
Stripe API credentials and date-range configuration
\.env.example
Required STRIPE_SECRET_KEY and optional date-range window controls (STRIPE_START_DATE, STRIPE_END_DATE, STRIPE_LOOKBACK_DAYS) are documented with defaults and validation constraints.
Connector implementation
server/connectors/stripe.ts
Standalone TypeScript script fetches charges, refunds, subscriptions, disputes, and payouts from Stripe REST API with cursor-based pagination and retry logic. Aggregates revenue (gross, refunds, fees, net, AOV), subscription health (MRR/ARR, churn, trials), and payment operations (failed charges, disputes, method mix, payouts), then renders a markdown report with revenue snapshots, day-by-day breakdown, subscription metrics, and actionable insights.
Agent scheduling and persona
data/.agents/stripe/jobs/daily-report.yaml, data/.agents/stripe/persona.md
Daily cron job (07:00 UTC) executes the connector script via claude-code provider with 300-second timeout; job verifies report generation on success and outputs errors on failure. Agent persona registers "Stripe Reporter" in finance department, describing its role and execution frequency.
Documentation and reference examples
server/connectors/README.md, server/connectors/stripe-sample-output.md
Comprehensive guide defining Cabinet Connectors architecture, onboarding checklist for new connectors (environment setup, hygiene, persona, job config), behavioral requirements (pagination guards, currency handling, fail-fast validation), and Stripe-specific specification (report sections, date-window rules, manual/scheduled execution, error cases, limitations). Sample output demonstrates report structure across revenue, subscription, and payment operations sections with insight highlights.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A bunny named Stripe hops through the code,
Collecting revenue down the financial road,
With subscriptions and payouts in markdown display,
Daily reports dance in Cabinet's cabaret,
Finance now flows where the agents play! 💰

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 32.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add Stripe connector' is concise, specific, and directly summarizes the main change—the addition of a Stripe connector across multiple files and configurations.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
server/connectors/stripe.ts (1)

477-494: Document the approximation constants.

The weekly (4.33) and daily (30) multipliers are reasonable approximations but could benefit from a brief inline comment explaining the rationale for future maintainers.

📝 Suggested comment
 function normalizeToMonthly(
   unitAmount: number,
   quantity: number,
   interval: "day" | "week" | "month" | "year",
   intervalCount: number
 ): number {
   const gross = unitAmount * quantity;
   switch (interval) {
     case "month":
       return gross / intervalCount;
     case "year":
       return gross / (12 * intervalCount);
     case "week":
+      // ~4.33 weeks per month (52 weeks / 12 months)
       return (gross * 4.33) / intervalCount;
     case "day":
+      // ~30 days per month (simplified)
       return (gross * 30) / intervalCount;
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/connectors/stripe.ts` around lines 477 - 494, Update the
normalizeToMonthly function to document the approximation constants used for
weekly and daily conversions: add concise inline comments by the cases for
"week" and "day" explaining that 4.33 represents average weeks per month (52
weeks / 12 months) and 30 represents an average days-per-month approximation, so
future maintainers understand the basis and limitations of these multipliers in
normalizeToMonthly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/connectors/README.md`:
- Around line 99-101: The MD028 warning is caused by the blank line between the
two blockquote paragraphs; edit the README content where the blockquotes start
with "**Test mode is strongly recommended**" and "**Never commit
`.env.local`.**" and remove the empty line so they are merged into a single
continuous blockquote (or alternatively convert each to a regular paragraph) to
satisfy markdownlint.

In `@server/connectors/stripe.ts`:
- Around line 717-724: The current computation of needsResponse and
disputesNeedingAttention only filters openDisputes for status ===
"needs_response", but Stripe also uses "warning_needs_response"; update the
filter in the needsResponse variable to include both statuses (e.g., check
d.status === "needs_response" || d.status === "warning_needs_response") so
disputesNeedingAttention correctly counts and sums amounts for both cases; refer
to openDisputes, needsResponse, and disputesNeedingAttention when making this
change (fetchAllOpenDisputes already returns both statuses).

---

Nitpick comments:
In `@server/connectors/stripe.ts`:
- Around line 477-494: Update the normalizeToMonthly function to document the
approximation constants used for weekly and daily conversions: add concise
inline comments by the cases for "week" and "day" explaining that 4.33
represents average weeks per month (52 weeks / 12 months) and 30 represents an
average days-per-month approximation, so future maintainers understand the basis
and limitations of these multipliers in normalizeToMonthly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 264e9f1f-acea-433b-8e24-968542c3d29e

📥 Commits

Reviewing files that changed from the base of the PR and between 8ba467c and 531fbb7.

📒 Files selected for processing (8)
  • .env.example
  • .gitignore
  • PROGRESS.md
  • data/.agents/stripe/jobs/daily-report.yaml
  • data/.agents/stripe/persona.md
  • server/connectors/README.md
  • server/connectors/stripe-sample-output.md
  • server/connectors/stripe.ts

Comment on lines +99 to +101
> **Test mode is strongly recommended** for development. Stripe's test mode is a parallel-universe view of your account with fake money and test customers — completely isolated from live data. You can build and validate the connector without risk, then swap to a `rk_live_` key once ready for production.

> **Never commit `.env.local`.** It's gitignored by default, but always double-check before pushing — `git status` should never show it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor: Remove blank line inside blockquote to fix markdownlint warning.

The blank line between blockquotes (lines 99-101) triggers MD028. Merge them into a single blockquote or use regular paragraphs.

📝 Proposed fix
-> **Test mode is strongly recommended** for development. Stripe's test mode is a parallel-universe view of your account with fake money and test customers — completely isolated from live data. You can build and validate the connector without risk, then swap to a `rk_live_` key once ready for production.
-
-> **Never commit `.env.local`.** It's gitignored by default, but always double-check before pushing — `git status` should never show it.
+> **Test mode is strongly recommended** for development. Stripe's test mode is a parallel-universe view of your account with fake money and test customers — completely isolated from live data. You can build and validate the connector without risk, then swap to a `rk_live_` key once ready for production.
+>
+> **Never commit `.env.local`.** It's gitignored by default, but always double-check before pushing — `git status` should never show it.
🧰 Tools
🪛 markdownlint-cli2 (0.22.0)

[warning] 100-100: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/connectors/README.md` around lines 99 - 101, The MD028 warning is
caused by the blank line between the two blockquote paragraphs; edit the README
content where the blockquotes start with "**Test mode is strongly recommended**"
and "**Never commit `.env.local`.**" and remove the empty line so they are
merged into a single continuous blockquote (or alternatively convert each to a
regular paragraph) to satisfy markdownlint.

Comment thread server/connectors/stripe.ts Outdated
Adds a Stripe connector that pulls revenue, subscription health, and payment
operations metrics from the Stripe REST API and writes a daily markdown report
to data/reports/.

- server/connectors/stripe.ts — fetches charges, refunds, balance transactions,
  subscriptions, products, disputes, and payouts across a rolling 14-day window;
  renders a three-section report (Revenue Snapshot, Subscription Health, Payment
  Operations) with auto-generated insights including failure-spike detection
- server/connectors/README.md — adds the general connector pattern documentation
  and full Stripe setup, env vars, and troubleshooting reference
- server/connectors/stripe-sample-output.md — example output with sanitized data
- data/.agents/stripe/ — Stripe Reporter agent with a daily 07:00 cron job
- .env.example — STRIPE_SECRET_KEY and optional window override vars
- .gitignore — whitelist data/.agents/stripe/ for tracking

Tested end-to-end with a synthetic data fixture covering revenue aggregation,
MRR normalization, operations rollups, and insights generation. All edge case
validation paths exercised locally (missing creds, invalid date format,
mismatched date range, lookback out of range).
@sdhilip200
sdhilip200 force-pushed the feat/stripe-connector branch from 531fbb7 to 59f68bb Compare April 11, 2026 10:30
@sdhilip2

Copy link
Copy Markdown

Thanks for the review @coderabbitai! Pushed 59f68bb with the following:

  • Dispute filter bugdisputesNeedingAttention now includes both needs_response and warning_needs_response statuses, since fetchAllOpenDisputes already returns both. Real bug catch.
  • Magic number documentation — added inline comments to normalizeToMonthly explaining the 4.33 (52÷12) and 30 (avg days/month) constants.
  • Markdown blockquote MD028 — merged the two adjacent blockquotes in README.md into one.

Not addressing the docstring coverage warning (32.26% vs 80% threshold): the existing connector pattern in this repo (see server/connectors/meta-ads.ts in #30) follows a minimal-comment style — top-of-file header block + section comments, no per-function docstrings. Adding per-function docstrings here would create style drift from the established pattern. Happy to revisit if @hilash wants the connector style to change repo-wide.

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@sdhilip2 Thanks for the detailed update!

  • Dispute filter — good catch on warning_needs_response; the fix correctly aligns the attention filter with what fetchAllOpenDisputes actually returns.
  • Magic number documentation — the inline comments on 4.33 (52÷12) and 30 (avg days/month) in normalizeToMonthly make the intent clear without ceremony.
  • MD028 blockquote merge — noted.

On docstring coverage: your rationale is sound. If server/connectors/meta-ads.ts sets the established pattern for connectors in this repo (top-of-file header + section comments, no per-function docstrings), enforcing 80% docstring coverage here would be inconsistent. I'll remember this style convention for future connector reviews.


✏️ Learnings added
Learnt from: sdhilip2
URL: https://github.com/hilash/cabinet/pull/35

Timestamp: 2026-04-11T10:30:40.233Z
Learning: In the `hilash/cabinet` repository, connector scripts under `server/connectors/` (e.g., `stripe.ts`, `meta-ads.ts`) follow a minimal-comment style: a top-of-file header block and section comments are used, but per-function docstrings are intentionally omitted. Do not flag low docstring coverage for files in this directory, as it would conflict with the established connector pattern.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
server/connectors/README.md (1)

99-101: ⚠️ Potential issue | 🟡 Minor

Duplicate: MD028 markdownlint warning still present.

The blank line inside the blockquote (line 100) triggers the MD028 warning. This was previously flagged but not yet fixed.

📝 Proposed fix (same as previous review)
-> **Test mode is strongly recommended** for development. Stripe's test mode is a parallel-universe view of your account with fake money and test customers — completely isolated from live data. You can build and validate the connector without risk, then swap to a `rk_live_` key once ready for production.
-
-> **Never commit `.env.local`.** It's gitignored by default, but always double-check before pushing — `git status` should never show it.
+> **Test mode is strongly recommended** for development. Stripe's test mode is a parallel-universe view of your account with fake money and test customers — completely isolated from live data. You can build and validate the connector without risk, then swap to a `rk_live_` key once ready for production.
+>
+> **Never commit `.env.local`.** It's gitignored by default, but always double-check before pushing — `git status` should never show it.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/connectors/README.md` around lines 99 - 101, Remove the stray blank
line inside the blockquote in server/connectors/README.md that causes the MD028
warning by merging the two paragraph lines into a single continuous blockquote;
specifically, edit the blockquote containing "Test mode is strongly recommended"
and "Never commit `.env.local`." so there is no empty line between them
(preserve wording and Markdown blockquote characters).
🧹 Nitpick comments (1)
server/connectors/README.md (1)

126-126: Consider clarifying the timezone for the scheduled report.

"07:00 server time" is ambiguous for distributed teams. Consider specifying the timezone (e.g., UTC, local system time) or referencing the system's default timezone behavior.

🕐 Suggested clarification
-The `data/.agents/stripe/jobs/daily-report.yaml` job runs the connector every day at **07:00 server time** via the Cabinet job scheduler. The schedule lands the report in your knowledge base before the start of the workday.
+The `data/.agents/stripe/jobs/daily-report.yaml` job runs the connector every day at **07:00** (in the server's local timezone) via the Cabinet job scheduler. The schedule lands the report in your knowledge base before the start of the workday.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/connectors/README.md` at line 126, Update the README sentence about
the scheduled job to remove ambiguity by explicitly stating the timezone used
for "07:00 server time" (for example: "07:00 UTC" or "07:00 system local time
(see system timezone)"). Reference the specific job file name
data/.agents/stripe/jobs/daily-report.yaml and either state that the schedule
uses the system's default timezone or show how to override it (e.g., mention
changing the server timezone or the job scheduler configuration). Ensure the
sentence now clearly tells readers which timezone is intended and where to
change it if they need a different one.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@server/connectors/README.md`:
- Around line 99-101: Remove the stray blank line inside the blockquote in
server/connectors/README.md that causes the MD028 warning by merging the two
paragraph lines into a single continuous blockquote; specifically, edit the
blockquote containing "Test mode is strongly recommended" and "Never commit
`.env.local`." so there is no empty line between them (preserve wording and
Markdown blockquote characters).

---

Nitpick comments:
In `@server/connectors/README.md`:
- Line 126: Update the README sentence about the scheduled job to remove
ambiguity by explicitly stating the timezone used for "07:00 server time" (for
example: "07:00 UTC" or "07:00 system local time (see system timezone)").
Reference the specific job file name data/.agents/stripe/jobs/daily-report.yaml
and either state that the schedule uses the system's default timezone or show
how to override it (e.g., mention changing the server timezone or the job
scheduler configuration). Ensure the sentence now clearly tells readers which
timezone is intended and where to change it if they need a different one.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 147de362-9733-4c42-acb2-1cca672ca7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 531fbb7 and 59f68bb.

📒 Files selected for processing (8)
  • .env.example
  • .gitignore
  • PROGRESS.md
  • data/.agents/stripe/jobs/daily-report.yaml
  • data/.agents/stripe/persona.md
  • server/connectors/README.md
  • server/connectors/stripe-sample-output.md
  • server/connectors/stripe.ts
✅ Files skipped from review due to trivial changes (4)
  • .gitignore
  • data/.agents/stripe/persona.md
  • server/connectors/stripe-sample-output.md
  • .env.example
🚧 Files skipped from review as they are similar to previous changes (3)
  • data/.agents/stripe/jobs/daily-report.yaml
  • PROGRESS.md
  • server/connectors/stripe.ts

pasogott pushed a commit to pasogott/cabinet that referenced this pull request May 2, 2026
cabinetai#35 — archive lane was collapsed by default, hiding overnight runs
behind a vertical rail. Defaulted the persisted collapsed-lanes set
to empty so archive expands on first load. Lane caps to ARCHIVE_PEEK
(8) items with a "Show N more →" affordance — header still shows the
full count.

cabinetai#36 — agent filter row sat below the header as a 12-pill scroller,
adding a second filter row before the kanban. Replaced with an
AgentFilterDropdown that lives inline in the header beside the
trigger chips. Single-select preserved; FilterBar kept as a
deprecated alias for the rename.
# Conflicts:
#	.env.example
#	.gitignore
#	PROGRESS.md
@oxedom

oxedom commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Thanks for this, @sdhilip200 — and sorry it sat unreviewed for so long. I'm going to close it, but the reason is on us, not on the code: Cabinet already ships a Stripe integration, and it's wired to Stripe's official MCP server. It's just invisible, so there was no way for you to know.

The entry has been in the MCP catalog the whole time:

const STRIPE: CatalogEntry = {
id: "stripe",
label: "Stripe",
blurb: "Query payments, customers, and invoices — and take action.",
iconSlug: "stripe",
bgImage: "/integrations/stripe-bg.webp",
logo: "/logos/stripe.svg",
sourceUrl: "https://docs.stripe.com/mcp",
registryId: "stripe",
trustTier: "official",
authBackend: "cli-pkce",
transport: "http",
mcpServerName: "cabinet-stripe",
url: "https://mcp.stripe.com",
credentials: [],
actions: [
"Search customers, payments & invoices",
"Create payment links & invoices",
"Issue refunds",
"Read balances & disputes",
],
setupSteps: [
{
title: "Sign in with Stripe",
body: "Click Connect & sign in — your agent's CLI opens Stripe in the browser and authorizes access (scoped by a restricted key under the hood).",
},
],
};

That points at https://mcp.stripe.com — Stripe's official remote MCP server — with trustTier: "official" and authBackend: "cli-pkce", so the user signs in through Stripe's own OAuth and permissions are scoped by a Stripe Restricted API Key. No secret ever lands in our config.

The reason you couldn't see it in the UI is a hand-maintained launch gate:

// Launch gate: only these connectors are live right now. Everything else is
// shown grayed-out + unclickable with a "Soon" badge, even if it already has
// an MCP catalog entry. Widen this set (or drop it back to the CONNECTABLE
// derivation below) as connectors are ready to ship.
const LAUNCHED = new Set([
"telegram",
"discord",
"google-drive",
"gmail",
"google-workspace",
"google-calendar",
"microsoft-365",
"microsoft-teams",
"onedrive",
"sharepoint",
"notion",
"slack",
"snowflake",
]);

implemented is computed as connectable && LAUNCHED.has(id). Stripe is connectable (CONNECTABLE is derived straight from MCP_CATALOG), but it isn't in LAUNCHED, so the card renders dimmed with a "Soon" badge. Adding "stripe" to that set is the entire remaining work — which makes this a one-line change on our side, and unfortunately makes the 1,043-line server/connectors/stripe.ts here redundant.

There's a deeper architectural mismatch worth naming, because it explains why this wasn't a near-miss. Cabinet has no in-process tool loop. Agents are spawned as external CLIs (Claude Code, Codex, Gemini, Cursor), and the CLI is the MCP client — so an integration isn't a module we call, it's a server entry we write into the CLI's own config. This PR introduces a server/connectors/ directory that doesn't exist on main; there's no code path that would ever have invoked it. That's a gap in our docs, not a mistake you made.

Genuinely sorry for the wasted effort. If you're still up for contributing, two things here are real and unclaimed:

@oxedom oxedom closed this Jul 13, 2026
@sdhilip200

Copy link
Copy Markdown
Contributor Author

Thanks for the guidance. I opened #230 for the issue #198 path instead of continuing the Stripe-specific approach.

This PR keeps unwired integrations in the request-only flow, but shows MCP catalog-wired integrations as connectable beta entries and adds a basic connection status signal in the hub.

Validation:

  • npm run lint
  • npx tsc --noEmit
  • npm run build

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants