kaax-mcp 0.1.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 +274 -0
- package/dist/client.d.ts +118 -0
- package/dist/client.js +308 -0
- package/dist/client.js.map +1 -0
- package/dist/convert.d.ts +23 -0
- package/dist/convert.js +192 -0
- package/dist/convert.js.map +1 -0
- package/dist/i18n.d.ts +64 -0
- package/dist/i18n.js +98 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +106 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +37 -0
- package/dist/platform.js +72 -0
- package/dist/platform.js.map +1 -0
- package/dist/prompts.d.ts +12 -0
- package/dist/prompts.js +185 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +17 -0
- package/dist/resources.js +305 -0
- package/dist/resources.js.map +1 -0
- package/dist/spatial.d.ts +51 -0
- package/dist/spatial.js +152 -0
- package/dist/spatial.js.map +1 -0
- package/dist/tools.d.ts +19 -0
- package/dist/tools.js +926 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +203 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Kaax MCP server
|
|
2
|
+
|
|
3
|
+
Connect any [MCP](https://modelcontextprotocol.io)-aware agent — Claude
|
|
4
|
+
Desktop, Claude Code, Cursor, Windsurf, Zed — to your Kaax account so it can
|
|
5
|
+
query your analyses, suggest tag taxonomies, recommend advanced
|
|
6
|
+
configurations, find similar fields across your history, aggregate density
|
|
7
|
+
statistics, and convert shapefiles to KML — all locally, with your own API
|
|
8
|
+
key.
|
|
9
|
+
|
|
10
|
+
## What you get
|
|
11
|
+
|
|
12
|
+
**Full onboarding from inside the agent** — no Kaax account required to start:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
kaax_start_onboarding → browser opens at /sign-up?onboardToken=…
|
|
16
|
+
user fills the form (password stays in the browser)
|
|
17
|
+
page binds the new account to the token
|
|
18
|
+
|
|
19
|
+
kaax_complete_onboarding(token) → polls server, returns apiKey ONCE
|
|
20
|
+
late-binds it on the in-process client
|
|
21
|
+
|
|
22
|
+
kaax_request_download → server-side HubSpot form submission
|
|
23
|
+
kaax_check_download_status → poll for admin approval
|
|
24
|
+
kaax_download_kaax → stream the binary to disk
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**21 tools**, split by tier:
|
|
28
|
+
|
|
29
|
+
- **Free** (no Pro subscription needed): onboarding, license check, billing
|
|
30
|
+
page opener, download flow, shapefile conversion, tag/config suggestions,
|
|
31
|
+
parameter docs.
|
|
32
|
+
- **Pro** (subscription required): everything that reads or writes data on
|
|
33
|
+
your Kaax account (analyses, fields, models, tags, density stats, peer
|
|
34
|
+
configs, similarity search). Free users get a localized "necesitás Pro"
|
|
35
|
+
message + the upgrade URL instead of an error.
|
|
36
|
+
|
|
37
|
+
The agent should **call `kaax_check_license` first** if it doesn't already
|
|
38
|
+
know the user's plan — every Pro tool tagged its description with `[Pro]`
|
|
39
|
+
so the agent can read intent from the schema.
|
|
40
|
+
|
|
41
|
+
The full list:
|
|
42
|
+
|
|
43
|
+
| Tool | Tier | What it does |
|
|
44
|
+
| --------------------------------- | ----- | -------------------------------------------------- |
|
|
45
|
+
| `kaax_start_onboarding` | Free | Open browser at signup with a single-use 15-min token |
|
|
46
|
+
| `kaax_complete_onboarding` | Free | Poll for binding; returns the apiKey once on success |
|
|
47
|
+
| `kaax_check_license` | Free | Show plan, capabilities, upgrade URL |
|
|
48
|
+
| `kaax_open_billing` | Free | Open the plans page in the user's browser |
|
|
49
|
+
| `kaax_request_download` | Free | Submit the HubSpot form for desktop apps |
|
|
50
|
+
| `kaax_check_download_status` | Free | Poll for approval; returns binary URLs on success |
|
|
51
|
+
| `kaax_download_kaax` | Free | Stream a binary to disk (no buffering) |
|
|
52
|
+
| `kaax_suggest_tags_for_field` | Free | Heuristic tag set for a new parcel |
|
|
53
|
+
| `kaax_suggest_configuration` | Free | Curated configuration preset per analysis type |
|
|
54
|
+
| `kaax_explain_advanced_config` | Free | Plain-language docs per parameter |
|
|
55
|
+
| `kaax_convert_shapefile_to_kml` | Free | Local .shp → .kml conversion (no GDAL needed) |
|
|
56
|
+
| `kaax_check_setup_status` | Pro | Snapshot of fields, models, configs, analyses, tags |
|
|
57
|
+
| `kaax_list_analyses` | Pro | Paginated, filterable list of analyses (v0) |
|
|
58
|
+
| `kaax_get_analysis` | Pro | Full detail for a single analysis |
|
|
59
|
+
| `kaax_list_fields` | Pro | Fields — name, tags, geometry flag (v2) |
|
|
60
|
+
| `kaax_list_models` | Pro | Detection models you've uploaded (v2) |
|
|
61
|
+
| `kaax_list_tags` | Pro | Tags in use with frequencies |
|
|
62
|
+
| `kaax_attach_field_tags` | Pro | Persist tags to a field (v2) |
|
|
63
|
+
| `kaax_peer_config_suggestions` | Pro | Anonymised, privacy-preserving crowd average (v2) |
|
|
64
|
+
| `kaax_find_similar_fields` | Pro | Cosine + geo similarity over your history |
|
|
65
|
+
| `kaax_get_density_stats` | Pro | Total area, detections/ha, mean rates |
|
|
66
|
+
|
|
67
|
+
**7 docs** the agent can `resources/read`:
|
|
68
|
+
|
|
69
|
+
- `kaax://docs/quickstart` — 30-minute zero-to-first-analysis walkthrough
|
|
70
|
+
- `kaax://docs/tags` — 4-axis taxonomy & normalisation rules
|
|
71
|
+
- `kaax://docs/configurations` — parameter cheat sheet
|
|
72
|
+
- `kaax://docs/shapefile-import` — .shp → .kml constraints
|
|
73
|
+
- `kaax://docs/models` — when and how to upload detection models
|
|
74
|
+
- `kaax://docs/density-stats` — what every metric means
|
|
75
|
+
- `kaax://docs/security` — what the MCP server does (and doesn't) send
|
|
76
|
+
|
|
77
|
+
**5 guided prompts** to seed common conversations:
|
|
78
|
+
|
|
79
|
+
- `kaax_onboard_from_zero` — full signup → activate → download flow (no account needed)
|
|
80
|
+
- `kaax_quickstart` — orient an existing user
|
|
81
|
+
- `kaax_analyze_field` — queue an analysis end-to-end
|
|
82
|
+
- `kaax_organize_data` — audit and clean up tags
|
|
83
|
+
- `kaax_import_shapefile` — convert + upload .shp parcels
|
|
84
|
+
|
|
85
|
+
## Install
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/Ahau-x/Kaax-LandingPage.git
|
|
89
|
+
cd Kaax-LandingPage/mcp
|
|
90
|
+
npm install
|
|
91
|
+
npm run build
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The build emits a runnable `dist/index.js` you can invoke directly via
|
|
95
|
+
`node dist/index.js` or — once published — `npx -y @kaax/mcp-server`.
|
|
96
|
+
|
|
97
|
+
## Configure
|
|
98
|
+
|
|
99
|
+
**Two paths:**
|
|
100
|
+
|
|
101
|
+
1. **You already have a Kaax account** — get an API key at
|
|
102
|
+
<https://www.kaax-agritech.com/dashboard/api-manage> (Pro plan or higher)
|
|
103
|
+
and set it as `KAAX_API_KEY` in your MCP client config.
|
|
104
|
+
2. **You're starting from zero** — just install the MCP without an
|
|
105
|
+
`KAAX_API_KEY` env var. Tell the agent "onboard me" and it will run
|
|
106
|
+
`kaax_start_onboarding`, which opens your browser at the signup form.
|
|
107
|
+
Once you submit, `kaax_complete_onboarding` retrieves the apiKey and
|
|
108
|
+
binds it to the session. Save the key from the tool output so you don't
|
|
109
|
+
have to onboard again next time.
|
|
110
|
+
|
|
111
|
+
### Claude Desktop
|
|
112
|
+
|
|
113
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` on
|
|
114
|
+
macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows:
|
|
115
|
+
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"mcpServers": {
|
|
119
|
+
"kaax": {
|
|
120
|
+
"command": "node",
|
|
121
|
+
"args": ["C:/path/to/Kaax-LandingPage/mcp/dist/index.js"],
|
|
122
|
+
"env": {
|
|
123
|
+
"KAAX_API_KEY": "your_api_key_here"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Restart Claude Desktop. The Kaax tools appear in the tool picker.
|
|
131
|
+
|
|
132
|
+
### Claude Code
|
|
133
|
+
|
|
134
|
+
Add to `.mcp.json` at the root of any project (or `~/.claude/mcp.json` for
|
|
135
|
+
all projects):
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"kaax": {
|
|
141
|
+
"command": "node",
|
|
142
|
+
"args": ["/absolute/path/to/Kaax-LandingPage/mcp/dist/index.js"],
|
|
143
|
+
"env": { "KAAX_API_KEY": "your_api_key_here" }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Cursor
|
|
150
|
+
|
|
151
|
+
`Settings → MCP → Add new MCP server`. Use the same `command` / `args` /
|
|
152
|
+
`env` shape as above.
|
|
153
|
+
|
|
154
|
+
### Windsurf
|
|
155
|
+
|
|
156
|
+
`Settings → Cascade → MCP Servers → Add new`. Same payload.
|
|
157
|
+
|
|
158
|
+
### Zed
|
|
159
|
+
|
|
160
|
+
Add to `~/.config/zed/settings.json`:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"context_servers": {
|
|
165
|
+
"kaax": {
|
|
166
|
+
"command": { "path": "node", "args": ["…/mcp/dist/index.js"] },
|
|
167
|
+
"env": { "KAAX_API_KEY": "your_api_key_here" }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Free vs Pro tier
|
|
174
|
+
|
|
175
|
+
The MCP works without a paid subscription — onboarding, downloading the
|
|
176
|
+
desktop apps, converting shapefiles and getting tag/config suggestions all
|
|
177
|
+
run on the Free tier. Tools that read or write account data (analyses,
|
|
178
|
+
fields, models, etc.) are tagged `[Pro]` in their descriptions; calling
|
|
179
|
+
one from a Free account returns a localized "necesitás Pro" message with
|
|
180
|
+
the upgrade URL instead of failing with a raw 403.
|
|
181
|
+
|
|
182
|
+
The agent should run `kaax_check_license` first when the user wants to do
|
|
183
|
+
anything beyond onboarding — that's a single cheap call that tells it
|
|
184
|
+
exactly what's available. Free-tier limits (5 fields, 1 local model,
|
|
185
|
+
3 custom configs, no API access) are enforced server-side; the MCP just
|
|
186
|
+
gives clearer messages than the raw 403.
|
|
187
|
+
|
|
188
|
+
## Language (KAAX_LOCALE)
|
|
189
|
+
|
|
190
|
+
User-facing strings default to **Spanish** because that's Kaax's primary
|
|
191
|
+
market. Set `KAAX_LOCALE=en` in your MCP client env to switch to English:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
"env": {
|
|
195
|
+
"KAAX_API_KEY": "…",
|
|
196
|
+
"KAAX_LOCALE": "en"
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The agent (Claude) translates the rest fluently on its own, so even
|
|
201
|
+
without setting `KAAX_LOCALE` you can chat in either language and the
|
|
202
|
+
user-facing answers will be in your language. The env var only affects
|
|
203
|
+
the small set of stub messages that the LLM tends to copy verbatim (URLs,
|
|
204
|
+
error codes, "this requires Pro").
|
|
205
|
+
|
|
206
|
+
## Override the base URL (private deployments only)
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
"env": {
|
|
210
|
+
"KAAX_API_KEY": "…",
|
|
211
|
+
"KAAX_BASE_URL": "https://kaax.acme-internal.com"
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Security
|
|
216
|
+
|
|
217
|
+
Read [`kaax://docs/security`](src/resources.ts) from inside the MCP itself,
|
|
218
|
+
or the short version below:
|
|
219
|
+
|
|
220
|
+
- API key read from `KAAX_API_KEY` once, never logged, sent only over HTTPS.
|
|
221
|
+
- Every API call is scoped to the api-key owner — the server cannot fetch
|
|
222
|
+
other users' data.
|
|
223
|
+
- `kaax_peer_config_suggestions` is the only tool that touches anonymised
|
|
224
|
+
aggregate data; the server endpoint enforces a minimum sample size, excludes
|
|
225
|
+
the caller, and rounds numeric values into natural quanta so a single
|
|
226
|
+
contributor cannot be re-identified.
|
|
227
|
+
- All write endpoints (`kaax_attach_field_tags`, anything creating data) are
|
|
228
|
+
rate-limited server-side (30/min/key) and audit-logged.
|
|
229
|
+
- Shapefile conversion is local file I/O — your .shp never leaves your
|
|
230
|
+
machine.
|
|
231
|
+
|
|
232
|
+
## Develop
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run dev # tsx watch on src/index.ts
|
|
236
|
+
npm run build # tsc → dist/
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Type-check only: `npx tsc --noEmit`.
|
|
240
|
+
|
|
241
|
+
## Architecture
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
mcp/src/
|
|
245
|
+
├── index.ts stdio bootstrap — wires tools, resources, prompts
|
|
246
|
+
├── client.ts HTTP wrapper + standalone onboarding helpers
|
|
247
|
+
├── tools.ts 19 callable tools
|
|
248
|
+
├── resources.ts 7 markdown docs served as MCP resources
|
|
249
|
+
├── prompts.ts 5 guided conversation starters
|
|
250
|
+
├── spatial.ts Haversine, KML centroid, cosine, density aggregation
|
|
251
|
+
├── convert.ts shapefile → KML in pure JS (no GDAL)
|
|
252
|
+
├── platform.ts openBrowser + streaming file download (no extra deps)
|
|
253
|
+
└── types.ts shared types for v0, v2 and landing shapes
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Performance & resource use
|
|
257
|
+
|
|
258
|
+
The MCP is engineered to stay light:
|
|
259
|
+
|
|
260
|
+
- **Stateless tools** — no in-process caches that could grow unbounded.
|
|
261
|
+
- **HTTP only** — the MCP never opens a Mongo / Redis / S3 client. All DB
|
|
262
|
+
access stays on the Kaax server, which already pools connections at
|
|
263
|
+
`maxPoolSize: 5` per instance with the shared `dbConnect()` cache.
|
|
264
|
+
- **Bounded polling** — `kaax_complete_onboarding` and
|
|
265
|
+
`kaax_check_download_status` use exponential back-off with a hard wall
|
|
266
|
+
(15 min for signup, configurable for downloads). They never spin.
|
|
267
|
+
- **Streamed downloads** — `kaax_download_kaax` pipes the response body
|
|
268
|
+
directly to disk; binaries never live in memory.
|
|
269
|
+
- **Detached child processes** — `openBrowser` spawns + `unref`s the
|
|
270
|
+
browser so the MCP exits cleanly even if you leave the browser open.
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
MIT — see [LICENSE](../LICENSE).
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client wrapping the public Kaax v0 API.
|
|
3
|
+
*
|
|
4
|
+
* The MCP server runs locally on the user's machine and talks to Kaax over
|
|
5
|
+
* HTTPS using the API key that lives at `/dashboard/api-manage`. We use
|
|
6
|
+
* `undici.fetch` for the small footprint and Node 18+ compatibility.
|
|
7
|
+
*/
|
|
8
|
+
import type { AccountOverview, AnalysesFilters, AnalysesPage, AnalysisType, DownloadStatusResponse, IssueOnboardingTokenResponse, OnboardingStatus, RequestDownloadResponse, V2FieldsPage, V2ModelsList, V2PeerSuggestion, V2SetupStatus, V2TagsList } from "./types.js";
|
|
9
|
+
/**
|
|
10
|
+
* POST /api/landing/onboarding-token — issue a 15-minute single-use token.
|
|
11
|
+
*
|
|
12
|
+
* The MCP server uses this at the very start of the browser-handoff signup
|
|
13
|
+
* flow. Returns the opaque token + a hint URL the MCP can `openBrowser` on.
|
|
14
|
+
*/
|
|
15
|
+
export declare function issueOnboardingToken(baseUrl?: string, source?: "mcp" | "landing-cli" | "other"): Promise<IssueOnboardingTokenResponse>;
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/landing/onboarding-status?token=… — single poll of the binding
|
|
18
|
+
* state. Callers (e.g. `pollOnboardingUntilBound`) loop on this with their
|
|
19
|
+
* own bounded back-off.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fetchOnboardingStatus(token: string, baseUrl?: string): Promise<OnboardingStatus>;
|
|
22
|
+
/**
|
|
23
|
+
* Bounded polling — increasing back-off, hard ceiling on total elapsed time.
|
|
24
|
+
* Returns the first non-`pending` response. Designed so a stuck MCP can
|
|
25
|
+
* never hammer the server: cap of ~120 polls over 15 minutes.
|
|
26
|
+
*/
|
|
27
|
+
export declare function pollOnboardingUntilBound(token: string, opts?: {
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
maxWaitMs?: number;
|
|
30
|
+
initialDelayMs?: number;
|
|
31
|
+
maxDelayMs?: number;
|
|
32
|
+
onTick?: (state: OnboardingStatus, attempt: number) => void;
|
|
33
|
+
}): Promise<OnboardingStatus>;
|
|
34
|
+
export declare class KaaxAPIError extends Error {
|
|
35
|
+
status?: number | undefined;
|
|
36
|
+
body?: string | undefined;
|
|
37
|
+
constructor(message: string, status?: number | undefined, body?: string | undefined);
|
|
38
|
+
}
|
|
39
|
+
export interface KaaxClientOptions {
|
|
40
|
+
/** Optional — if absent, only the onboarding helpers work. */
|
|
41
|
+
apiKey?: string;
|
|
42
|
+
baseUrl?: string;
|
|
43
|
+
/** Timeout in milliseconds. Defaults to 30s. */
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
}
|
|
46
|
+
export declare class KaaxClient {
|
|
47
|
+
/** May be undefined while the user has not finished onboarding yet. */
|
|
48
|
+
private apiKey;
|
|
49
|
+
readonly baseUrl: string;
|
|
50
|
+
private readonly timeoutMs;
|
|
51
|
+
constructor(opts?: KaaxClientOptions);
|
|
52
|
+
/** True iff the client has an apiKey and can hit authenticated endpoints. */
|
|
53
|
+
hasApiKey(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Late-bind an apiKey acquired via the onboarding flow. The new key is
|
|
56
|
+
* used for every subsequent request without restarting the MCP.
|
|
57
|
+
*/
|
|
58
|
+
setApiKey(apiKey: string): void;
|
|
59
|
+
private requireKey;
|
|
60
|
+
/**
|
|
61
|
+
* `POST /api/v0/analyses` — the single public endpoint.
|
|
62
|
+
* Filters go in the JSON body; pagination as query params.
|
|
63
|
+
*/
|
|
64
|
+
listAnalyses(filters?: AnalysesFilters): Promise<AnalysesPage>;
|
|
65
|
+
/**
|
|
66
|
+
* Pulls *every* analysis page (up to a safety cap) and concatenates them.
|
|
67
|
+
* Useful for aggregates / heuristics — never on hot UI paths.
|
|
68
|
+
*/
|
|
69
|
+
listAllAnalyses(filters?: Omit<AnalysesFilters, "page" | "limit">, opts?: {
|
|
70
|
+
maxPages?: number;
|
|
71
|
+
pageSize?: number;
|
|
72
|
+
}): Promise<AnalysesPage>;
|
|
73
|
+
/** GET /api/v2/setup-status — snapshot of fields, models, configs, tags. */
|
|
74
|
+
setupStatus(): Promise<V2SetupStatus | null>;
|
|
75
|
+
/** GET /api/v2/fields — paginated, filterable list of the user's fields. */
|
|
76
|
+
listFields(params?: {
|
|
77
|
+
tag?: string;
|
|
78
|
+
type?: AnalysisType;
|
|
79
|
+
q?: string;
|
|
80
|
+
page?: number;
|
|
81
|
+
limit?: number;
|
|
82
|
+
}): Promise<V2FieldsPage | null>;
|
|
83
|
+
/** GET /api/v2/models — every detection model owned by the caller. */
|
|
84
|
+
listModels(): Promise<V2ModelsList | null>;
|
|
85
|
+
/** GET /api/v2/tags — tag dictionary with usage counts. */
|
|
86
|
+
listTagsV2(): Promise<V2TagsList | null>;
|
|
87
|
+
/** POST /api/v2/tags — append a tag to the user dictionary. */
|
|
88
|
+
createTag(tag: string): Promise<{
|
|
89
|
+
tag: string;
|
|
90
|
+
created: boolean;
|
|
91
|
+
} | null>;
|
|
92
|
+
/** POST /api/v2/fields/:id/tags — attach tags to a field. */
|
|
93
|
+
attachFieldTags(fieldId: string, tags: string[]): Promise<{
|
|
94
|
+
fieldId: string;
|
|
95
|
+
tags: string[];
|
|
96
|
+
} | null>;
|
|
97
|
+
/** GET /api/v2/peer-config-suggestions?type=… — anonymised peer averages. */
|
|
98
|
+
peerSuggestions(type: AnalysisType): Promise<V2PeerSuggestion | null>;
|
|
99
|
+
/** POST /api/landing/request-download — submit the HubSpot form server-side. */
|
|
100
|
+
requestDownload(body: {
|
|
101
|
+
useCase?: string;
|
|
102
|
+
company?: string;
|
|
103
|
+
locale?: "en" | "es" | "zh";
|
|
104
|
+
}): Promise<RequestDownloadResponse>;
|
|
105
|
+
/** GET /api/landing/download-status — returns status + binary URLs on approval. */
|
|
106
|
+
downloadStatus(): Promise<DownloadStatusResponse>;
|
|
107
|
+
private overviewCache;
|
|
108
|
+
private static readonly OVERVIEW_TTL_MS;
|
|
109
|
+
/** GET /api/landing/account-overview — plan + limits + capabilities. */
|
|
110
|
+
accountOverview(force?: boolean): Promise<AccountOverview>;
|
|
111
|
+
/** Invalidate the overview cache — call after a successful upgrade. */
|
|
112
|
+
invalidateOverview(): void;
|
|
113
|
+
/** Helper — GET that returns `null` on 404 / network errors. */
|
|
114
|
+
private tryGet;
|
|
115
|
+
/** Helper — POST that returns `null` on 404. */
|
|
116
|
+
private tryPost;
|
|
117
|
+
private request;
|
|
118
|
+
}
|