@usefillo/mcp 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -98,14 +98,18 @@ the named scope. With both, the login token wins — a key has no acting human.
98
98
  | Destinations | `fillo_get_integration`, `fillo_enable_integration`, `fillo_disable_integration`, `fillo_list_connections`, `fillo_select_connection`, `fillo_disconnect_integration`, `fillo_remove_connection_account`, `fillo_rename_discord_channel`, `fillo_hubspot_properties`, `fillo_hubspot_pipelines` | `integrations:manage` |
99
99
  | Responses and delivery | `fillo_list_held_responses`, `fillo_release_responses`, `fillo_delete_response`, `fillo_delivery_status`, `fillo_retry_deliveries`, `fillo_redeliver_responses`, `fillo_list_drafts`, `fillo_form_insights`, `fillo_list_respondents`, `fillo_delete_respondent` | `responses:manage`, `respondents:*`; `fillo_form_insights` needs `forms:read` **and** `responses:read` |
100
100
  | Webhooks | `fillo_list_webhooks`, `fillo_add_webhook`, `fillo_update_webhook`, `fillo_remove_webhook` | `webhooks:manage` |
101
- | Workspace | `fillo_rename_workspace`, `fillo_rename_project`, `fillo_get_branding`, `fillo_set_branding`, `fillo_list_members`, `fillo_invite_member`, `fillo_change_member_role`, `fillo_remove_member` | `workspace:manage`, `members:manage` |
101
+ | Workspace | `fillo_rename_workspace`, `fillo_rename_project`, `fillo_get_branding`, `fillo_set_branding`, `fillo_get_billing`, `fillo_list_members`, `fillo_invite_member`, `fillo_change_member_role`, `fillo_remove_member` | `workspace:manage`, `members:manage` |
102
102
  | Credentials | `fillo_list_tokens`, `fillo_revoke_token`, `fillo_list_sync_tokens`, `fillo_create_sync_token`, `fillo_revoke_sync_token`, `fillo_list_api_keys`, `fillo_revoke_api_key`, `fillo_list_agents`, `fillo_revoke_agent` | `workspace:manage` |
103
103
  | Developer settings | `fillo_get_code_sync_policy`, `fillo_set_code_sync_policy`, `fillo_get_origins`, `fillo_set_origins`, `fillo_identity_status`, `fillo_enable_identity`, `fillo_disable_identity` | `workspace:manage` |
104
104
 
105
105
  `fillo_delete_form`, `fillo_get_branding`, `fillo_set_branding`,
106
- `fillo_list_api_keys`, and `fillo_revoke_api_key` need a login token — there is
107
- no project-API-key route for them, so a leaked key can never enumerate or revoke
108
- the workspace's credentials. `fillo_delete_response` needs one too, for a
106
+ `fillo_get_billing`, `fillo_list_api_keys`, and `fillo_revoke_api_key` need a
107
+ login token — there is no project-API-key route for them, so a leaked key can
108
+ never enumerate or revoke the workspace's credentials or read its plan.
109
+ `fillo_get_billing` is read-only: it reports the plan and this month's usage and
110
+ returns the Settings link, but no tool can subscribe, change the plan, start a
111
+ trial, or open checkout — an owner or admin does that in Settings → Billing &
112
+ plan. `fillo_delete_response` needs one too, for a
109
113
  different reason: its scoped route takes no typed confirmation, so on a project
110
114
  API key the confirmation would be checked only by the caller, which is no
111
115
  confirmation at all.
package/dist/index.js CHANGED
@@ -2523,6 +2523,7 @@ function registerWorkspaceAdmin(server) {
2523
2523
  registerRenameProject(server);
2524
2524
  registerGetBranding(server);
2525
2525
  registerSetBranding(server);
2526
+ registerGetBilling(server);
2526
2527
  registerListMembers(server);
2527
2528
  registerInviteMember(server);
2528
2529
  registerSetMemberRole(server);
@@ -2656,6 +2657,64 @@ function registerSetBranding(server) {
2656
2657
  }
2657
2658
  );
2658
2659
  }
