mcp --http: SSE keepalive for long tool calls; public App Store search shares one 20-a-minute budget
This commit is contained in:
parent
c500866295
commit
9620768897
6 changed files with 65 additions and 4 deletions
|
|
@ -190,7 +190,19 @@ export function lintListing(store: 'apple' | 'play', fields: Record<string, unkn
|
|||
|
||||
interface ItunesApp { trackId?: number; trackName?: string; sellerName?: string; averageUserRating?: number; userRatingCount?: number; primaryGenreName?: string }
|
||||
|
||||
// Apple allows about 20 search calls a minute per IP: one shared budget for the whole server, whoever asks
|
||||
const SEARCH_PER_MIN = 20;
|
||||
const searchTimes: number[] = [];
|
||||
export function searchBudget(now = Date.now()): { ok: true } | { ok: false; retryAfter: number } {
|
||||
while (searchTimes.length && searchTimes[0]! <= now - 60_000) searchTimes.shift();
|
||||
if (searchTimes.length >= SEARCH_PER_MIN) return { ok: false, retryAfter: Math.ceil((searchTimes[0]! + 60_000 - now) / 1000) };
|
||||
searchTimes.push(now);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
export async function searchApps(term: string, country: string, limit: number, base: string, f: typeof fetch): Promise<{ results: Record<string, unknown>[] }> {
|
||||
const b = searchBudget();
|
||||
if (!b.ok) throw new Error(`the App Store search is busy (Apple allows ${SEARCH_PER_MIN} calls a minute for this server): try again in ${b.retryAfter} s`);
|
||||
const url = `${base}${base.includes('?') ? '&' : '?'}${new URLSearchParams({ term, country: country.toLowerCase(), media: 'software', entity: 'software', limit: String(limit) })}`;
|
||||
const r = await f(url, { signal: AbortSignal.timeout(10_000), headers: { accept: 'application/json' } });
|
||||
if (!r.ok) throw new Error(`the App Store search answered ${r.status}`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue