@blen/fedreg-mcp-server 2.0.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/CHANGELOG.md +125 -0
- package/LICENSE +202 -0
- package/NOTICE +15 -0
- package/README.md +219 -0
- package/SECURITY.md +99 -0
- package/dist/auth/embedded.d.ts +2 -0
- package/dist/auth/embedded.d.ts.map +1 -0
- package/dist/auth/embedded.js +17 -0
- package/dist/auth/embedded.js.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +120 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/sandbox/deno.d.ts +13 -0
- package/dist/sandbox/deno.d.ts.map +1 -0
- package/dist/sandbox/deno.js +203 -0
- package/dist/sandbox/deno.js.map +1 -0
- package/dist/sandbox/index.d.ts +20 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +46 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/isolate.d.ts +7 -0
- package/dist/sandbox/isolate.d.ts.map +1 -0
- package/dist/sandbox/isolate.js +100 -0
- package/dist/sandbox/isolate.js.map +1 -0
- package/dist/sandbox/policy.d.ts +7 -0
- package/dist/sandbox/policy.d.ts.map +1 -0
- package/dist/sandbox/policy.js +70 -0
- package/dist/sandbox/policy.js.map +1 -0
- package/dist/sandbox/types.d.ts +41 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +2 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/sdk/bindings.d.ts +10 -0
- package/dist/sdk/bindings.d.ts.map +1 -0
- package/dist/sdk/bindings.js +15 -0
- package/dist/sdk/bindings.js.map +1 -0
- package/dist/sdk/ecfr-client.d.ts +61 -0
- package/dist/sdk/ecfr-client.d.ts.map +1 -0
- package/dist/sdk/ecfr-client.js +45 -0
- package/dist/sdk/ecfr-client.js.map +1 -0
- package/dist/sdk/fr-client.d.ts +81 -0
- package/dist/sdk/fr-client.d.ts.map +1 -0
- package/dist/sdk/fr-client.js +77 -0
- package/dist/sdk/fr-client.js.map +1 -0
- package/dist/sdk/regs-client.d.ts +34 -0
- package/dist/sdk/regs-client.d.ts.map +1 -0
- package/dist/sdk/regs-client.js +44 -0
- package/dist/sdk/regs-client.js.map +1 -0
- package/dist/sdk/runtime.d.ts +21 -0
- package/dist/sdk/runtime.d.ts.map +1 -0
- package/dist/sdk/runtime.js +31 -0
- package/dist/sdk/runtime.js.map +1 -0
- package/dist/sdk/sources/corpus-loader.d.ts +6 -0
- package/dist/sdk/sources/corpus-loader.d.ts.map +1 -0
- package/dist/sdk/sources/corpus-loader.js +9 -0
- package/dist/sdk/sources/corpus-loader.js.map +1 -0
- package/dist/sdk/sources/ecfr.d.ts +3 -0
- package/dist/sdk/sources/ecfr.d.ts.map +1 -0
- package/dist/sdk/sources/ecfr.js +12 -0
- package/dist/sdk/sources/ecfr.js.map +1 -0
- package/dist/sdk/sources/fr.d.ts +3 -0
- package/dist/sdk/sources/fr.d.ts.map +1 -0
- package/dist/sdk/sources/fr.js +12 -0
- package/dist/sdk/sources/fr.js.map +1 -0
- package/dist/sdk/sources/index.d.ts +7 -0
- package/dist/sdk/sources/index.d.ts.map +1 -0
- package/dist/sdk/sources/index.js +25 -0
- package/dist/sdk/sources/index.js.map +1 -0
- package/dist/sdk/sources/regs.d.ts +3 -0
- package/dist/sdk/sources/regs.d.ts.map +1 -0
- package/dist/sdk/sources/regs.js +24 -0
- package/dist/sdk/sources/regs.js.map +1 -0
- package/dist/sdk/sources/source.d.ts +32 -0
- package/dist/sdk/sources/source.d.ts.map +1 -0
- package/dist/sdk/sources/source.js +2 -0
- package/dist/sdk/sources/source.js.map +1 -0
- package/dist/search/bm25.d.ts +25 -0
- package/dist/search/bm25.d.ts.map +1 -0
- package/dist/search/bm25.js +67 -0
- package/dist/search/bm25.js.map +1 -0
- package/dist/search/corpus.d.ts +24 -0
- package/dist/search/corpus.d.ts.map +1 -0
- package/dist/search/corpus.js +23 -0
- package/dist/search/corpus.js.map +1 -0
- package/dist/server/authz.d.ts +18 -0
- package/dist/server/authz.d.ts.map +1 -0
- package/dist/server/authz.js +42 -0
- package/dist/server/authz.js.map +1 -0
- package/dist/server/http.d.ts +21 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +159 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/ipRateLimiter.d.ts +11 -0
- package/dist/server/ipRateLimiter.d.ts.map +1 -0
- package/dist/server/ipRateLimiter.js +27 -0
- package/dist/server/ipRateLimiter.js.map +1 -0
- package/dist/server/mcpServer.d.ts +15 -0
- package/dist/server/mcpServer.d.ts.map +1 -0
- package/dist/server/mcpServer.js +67 -0
- package/dist/server/mcpServer.js.map +1 -0
- package/dist/server/stdio.d.ts +3 -0
- package/dist/server/stdio.d.ts.map +1 -0
- package/dist/server/stdio.js +16 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/server/toolCatalog.d.ts +20 -0
- package/dist/server/toolCatalog.d.ts.map +1 -0
- package/dist/server/toolCatalog.js +29 -0
- package/dist/server/toolCatalog.js.map +1 -0
- package/dist/server/wellKnown.d.ts +16 -0
- package/dist/server/wellKnown.d.ts.map +1 -0
- package/dist/server/wellKnown.js +17 -0
- package/dist/server/wellKnown.js.map +1 -0
- package/dist/server/zodToJsonSchema.d.ts +7 -0
- package/dist/server/zodToJsonSchema.d.ts.map +1 -0
- package/dist/server/zodToJsonSchema.js +44 -0
- package/dist/server/zodToJsonSchema.js.map +1 -0
- package/dist/supervisor/index.d.ts +19 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +22 -0
- package/dist/supervisor/index.js.map +1 -0
- package/dist/tools/describeSchema.d.ts +35 -0
- package/dist/tools/describeSchema.d.ts.map +1 -0
- package/dist/tools/describeSchema.js +14 -0
- package/dist/tools/describeSchema.js.map +1 -0
- package/dist/tools/execute.d.ts +33 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +28 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/searchApi.d.ts +27 -0
- package/dist/tools/searchApi.d.ts.map +1 -0
- package/dist/tools/searchApi.js +14 -0
- package/dist/tools/searchApi.js.map +1 -0
- package/dist/util/httpClient.d.ts +46 -0
- package/dist/util/httpClient.d.ts.map +1 -0
- package/dist/util/httpClient.js +139 -0
- package/dist/util/httpClient.js.map +1 -0
- package/dist/util/logger.d.ts +7 -0
- package/dist/util/logger.d.ts.map +1 -0
- package/dist/util/logger.js +19 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/quotas.d.ts +13 -0
- package/dist/util/quotas.d.ts.map +1 -0
- package/dist/util/quotas.js +29 -0
- package/dist/util/quotas.js.map +1 -0
- package/dist/util/tokenBucket.d.ts +11 -0
- package/dist/util/tokenBucket.d.ts.map +1 -0
- package/dist/util/tokenBucket.js +30 -0
- package/dist/util/tokenBucket.js.map +1 -0
- package/package.json +95 -0
- package/schema/ecfr.json +148 -0
- package/schema/fr.json +194 -0
- package/schema/regs.json +67 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describeSchema.js","sourceRoot":"","sources":["../../src/tools/describeSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAoB,MAAM,qBAAqB,CAAC;AAE7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;IAC7G,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;CAC9F,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,2CAA2C,EAAE,CAAC,CAAC;AAOhH,MAAM,UAAU,cAAc,CAAC,KAA2B,EAAE,OAAiC;IAC3F,MAAM,IAAI,GAAG,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;IAC9H,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3K,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Sdk } from '../sdk/bindings.js';
|
|
3
|
+
import type { SandboxRunner } from '../sandbox/types.js';
|
|
4
|
+
import { SubjectQuota } from '../util/quotas.js';
|
|
5
|
+
export declare const ExecuteInput: z.ZodObject<{
|
|
6
|
+
code: z.ZodString;
|
|
7
|
+
timeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
8
|
+
memoryMb: z.ZodDefault<z.ZodNumber>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
code: string;
|
|
11
|
+
timeoutMs: number;
|
|
12
|
+
memoryMb: number;
|
|
13
|
+
}, {
|
|
14
|
+
code: string;
|
|
15
|
+
timeoutMs?: number | undefined;
|
|
16
|
+
memoryMb?: number | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export type ExecuteInputT = z.infer<typeof ExecuteInput>;
|
|
19
|
+
export interface ExecuteDeps {
|
|
20
|
+
sdk: Sdk;
|
|
21
|
+
sandbox: SandboxRunner;
|
|
22
|
+
regsMaxCallsPerExecute: number;
|
|
23
|
+
regsSubjectQuota: SubjectQuota;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Per-request context, re-derived from the caller's bearer token on every HTTP request.
|
|
27
|
+
* stdio has no subject.
|
|
28
|
+
*/
|
|
29
|
+
export interface RequestCtx {
|
|
30
|
+
subject?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function execute(input: ExecuteInputT, deps: ExecuteDeps, requestCtx?: RequestCtx): Promise<import("../index.js").ExecuteResult>;
|
|
33
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,eAAO,MAAM,YAAY;;;;;;;;;;;;EAIvB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAEzD,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,GAAG,CAAC;IACT,OAAO,EAAE,aAAa,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,YAAY,CAAC;CAChC;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,UAAU,gDAsB7F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { dispatch } from '../sdk/runtime.js';
|
|
3
|
+
export const ExecuteInput = z.object({
|
|
4
|
+
code: z.string().min(1).describe('TypeScript code to run inside the sandbox. SDK globals are bound per source (e.g. `fr`, `ecfr`, `regs`).'),
|
|
5
|
+
timeoutMs: z.number().int().min(100).max(60_000).default(15_000),
|
|
6
|
+
memoryMb: z.number().int().min(16).max(256).default(64),
|
|
7
|
+
});
|
|
8
|
+
export async function execute(input, deps, requestCtx) {
|
|
9
|
+
let regsCalls = 0;
|
|
10
|
+
return deps.sandbox.execute({ code: input.code, timeoutMs: input.timeoutMs, memoryMb: input.memoryMb, bindings: deps.sdk.registeredNames }, {
|
|
11
|
+
dispatch: (req) => {
|
|
12
|
+
if (req.binding === 'regs') {
|
|
13
|
+
if (regsCalls >= deps.regsMaxCallsPerExecute) {
|
|
14
|
+
return Promise.resolve({ ok: false, error: { name: 'RegsCallBudgetExceeded', message: `Exceeded the per-execute regulations.gov call budget (${deps.regsMaxCallsPerExecute}). Narrow your query or paginate across separate execute calls.` } });
|
|
15
|
+
}
|
|
16
|
+
if (requestCtx?.subject) {
|
|
17
|
+
const q = deps.regsSubjectQuota.consume(requestCtx.subject);
|
|
18
|
+
if (!q.allowed) {
|
|
19
|
+
return Promise.resolve({ ok: false, error: { name: 'RegsSubjectQuotaExceeded', message: `Per-subject regulations.gov quota exceeded. Try again after ${new Date(q.resetAt).toISOString()}.` } });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
regsCalls++;
|
|
23
|
+
}
|
|
24
|
+
return dispatch({ clients: deps.sdk.clients, meta: deps.sdk.meta }, req);
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0GAA0G,CAAC;IAC5I,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAChE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxD,CAAC,CAAC;AAmBH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAoB,EAAE,IAAiB,EAAE,UAAuB;IAC5F,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CACzB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,EAC9G;QACE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;YAChB,IAAI,GAAG,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;gBAC3B,IAAI,SAAS,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBAC7C,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,yDAAyD,IAAI,CAAC,sBAAsB,iEAAiE,EAAE,EAAE,CAAC,CAAC;gBACnP,CAAC;gBACD,IAAI,UAAU,EAAE,OAAO,EAAE,CAAC;oBACxB,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;oBAC5D,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;wBACf,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,+DAA+D,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;oBACnM,CAAC;gBACH,CAAC;gBACD,SAAS,EAAE,CAAC;YACd,CAAC;YACD,OAAO,QAAQ,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;QAC3E,CAAC;KACF,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Corpus } from '../search/corpus.js';
|
|
3
|
+
export declare const SearchApiInput: z.ZodObject<{
|
|
4
|
+
query: z.ZodString;
|
|
5
|
+
k: z.ZodDefault<z.ZodNumber>;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
query: string;
|
|
8
|
+
k: number;
|
|
9
|
+
}, {
|
|
10
|
+
query: string;
|
|
11
|
+
k?: number | undefined;
|
|
12
|
+
}>;
|
|
13
|
+
export type SearchApiInputT = z.infer<typeof SearchApiInput>;
|
|
14
|
+
export interface SearchHit {
|
|
15
|
+
id: string;
|
|
16
|
+
kind: 'endpoint' | 'field';
|
|
17
|
+
binding: string;
|
|
18
|
+
description: string;
|
|
19
|
+
signature?: string;
|
|
20
|
+
example?: string;
|
|
21
|
+
score: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function searchApi(input: SearchApiInputT, corpus: Corpus): {
|
|
24
|
+
hits: SearchHit[];
|
|
25
|
+
note: string;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=searchApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchApi.d.ts","sourceRoot":"","sources":["../../src/tools/searchApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,eAAO,MAAM,cAAc;;;;;;;;;EAGzB,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE7D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IACxD,WAAW,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;CAC1E;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAOrG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export const SearchApiInput = z.object({
|
|
3
|
+
query: z.string().min(1).describe('Free-text query over endpoint and field documentation across all bound sources (fr.*, ecfr.*, regs.*).'),
|
|
4
|
+
k: z.number().int().min(1).max(50).default(10).describe('Max number of results to return'),
|
|
5
|
+
});
|
|
6
|
+
export function searchApi(input, corpus) {
|
|
7
|
+
const scored = corpus.index.search(input.query, input.k);
|
|
8
|
+
const hits = scored.map(s => {
|
|
9
|
+
const e = corpus.entries.get(s.id);
|
|
10
|
+
return { id: e.id, kind: e.kind, binding: e.binding, description: e.description, signature: e.signature, example: e.example, score: Math.round(s.score * 1000) / 1000 };
|
|
11
|
+
});
|
|
12
|
+
return { hits, note: 'Use describe_schema with `path` for exact lookup or `prefix` to explore a namespace. Use execute to run TypeScript against the bound source globals.' };
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=searchApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"searchApi.js","sourceRoot":"","sources":["../../src/tools/searchApi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,wGAAwG,CAAC;IAC3I,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;CAC3F,CAAC,CAAC;AAQH,MAAM,UAAU,SAAS,CAAC,KAAsB,EAAE,MAAc;IAC9D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,IAAI,GAAgB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC;QACpC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC;IAC1K,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,sJAAsJ,EAAE,CAAC;AAChL,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Dispatcher } from 'undici';
|
|
2
|
+
export interface HttpClientOptions {
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
userAgent?: string;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
retries?: number;
|
|
7
|
+
cacheTtlMs?: number;
|
|
8
|
+
cacheMaxItems?: number;
|
|
9
|
+
dispatcher?: Dispatcher;
|
|
10
|
+
defaultHeaders?: Record<string, string>;
|
|
11
|
+
retry429?: boolean;
|
|
12
|
+
preflightLimiter?: {
|
|
13
|
+
tryTake(): boolean;
|
|
14
|
+
secondsUntilNext?(): number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface CallOptions {
|
|
18
|
+
method?: 'GET' | 'POST';
|
|
19
|
+
path: string;
|
|
20
|
+
query?: Record<string, string | number | boolean | string[] | undefined>;
|
|
21
|
+
headers?: Record<string, string>;
|
|
22
|
+
accept?: 'json' | 'xml' | 'text';
|
|
23
|
+
body?: unknown;
|
|
24
|
+
}
|
|
25
|
+
export declare class HttpClient {
|
|
26
|
+
#private;
|
|
27
|
+
private readonly cache;
|
|
28
|
+
private readonly cacheEnabled;
|
|
29
|
+
private readonly baseUrl;
|
|
30
|
+
private readonly userAgent;
|
|
31
|
+
private readonly timeoutMs;
|
|
32
|
+
private readonly retries;
|
|
33
|
+
private readonly retry429;
|
|
34
|
+
private readonly dispatcher?;
|
|
35
|
+
private readonly preflightLimiter?;
|
|
36
|
+
constructor(opts: HttpClientOptions);
|
|
37
|
+
call<T = unknown>(o: CallOptions): Promise<T>;
|
|
38
|
+
private cacheKey;
|
|
39
|
+
private buildUrl;
|
|
40
|
+
}
|
|
41
|
+
export declare class HttpError extends Error {
|
|
42
|
+
readonly status: number;
|
|
43
|
+
readonly bodySnippet: string;
|
|
44
|
+
constructor(message: string, status: number, bodySnippet: string);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=httpClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpClient.d.ts","sourceRoot":"","sources":["../../src/util/httpClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAKlD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE;QAAE,OAAO,IAAI,OAAO,CAAC;QAAC,gBAAgB,CAAC,IAAI,MAAM,CAAA;KAAE,CAAC;CACxE;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,qBAAa,UAAU;;IAErB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuF;IAC7G,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAsD;gBAE5E,IAAI,EAAE,iBAAiB;IAe7B,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAuEnD,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,QAAQ;CAajB;AAED,qBAAa,SAAU,SAAQ,KAAK;aACW,MAAM,EAAE,MAAM;aAAkB,WAAW,EAAE,MAAM;gBAApF,OAAO,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM,EAAkB,WAAW,EAAE,MAAM;CAIjG"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { request } from 'undici';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { log } from './logger.js';
|
|
5
|
+
export class HttpClient {
|
|
6
|
+
#defaultHeaders;
|
|
7
|
+
cache;
|
|
8
|
+
cacheEnabled;
|
|
9
|
+
baseUrl;
|
|
10
|
+
userAgent;
|
|
11
|
+
timeoutMs;
|
|
12
|
+
retries;
|
|
13
|
+
retry429;
|
|
14
|
+
dispatcher;
|
|
15
|
+
preflightLimiter;
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
this.#defaultHeaders = opts.defaultHeaders ?? {};
|
|
18
|
+
this.baseUrl = opts.baseUrl;
|
|
19
|
+
this.userAgent = opts.userAgent ?? 'fedreg-mcp-server/2.0 (+https://github.com/blen-labs/fedreg-mcp-server)';
|
|
20
|
+
this.timeoutMs = opts.timeoutMs ?? 20_000;
|
|
21
|
+
this.retries = opts.retries ?? 3;
|
|
22
|
+
this.retry429 = opts.retry429 ?? true;
|
|
23
|
+
this.dispatcher = opts.dispatcher;
|
|
24
|
+
this.preflightLimiter = opts.preflightLimiter;
|
|
25
|
+
const max = opts.cacheMaxItems ?? 2000;
|
|
26
|
+
const ttl = opts.cacheTtlMs ?? 300_000;
|
|
27
|
+
this.cacheEnabled = max > 0 && ttl > 0;
|
|
28
|
+
this.cache = new LRUCache({ max: Math.max(max, 1), ttl: Math.max(ttl, 1) });
|
|
29
|
+
}
|
|
30
|
+
async call(o) {
|
|
31
|
+
const url = this.buildUrl(o.path, o.query);
|
|
32
|
+
const method = o.method ?? 'GET';
|
|
33
|
+
const key = method === 'GET' && this.cacheEnabled ? this.cacheKey(url, o.headers) : '';
|
|
34
|
+
if (key && this.cache.has(key)) {
|
|
35
|
+
log.debug('http.cache_hit', { url });
|
|
36
|
+
return this.cache.get(key).body;
|
|
37
|
+
}
|
|
38
|
+
const accept = o.accept === 'xml' ? 'application/xml,text/xml'
|
|
39
|
+
: o.accept === 'text' ? 'text/plain'
|
|
40
|
+
: 'application/json';
|
|
41
|
+
if (this.preflightLimiter && !this.preflightLimiter.tryTake()) {
|
|
42
|
+
const wait = this.preflightLimiter.secondsUntilNext?.() ?? 0;
|
|
43
|
+
const err = new HttpError(`${method} ${url} -> upstream rate limit reached${Number.isFinite(wait) && wait > 0 ? ` (retry in ~${wait}s)` : ''}`, 429, '');
|
|
44
|
+
err.name = 'RegsRateLimited';
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
let attempt = 0;
|
|
48
|
+
let lastErr;
|
|
49
|
+
while (attempt <= this.retries) {
|
|
50
|
+
try {
|
|
51
|
+
const res = await request(url, {
|
|
52
|
+
method,
|
|
53
|
+
headers: {
|
|
54
|
+
'accept': accept,
|
|
55
|
+
'user-agent': this.userAgent,
|
|
56
|
+
...this.#defaultHeaders,
|
|
57
|
+
...(o.body ? { 'content-type': 'application/json' } : {}),
|
|
58
|
+
...(o.headers ?? {}),
|
|
59
|
+
},
|
|
60
|
+
body: o.body ? JSON.stringify(o.body) : undefined,
|
|
61
|
+
bodyTimeout: this.timeoutMs,
|
|
62
|
+
headersTimeout: this.timeoutMs,
|
|
63
|
+
...(this.dispatcher ? { dispatcher: this.dispatcher } : {}),
|
|
64
|
+
});
|
|
65
|
+
if (res.statusCode >= 400) {
|
|
66
|
+
const text = await res.body.text();
|
|
67
|
+
const err = new HttpError(`${method} ${url} -> ${res.statusCode}`, res.statusCode, text);
|
|
68
|
+
if (res.statusCode === 429) {
|
|
69
|
+
const retryAfter = Array.isArray(res.headers['retry-after']) ? res.headers['retry-after'][0] : res.headers['retry-after'];
|
|
70
|
+
err.name = 'RateLimited';
|
|
71
|
+
err.message = `${method} ${url} -> 429 Too Many Requests${retryAfter ? ` (retry-after ${retryAfter})` : ''}`;
|
|
72
|
+
}
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
let body;
|
|
76
|
+
if (accept.startsWith('application/json'))
|
|
77
|
+
body = await res.body.json();
|
|
78
|
+
else
|
|
79
|
+
body = await res.body.text();
|
|
80
|
+
const headers = {};
|
|
81
|
+
for (const [k, v] of Object.entries(res.headers))
|
|
82
|
+
headers[k] = Array.isArray(v) ? v.join(',') : String(v ?? '');
|
|
83
|
+
if (key)
|
|
84
|
+
this.cache.set(key, { status: res.statusCode, body, headers });
|
|
85
|
+
return body;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
lastErr = err;
|
|
89
|
+
const status = err instanceof HttpError ? err.status : 0;
|
|
90
|
+
const retryable = status === 0 || (status === 429 && this.retry429) || status >= 500;
|
|
91
|
+
if (!retryable || attempt === this.retries)
|
|
92
|
+
break;
|
|
93
|
+
const delay = Math.min(2 ** attempt * 250, 4000);
|
|
94
|
+
await new Promise(r => setTimeout(r, delay));
|
|
95
|
+
attempt++;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
throw lastErr;
|
|
99
|
+
}
|
|
100
|
+
cacheKey(url, perCallHeaders) {
|
|
101
|
+
const merged = { ...this.#defaultHeaders, ...(perCallHeaders ?? {}) };
|
|
102
|
+
const entries = Object.entries(merged);
|
|
103
|
+
if (entries.length === 0)
|
|
104
|
+
return url; // fr/ecfr: bare URL key, unchanged
|
|
105
|
+
const normalized = {};
|
|
106
|
+
for (const [k, v] of entries.sort(([a], [b]) => a.localeCompare(b)))
|
|
107
|
+
normalized[k.toLowerCase()] = v;
|
|
108
|
+
const hash = createHash('sha256').update(JSON.stringify(normalized)).digest('hex').slice(0, 16);
|
|
109
|
+
return `${url}\n${hash}`;
|
|
110
|
+
}
|
|
111
|
+
buildUrl(path, query) {
|
|
112
|
+
const base = this.baseUrl.replace(/\/$/, '');
|
|
113
|
+
const p = path.startsWith('/') ? path : '/' + path;
|
|
114
|
+
const url = new URL(base + p);
|
|
115
|
+
if (query) {
|
|
116
|
+
for (const [k, v] of Object.entries(query)) {
|
|
117
|
+
if (v === undefined || v === null)
|
|
118
|
+
continue;
|
|
119
|
+
if (Array.isArray(v))
|
|
120
|
+
for (const item of v)
|
|
121
|
+
url.searchParams.append(k, String(item));
|
|
122
|
+
else
|
|
123
|
+
url.searchParams.append(k, String(v));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return url.toString();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export class HttpError extends Error {
|
|
130
|
+
status;
|
|
131
|
+
bodySnippet;
|
|
132
|
+
constructor(message, status, bodySnippet) {
|
|
133
|
+
super(message);
|
|
134
|
+
this.status = status;
|
|
135
|
+
this.bodySnippet = bodySnippet;
|
|
136
|
+
this.name = 'HttpError';
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=httpClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../src/util/httpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const log: {
|
|
2
|
+
debug: (msg: string, extra?: Record<string, unknown>) => void;
|
|
3
|
+
info: (msg: string, extra?: Record<string, unknown>) => void;
|
|
4
|
+
warn: (msg: string, extra?: Record<string, unknown>) => void;
|
|
5
|
+
error: (msg: string, extra?: Record<string, unknown>) => void;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,GAAG;iBACD,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBACxC,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBACvC,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;iBACtC,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CACrD,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const order = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
2
|
+
function envLevel() {
|
|
3
|
+
const v = (process.env.FEDREG_LOG_LEVEL ?? 'info').toLowerCase();
|
|
4
|
+
return ['debug', 'info', 'warn', 'error'].includes(v) ? v : 'info';
|
|
5
|
+
}
|
|
6
|
+
export const log = {
|
|
7
|
+
debug: (msg, extra) => write('debug', msg, extra),
|
|
8
|
+
info: (msg, extra) => write('info', msg, extra),
|
|
9
|
+
warn: (msg, extra) => write('warn', msg, extra),
|
|
10
|
+
error: (msg, extra) => write('error', msg, extra),
|
|
11
|
+
};
|
|
12
|
+
function write(level, msg, extra) {
|
|
13
|
+
if (order[level] < order[envLevel()])
|
|
14
|
+
return;
|
|
15
|
+
const line = JSON.stringify({ t: new Date().toISOString(), level, msg, ...(extra ?? {}) });
|
|
16
|
+
// stdio transport reserves stdout for JSON-RPC; log to stderr.
|
|
17
|
+
process.stderr.write(line + '\n');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/util/logger.ts"],"names":[],"mappings":"AACA,MAAM,KAAK,GAA0B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAElF,SAAS,QAAQ;IACf,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACjE,OAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAa,CAAC,QAAQ,CAAC,CAAU,CAAC,CAAC,CAAC,CAAE,CAAW,CAAC,CAAC,CAAC,MAAM,CAAC;AACtG,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,KAAK,EAAE,CAAC,GAAW,EAAE,KAA+B,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;IACnF,IAAI,EAAE,CAAC,GAAW,EAAE,KAA+B,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC;IACjF,IAAI,EAAE,CAAC,GAAW,EAAE,KAA+B,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC;IACjF,KAAK,EAAE,CAAC,GAAW,EAAE,KAA+B,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;CACpF,CAAC;AAEF,SAAS,KAAK,CAAC,KAAY,EAAE,GAAW,EAAE,KAA+B;IACvE,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAAE,OAAO;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3F,+DAA+D;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class SubjectQuota {
|
|
2
|
+
private readonly limit;
|
|
3
|
+
private readonly windowMs;
|
|
4
|
+
private readonly counts;
|
|
5
|
+
constructor(limit: number, windowMs?: number);
|
|
6
|
+
/** Returns whether the subject may make one more request in the current window. */
|
|
7
|
+
consume(subject: string): {
|
|
8
|
+
allowed: boolean;
|
|
9
|
+
remaining: number;
|
|
10
|
+
resetAt: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=quotas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotas.d.ts","sourceRoot":"","sources":["../../src/util/quotas.ts"],"names":[],"mappings":"AAIA,qBAAa,YAAY;IAEX,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;IADrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuD;gBACjD,KAAK,EAAE,MAAM,EAAmB,QAAQ,GAAE,MAAe;IAItF,mFAAmF;IACnF,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAenF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { LRUCache } from 'lru-cache';
|
|
2
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
3
|
+
export class SubjectQuota {
|
|
4
|
+
limit;
|
|
5
|
+
windowMs;
|
|
6
|
+
counts;
|
|
7
|
+
constructor(limit, windowMs = DAY_MS) {
|
|
8
|
+
this.limit = limit;
|
|
9
|
+
this.windowMs = windowMs;
|
|
10
|
+
this.counts = new LRUCache({ max: 10_000, ttl: windowMs });
|
|
11
|
+
}
|
|
12
|
+
/** Returns whether the subject may make one more request in the current window. */
|
|
13
|
+
consume(subject) {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
const rec = this.counts.get(subject);
|
|
16
|
+
if (!rec || rec.resetAt < now) {
|
|
17
|
+
const resetAt = now + this.windowMs;
|
|
18
|
+
this.counts.set(subject, { count: 1, resetAt });
|
|
19
|
+
return { allowed: true, remaining: this.limit - 1, resetAt };
|
|
20
|
+
}
|
|
21
|
+
if (rec.count >= this.limit) {
|
|
22
|
+
return { allowed: false, remaining: 0, resetAt: rec.resetAt };
|
|
23
|
+
}
|
|
24
|
+
rec.count++;
|
|
25
|
+
this.counts.set(subject, rec);
|
|
26
|
+
return { allowed: true, remaining: this.limit - rec.count, resetAt: rec.resetAt };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=quotas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quotas.js","sourceRoot":"","sources":["../../src/util/quotas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnC,MAAM,OAAO,YAAY;IAEM;IAAgC;IAD5C,MAAM,CAAuD;IAC9E,YAA6B,KAAa,EAAmB,WAAmB,MAAM;QAAzD,UAAK,GAAL,KAAK,CAAQ;QAAmB,aAAQ,GAAR,QAAQ,CAAiB;QACpF,IAAI,CAAC,MAAM,GAAG,IAAI,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,mFAAmF;IACnF,OAAO,CAAC,OAAe;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC;QAC/D,CAAC;QACD,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAChE,CAAC;QACD,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACpF,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** In-memory token bucket. One instance = one shared limit (e.g. process-wide regs quota). */
|
|
2
|
+
export declare class TokenBucket {
|
|
3
|
+
private readonly ratePerSec;
|
|
4
|
+
private readonly burst;
|
|
5
|
+
private tokens;
|
|
6
|
+
private updatedAt;
|
|
7
|
+
constructor(ratePerSec: number, burst: number);
|
|
8
|
+
tryTake(): boolean;
|
|
9
|
+
secondsUntilNext(): number;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tokenBucket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenBucket.d.ts","sourceRoot":"","sources":["../../src/util/tokenBucket.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,qBAAa,WAAW;IAGV,OAAO,CAAC,QAAQ,CAAC,UAAU;IAAU,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFvE,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBACG,UAAU,EAAE,MAAM,EAAmB,KAAK,EAAE,MAAM;IAI/E,OAAO,IAAI,OAAO;IAQlB,gBAAgB,IAAI,MAAM;CAK3B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** In-memory token bucket. One instance = one shared limit (e.g. process-wide regs quota). */
|
|
2
|
+
export class TokenBucket {
|
|
3
|
+
ratePerSec;
|
|
4
|
+
burst;
|
|
5
|
+
tokens;
|
|
6
|
+
updatedAt;
|
|
7
|
+
constructor(ratePerSec, burst) {
|
|
8
|
+
this.ratePerSec = ratePerSec;
|
|
9
|
+
this.burst = burst;
|
|
10
|
+
this.tokens = burst;
|
|
11
|
+
this.updatedAt = Date.now();
|
|
12
|
+
}
|
|
13
|
+
tryTake() {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
this.tokens = Math.min(this.burst, this.tokens + ((now - this.updatedAt) / 1000) * this.ratePerSec);
|
|
16
|
+
this.updatedAt = now;
|
|
17
|
+
if (this.tokens < 1)
|
|
18
|
+
return false;
|
|
19
|
+
this.tokens -= 1;
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
secondsUntilNext() {
|
|
23
|
+
if (this.tokens >= 1)
|
|
24
|
+
return 0;
|
|
25
|
+
if (this.ratePerSec <= 0)
|
|
26
|
+
return Infinity;
|
|
27
|
+
return Math.ceil((1 - this.tokens) / this.ratePerSec);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=tokenBucket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenBucket.js","sourceRoot":"","sources":["../../src/util/tokenBucket.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,MAAM,OAAO,WAAW;IAGO;IAAqC;IAF1D,MAAM,CAAS;IACf,SAAS,CAAS;IAC1B,YAA6B,UAAkB,EAAmB,KAAa;QAAlD,eAAU,GAAV,UAAU,CAAQ;QAAmB,UAAK,GAAL,KAAK,CAAQ;QAC7E,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO;QACL,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACpG,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;QACrB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAClC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,gBAAgB;QACd,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC;YAAE,OAAO,QAAQ,CAAC;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;IACxD,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blen/fedreg-mcp-server",
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Code-mode MCP server for the U.S. Federal Register, Electronic Code of Federal Regulations, and regulations.gov APIs.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"author": "BLEN, Inc. (https://blenlabs.com)",
|
|
7
|
+
"homepage": "https://github.com/blen-labs/fedreg-mcp-server#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/blen-labs/fedreg-mcp-server.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/blen-labs/fedreg-mcp-server/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"model-context-protocol",
|
|
18
|
+
"federal-register",
|
|
19
|
+
"ecfr",
|
|
20
|
+
"regulations.gov",
|
|
21
|
+
"public-comments",
|
|
22
|
+
"code-mode",
|
|
23
|
+
"sandbox",
|
|
24
|
+
"isolated-vm",
|
|
25
|
+
"ai-agents",
|
|
26
|
+
"claude",
|
|
27
|
+
"anthropic",
|
|
28
|
+
"regulations",
|
|
29
|
+
"government-data"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"main": "dist/index.js",
|
|
33
|
+
"types": "dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": "./dist/index.js",
|
|
37
|
+
"types": "./dist/index.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./package.json": "./package.json"
|
|
40
|
+
},
|
|
41
|
+
"bin": {
|
|
42
|
+
"fedreg-mcp-server": "dist/bin.js"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"schema",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE",
|
|
49
|
+
"NOTICE",
|
|
50
|
+
"CHANGELOG.md",
|
|
51
|
+
"SECURITY.md"
|
|
52
|
+
],
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=20.10"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@modelcontextprotocol/node": "2.0.0",
|
|
58
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
59
|
+
"acorn": "^8.12.1",
|
|
60
|
+
"acorn-walk": "^8.3.4",
|
|
61
|
+
"jose": "^5.9.6",
|
|
62
|
+
"lru-cache": "^11.0.2",
|
|
63
|
+
"undici": "^6.21.0",
|
|
64
|
+
"zod": "^3.23.8"
|
|
65
|
+
},
|
|
66
|
+
"optionalDependencies": {
|
|
67
|
+
"isolated-vm": "^5.0.1"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@anthropic-ai/mcpb": "^2.1.2",
|
|
71
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
72
|
+
"@types/node": "^22.10.2",
|
|
73
|
+
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
|
74
|
+
"@typescript-eslint/parser": "^8.18.0",
|
|
75
|
+
"eslint": "^9.17.0",
|
|
76
|
+
"nock": "^14.0.0-beta.19",
|
|
77
|
+
"tsx": "^4.19.2",
|
|
78
|
+
"typescript": "^5.7.2",
|
|
79
|
+
"vitest": "^2.1.8"
|
|
80
|
+
},
|
|
81
|
+
"publishConfig": {
|
|
82
|
+
"access": "public"
|
|
83
|
+
},
|
|
84
|
+
"scripts": {
|
|
85
|
+
"build": "tsc -p tsconfig.build.json && (chmod +x dist/bin.js || true)",
|
|
86
|
+
"dev": "tsx src/bin.ts",
|
|
87
|
+
"start": "node dist/bin.js",
|
|
88
|
+
"test": "vitest run",
|
|
89
|
+
"test:watch": "vitest",
|
|
90
|
+
"lint": "eslint .",
|
|
91
|
+
"typecheck": "tsc --noEmit",
|
|
92
|
+
"mcpb:prepare": "node scripts/mcpb-prepare.mjs",
|
|
93
|
+
"mcpb:pack": "mcpb pack"
|
|
94
|
+
}
|
|
95
|
+
}
|