2660
+ var LONG_DATE = new Intl.DateTimeFormat("en-GB", {
2661
+ day: "numeric",
2662
+ month: "long",
2663
+ year: "numeric",
2664
+ timeZone: "UTC"
2665
+ });
2666
+ var COUNT = new Intl.NumberFormat("en-US");
2667
+ function isoDate(value) {
2668
+ if (typeof value !== "string") return null;
2669
+ const date = new Date(value);
2670
+ return Number.isNaN(date.getTime()) ? null : LONG_DATE.format(date);
2671
+ }
2672
+ function billingSummary(json) {
2673
+ const tier = typeof json?.tier === "string" ? `Everything ${json.tier}` : "Everything";
2674
+ const plan = json?.plan === "free" ? "Free" : json?.plan === "trial" ? `${tier} trial` : json?.plan === "complimentary" ? `${tier}, complimentary` : json?.plan === "subscribed" ? `${tier}, billed ${json.interval === "year" ? "yearly" : "monthly"}` : "Plan unknown";
2675
+ const parts = [plan];
2676
+ const usage = json?.usage;
2677
+ if (typeof usage?.responses === "number" && typeof json?.allowance === "number") {
2678
+ parts.push(
2679
+ `${COUNT.format(usage.responses)} of ${COUNT.format(json.allowance)} responses this month`
2680
+ );
2681
+ }
2682
+ const periodEnd = isoDate(json?.currentPeriodEnd);
2683
+ const trialEnd = isoDate(json?.trialEndsAt);
2684
+ if (json?.plan === "subscribed" && json.status === "past_due") {
2685
+ parts.push("the last payment failed; Stripe is retrying");
2686
+ } else if (json?.plan === "subscribed" && periodEnd) {
2687
+ parts.push(json.cancelAtPeriodEnd ? `cancels ${periodEnd}` : `renews ${periodEnd}`);
2688
+ } else if (json?.plan === "trial" && trialEnd) {
2689
+ parts.push(`trial ends ${trialEnd}`);
2690
+ }
2691
+ const manageUrl = typeof json?.manageUrl === "string" && /^https?:\/\//u.test(json.manageUrl) ? `: ${json.manageUrl}` : "";
2692
+ return `${parts.join(" \xB7 ")}. Plan changes are made by an owner or admin in Settings \u2192 Billing & plan${manageUrl}`;
2693
+ }
2694
+ function registerGetBilling(server) {
2695
+ server.registerTool(
2696
+ "fillo_get_billing",
2697
+ {
2698
+ title: "Read the workspace's plan and usage",
2699
+ description: "Report the workspace's plan (Free, trial, complimentary, or an Everything volume and billing period), this month's response count against its allowance, recent monthly usage, and the Settings link where an owner or admin changes the plan. Read-only: no tool can subscribe, change the plan, start a trial, or open checkout \u2014 report the numbers and hand the human manageUrl. Needs a LOGIN TOKEN \u2014 billing has no project-API-key route.",
2700
+ inputSchema: {},
2701
+ annotations: READ_ONLY
2702
+ },
2703
+ async () => {
2704
+ const lane = resolveLane();
2705
+ if (!lane) return noCredential("(login token only)");
2706
+ if (lane.kind !== "cli") return LOGIN_ONLY("Reading the plan and usage");
2707
+ const res = await laneFetch(lane, { path: "/workspace/billing" });
2708
+ const problem = laneProblem(lane, res, {
2709
+ scope: "(login token only)",
2710
+ fallback: "Couldn't read the plan and usage",
2711
+ missing: "This Fillo server doesn't report billing yet. Open Settings \u2192 Billing & plan to see the plan and usage."
2712
+ });
2713
+ if (problem) return problem;
2714
+ return ok(billingSummary(res.json), res.json);
2715
+ }
2716
+ );
2717
+ }
2659
2718
  function registerInviteMember(server) {
2660
2719
  server.registerTool(
2661
2720
  "fillo_invite_member",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usefillo/mcp",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "mcpName": "io.github.jacobfunch/usefillo",
5
5
  "description": "Fillo MCP server — provision, scaffold, publish, and query forms from your coding agent.",
6
6
  "license": "MIT",