anki-mcp-http 0.20.1 → 0.22.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
@@ -237,6 +237,8 @@ For client-specific features and troubleshooting, consult your MCP client's docu
237
237
 
238
238
  HTTP mode runs the server as a local web server speaking the MCP Streamable HTTP protocol. It's the transport a web-based AI tool talks to when pointed at your machine, and it's also what the [Remote](#remote) options expose to the outside world. On its own, HTTP mode binds to `localhost` only.
239
239
 
240
+ > **Binding beyond localhost?** If you pass `--host 0.0.0.0` (or run behind a reverse proxy/public domain), the server only accepts loopback `Host` headers by default for DNS-rebinding protection — set `ALLOWED_HOSTS` to the hostname(s) clients use. See [HTTP Mode Configuration](#http-mode-configuration).
241
+
240
242
  **Setup - Choose one method:**
241
243
 
242
244
  **Method 1: Using npx (recommended - no installation needed)**
@@ -330,7 +332,9 @@ If you'd rather expose [local HTTP mode](#http-local-web-based-ai) publicly with
330
332
  ankimcp --ngrok
331
333
  ```
332
334
 
333
- This route is **unauthenticated** — anyone with the URL can reach your Anki, so it's less secure than [Tunnel](#tunnel--recommended). Prefer Tunnel unless you have a specific reason to manage your own ngrok endpoint. (Requires a global ngrok install and authtoken; the manual two-terminal `ngrok http 3000` setup works too.)
335
+ This route is **unauthenticated** — anyone with the URL can reach your Anki, so it's less secure than [Tunnel](#tunnel--recommended). Prefer Tunnel unless you have a specific reason to manage your own ngrok endpoint. (Requires a global ngrok install and authtoken.)
336
+
337
+ The `--ngrok` flag launches ngrok with `--host-header=rewrite`, so ngrok rewrites the upstream `Host` to `localhost` before forwarding. That keeps requests within the loopback Host allowlist (see [DNS-rebinding protection](#http-mode-configuration)) without you having to add the public `*.ngrok` domain to `ALLOWED_HOSTS`. If you instead run ngrok manually, use the same flag — `ngrok http --host-header=rewrite 3000` — otherwise ngrok forwards the public ngrok hostname as `Host` and the server rejects it with `403`.
334
338
 
335
339
  ### CLI Options (all modes)
336
340
 
@@ -449,6 +453,8 @@ For more details, see the [official MCP documentation](https://modelcontextproto
449
453
  | `ANKI_CONNECT_API_KEY` | API key if configured in AnkiConnect | - |
450
454
  | `ANKI_CONNECT_TIMEOUT` | Request timeout in ms | `5000` |
451
455
  | `READ_ONLY` | Enable read-only mode (`true` or `1`) | `false` |
456
+ | `ALLOWED_HOSTS` | HTTP mode: extra `Host` header values to accept beyond loopback (comma-separated hostnames). Required when binding to a LAN/public address or running behind a reverse proxy. See [HTTP Mode Configuration](#http-mode-configuration). | loopback only |
457
+ | `ALLOWED_ORIGINS` | HTTP mode: comma-separated allowlist of browser `Origin`/`Referer` patterns (wildcards supported, e.g. `https://*.ngrok.io`). | `http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*` |
452
458
  | `TUNNEL_SERVER_URL` | Tunnel server WebSocket URL (tunnel mode only) | `wss://tunnel.ankimcp.ai` |
453
459
  | `MEDIA_ALLOWED_TYPES` | Extra MIME types to allow for file path imports (comma-separated, e.g., `application/pdf`) | - |
454
460
  | `MEDIA_IMPORT_DIR` | Restrict file path imports to this directory | - |
@@ -520,6 +526,14 @@ These protections apply to `storeMediaFile`, `retrieveMediaFile`, `deleteMediaFi
520
526
 
521
527
  > Path traversal vulnerability reported by [Hideaki Takahashi](https://github.com/Koukyosyumei).
522
528
 
529
+ ### DNS-Rebinding Protection (HTTP transport)
530
+
531
+ When running in HTTP mode, the server validates the `Host` header on every request. By default only loopback hosts (`localhost`, `127.0.0.1`, `::1`) are accepted, regardless of port. `Host` is a browser-forbidden header, so a malicious web page cannot forge it — this closes the DNS-rebinding path where a rebound page reaches the local server with a spoofed `Host` and no `Origin`, and reaches the MCP tools. A disallowed `Host` is rejected with `403`.
532
+
533
+ If you bind to `0.0.0.0`, run behind a reverse proxy, or expose a public tunnel domain, set `ALLOWED_HOSTS` (comma-separated hostnames) to permit those hosts. When tunneling with ngrok the server uses `--host-header=rewrite`, so the upstream still sees a loopback `Host`. See [HTTP Mode Configuration](#http-mode-configuration) for the full list of options.
534
+
535
+ > DNS-rebinding vulnerability reported by [avishaigo-commits](https://github.com/avishaigo-commits) and [yotampe-pluto](https://github.com/yotampe-pluto).
536
+
523
537
  ## Privacy Policy
524
538
 
525
539
  This MCP server runs locally on your machine and collects no telemetry, analytics, or usage data.
@@ -610,13 +624,26 @@ npm run build # Builds once, creates dist/ with all three entry points
610
624
  **Environment Variables:**
611
625
  - `PORT` - HTTP server port (default: 3000)
612
626
  - `HOST` - Bind address (default: 127.0.0.1 for localhost-only)
613
- - `ALLOWED_ORIGINS` - Comma-separated list of allowed origins for CORS (default: localhost)
627
+ - `ALLOWED_HOSTS` - Comma-separated extra `Host` header values to accept beyond the built-in loopback set (`localhost`, `127.0.0.1`, `::1`). Hostname-only and port-agnostic. Default: loopback only.
628
+ - `ALLOWED_ORIGINS` - Comma-separated allowlist of browser `Origin`/`Referer` patterns; wildcards supported (e.g. `https://*.ngrok.io`). Default: `http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*`.
614
629
  - `LOG_LEVEL` - Logging level (default: info)
615
630
 
616
631
  **Security:**
617
- - Origin header validation (prevents DNS rebinding attacks)
618
- - Binds to localhost (127.0.0.1) by default
619
- - No authentication in current version (OAuth support planned)
632
+ - **Host header validation (DNS-rebinding protection)** — every HTTP request must carry a `Host` header that matches the allowlist. By default only loopback hosts (`localhost`, `127.0.0.1`, `::1`) are accepted, regardless of port. `Host` is a browser-forbidden header, so a malicious web page cannot forge it — this closes the [DNS-rebinding](https://github.com/ankimcp/anki-mcp-server/security/advisories) path where a rebound page reaches the server with a spoofed `Host` and no `Origin`. A disallowed `Host` is rejected with `403`.
633
+ - **Origin header validation** — browser requests with a present-but-disallowed `Origin`/`Referer` are rejected. Requests with **no** `Origin` (curl, Postman, MCP-over-HTTP clients) are allowed; Host validation is the defense against rebinding.
634
+ - Binds to localhost (127.0.0.1) by default.
635
+ - No authentication in current version (OAuth support planned).
636
+
637
+ **Exposing HTTP mode beyond localhost** — if you bind to a LAN/public address or put the server behind a reverse proxy or public domain, you **must** set `ALLOWED_HOSTS` to the hostname(s) clients will use, otherwise every non-loopback request is rejected with `403`:
638
+
639
+ ```bash
640
+ # Bind to all interfaces and accept the machine's LAN name + a public domain
641
+ ALLOWED_HOSTS=my-nas.local,anki.example.com PORT=8080 HOST=0.0.0.0 node dist/main-http.js
642
+ ```
643
+
644
+ When you bind to `0.0.0.0`/`::` without `ALLOWED_HOSTS`, the server logs a startup warning that only loopback `Host` headers will be accepted.
645
+
646
+ > **Docker / reverse proxy / public domain:** the same rule applies. In Docker, requests usually arrive with the container's published hostname or the proxy's `Host`, so set `ALLOWED_HOSTS` accordingly. A reverse proxy (nginx, Caddy, Traefik) should either forward the original `Host` and have that hostname listed in `ALLOWED_HOSTS`, or rewrite the upstream `Host` to `localhost`. The built-in `--ngrok` integration handles this automatically (see below).
620
647
 
621
648
  **Example: Running Modes**
622
649
  ```bash
@@ -908,7 +935,7 @@ This project follows [Semantic Versioning](https://semver.org/) with a pre-1.0 d
908
935
  - Will be released when the API is stable and tested
909
936
  - Breaking changes will require major version bumps (2.0.0, etc.)
910
937
 
911
- **Current Status**: `0.20.0` - Active beta development. Recent features include model field management (`addModelField`, `removeModelField`, `renameModelField`, `repositionModelField`), batch note creation (`addNotes`), integrated ngrok tunneling (`--ngrok` flag), media file management, model/template management, and comprehensive deck statistics. APIs may change based on feedback and testing.
938
+ **Current Status**: `0.22.0` - Active beta development. Recent features include collection-wide review analysis (`review_stats` now aggregates across all decks when `deck` is omitted), model field management (`addModelField`, `removeModelField`, `renameModelField`, `repositionModelField`), batch note creation (`addNotes`), integrated ngrok tunneling (`--ngrok` flag), media file management, model/template management, and comprehensive deck statistics. APIs may change based on feedback and testing.
912
939
 
913
940
  ### MCPB spec evolution
914
941
 
@@ -9,8 +9,11 @@ var AppModule_1;
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.AppModule = void 0;
11
11
  const common_1 = require("@nestjs/common");
12
+ const core_1 = require("@nestjs/core");
12
13
  const config_1 = require("@nestjs/config");
13
14
  const mcp_nest_1 = require("@rekog/mcp-nest");
15
+ const origin_validation_guard_1 = require("./http/guards/origin-validation.guard");
16
+ const host_validation_guard_1 = require("./http/guards/host-validation.guard");
14
17
  const essential_1 = require("./mcp/primitives/essential");
15
18
  const gui_1 = require("./mcp/primitives/gui");
16
19
  const app_config_service_1 = require("./app-config.service");
@@ -111,6 +114,14 @@ let AppModule = AppModule_1 = class AppModule {
111
114
  useValue: validatedConfig,
112
115
  },
113
116
  app_config_service_1.AppConfigService,
117
+ {
118
+ provide: core_1.APP_GUARD,
119
+ useClass: origin_validation_guard_1.OriginValidationGuard,
120
+ },
121
+ {
122
+ provide: core_1.APP_GUARD,
123
+ useClass: host_validation_guard_1.HostValidationGuard,
124
+ },
114
125
  ...essential_1.ESSENTIAL_MCP_TOOLS,
115
126
  ...gui_1.GUI_MCP_TOOLS,
116
127
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ export declare const DEFAULT_ALLOWED_ORIGINS: string[];
2
3
  export declare const configSchema: z.ZodObject<{
3
4
  port: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
4
5
  host: z.ZodDefault<z.ZodString>;
@@ -7,6 +8,8 @@ export declare const configSchema: z.ZodObject<{
7
8
  production: "production";
8
9
  test: "test";
9
10
  }>>;
11
+ allowedHosts: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodString>>>;
12
+ allowedOrigins: z.ZodDefault<z.ZodPreprocess<z.ZodArray<z.ZodString>>>;
10
13
  ankiConnect: z.ZodObject<{
11
14
  url: z.ZodDefault<z.ZodString>;
12
15
  apiKey: z.ZodOptional<z.ZodString>;
@@ -1,12 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configSchema = void 0;
3
+ exports.configSchema = exports.DEFAULT_ALLOWED_ORIGINS = void 0;
4
4
  exports.transformEnvToConfig = transformEnvToConfig;
5
5
  const zod_1 = require("zod");
6
+ exports.DEFAULT_ALLOWED_ORIGINS = [
7
+ "http://localhost:*",
8
+ "http://127.0.0.1:*",
9
+ "https://localhost:*",
10
+ "https://127.0.0.1:*",
11
+ ];
12
+ function parseCsvList(val) {
13
+ if (val === undefined || val === null)
14
+ return undefined;
15
+ if (Array.isArray(val))
16
+ return val;
17
+ if (typeof val !== "string")
18
+ return undefined;
19
+ const items = val
20
+ .split(",")
21
+ .map((item) => item.trim())
22
+ .filter((item) => item.length > 0);
23
+ return items;
24
+ }
6
25
  exports.configSchema = zod_1.z.object({
7
26
  port: zod_1.z.coerce.number().int().positive().default(3000),
8
27
  host: zod_1.z.string().default("127.0.0.1"),
9
28
  nodeEnv: zod_1.z.enum(["development", "production", "test"]).default("development"),
29
+ allowedHosts: zod_1.z.preprocess(parseCsvList, zod_1.z.array(zod_1.z.string())).default([]),
30
+ allowedOrigins: zod_1.z
31
+ .preprocess(parseCsvList, zod_1.z.array(zod_1.z.string()))
32
+ .default(exports.DEFAULT_ALLOWED_ORIGINS),
10
33
  ankiConnect: zod_1.z.object({
11
34
  url: zod_1.z.string().url().default("http://localhost:8765"),
12
35
  apiKey: zod_1.z.string().optional(),
@@ -35,6 +58,8 @@ function transformEnvToConfig(env) {
35
58
  port: env.PORT,
36
59
  host: env.HOST,
37
60
  nodeEnv: env.NODE_ENV,
61
+ allowedHosts: env.ALLOWED_HOSTS,
62
+ allowedOrigins: env.ALLOWED_ORIGINS,
38
63
  ankiConnect: {
39
64
  url: env.ANKI_CONNECT_URL,
40
65
  apiKey: env.ANKI_CONNECT_API_KEY,
@@ -1 +1 @@
1
- {"version":3,"file":"config.schema.js","sourceRoot":"","sources":["../../src/config/config.schema.ts"],"names":[],"mappings":";;;AAqDA,oDAoBC;AAzED,6BAAwB;AAMX,QAAA,YAAY,GAAG,OAAC,CAAC,MAAM,CAAC;IAEnC,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACtD,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;IACrC,OAAO,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;IAG7E,WAAW,EAAE,OAAC,CAAC,MAAM,CAAC;QACpB,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC;QACtD,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC7B,UAAU,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;KAC1D,CAAC;IAGF,IAAI,EAAE,OAAC,CAAC,MAAM,CAAC;QACb,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC;KAC5C,CAAC;IAGF,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;QACf,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,yBAAyB,CAAC;KAC/D,CAAC;IAGF,QAAQ,EAAE,OAAC;SACR,UAAU,CAAC,CAAC,GAAG,EAAE,EAAE;QAClB,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QAC/C,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;YACnE,OAAO,KAAK,CAAC;QACf,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC;SACd,OAAO,CAAC,KAAK,CAAC;IAGjB,QAAQ,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;CACrE,CAAC,CAAC;AAWH,SAAgB,oBAAoB,CAAC,GAAwB;IAC3D,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,WAAW,EAAE;YACX,GAAG,EAAE,GAAG,CAAC,gBAAgB;YACzB,MAAM,EAAE,GAAG,CAAC,oBAAoB;YAChC,UAAU,EAAE,GAAG,CAAC,wBAAwB;YACxC,OAAO,EAAE,GAAG,CAAC,oBAAoB;SAClC;QACD,IAAI,EAAE;YACJ,QAAQ,EAAE,GAAG,CAAC,qBAAqB;SACpC;QACD,MAAM,EAAE;YACN,SAAS,EAAE,GAAG,CAAC,iBAAiB;SACjC;QACD,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,QAAQ,EAAE,GAAG,CAAC,SAAS;KACxB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.schema.js","sourceRoot":"","sources":["../../src/config/config.schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { CanActivate, ExecutionContext } from "@nestjs/common";
2
+ import { type AppConfig } from "../../config";
3
+ export declare function shouldWarnLoopbackOnly(host: string, allowedHosts: string[]): boolean;
4
+ export declare class HostValidationGuard implements CanActivate {
5
+ private readonly logger;
6
+ private readonly allowedHosts;
7
+ private static readonly LOOPBACK_HOSTS;
8
+ constructor(config: AppConfig);
9
+ canActivate(context: ExecutionContext): boolean;
10
+ private static extractHostname;
11
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var HostValidationGuard_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.HostValidationGuard = void 0;
17
+ exports.shouldWarnLoopbackOnly = shouldWarnLoopbackOnly;
18
+ const common_1 = require("@nestjs/common");
19
+ const config_1 = require("../../config");
20
+ const LOOPBACK_BIND_HOSTS = new Set(["localhost", "127.0.0.1", "::1"]);
21
+ function shouldWarnLoopbackOnly(host, allowedHosts) {
22
+ const normalized = host.trim().toLowerCase();
23
+ const isLoopbackBind = LOOPBACK_BIND_HOSTS.has(normalized);
24
+ return !isLoopbackBind && allowedHosts.length === 0;
25
+ }
26
+ let HostValidationGuard = class HostValidationGuard {
27
+ static { HostValidationGuard_1 = this; }
28
+ logger = new common_1.Logger(HostValidationGuard_1.name);
29
+ allowedHosts;
30
+ static LOOPBACK_HOSTS = ["localhost", "127.0.0.1", "::1"];
31
+ constructor(config) {
32
+ this.allowedHosts = new Set([
33
+ ...HostValidationGuard_1.LOOPBACK_HOSTS,
34
+ ...config.allowedHosts.map((host) => HostValidationGuard_1.extractHostname(host)),
35
+ ].filter((host) => host.length > 0));
36
+ }
37
+ canActivate(context) {
38
+ const request = context.switchToHttp().getRequest();
39
+ const hostHeader = request.headers.host;
40
+ if (!hostHeader || hostHeader.trim().length === 0) {
41
+ this.logger.warn("Rejected request with missing Host header (DNS-rebinding protection)");
42
+ return false;
43
+ }
44
+ const hostname = HostValidationGuard_1.extractHostname(hostHeader);
45
+ if (this.allowedHosts.has(hostname)) {
46
+ return true;
47
+ }
48
+ this.logger.warn(`Rejected request with disallowed Host header: "${hostHeader}". ` +
49
+ `Allowed hosts are loopback by default; set ALLOWED_HOSTS ` +
50
+ `(comma-separated hostnames) to permit additional hosts.`);
51
+ return false;
52
+ }
53
+ static extractHostname(value) {
54
+ const trimmed = value.trim().toLowerCase();
55
+ if (trimmed.length === 0) {
56
+ return "";
57
+ }
58
+ if (trimmed.startsWith("[")) {
59
+ const closing = trimmed.indexOf("]");
60
+ if (closing !== -1) {
61
+ return trimmed.slice(1, closing);
62
+ }
63
+ }
64
+ const firstColon = trimmed.indexOf(":");
65
+ const lastColon = trimmed.lastIndexOf(":");
66
+ if (firstColon !== -1 && firstColon === lastColon) {
67
+ return trimmed.slice(0, firstColon);
68
+ }
69
+ return trimmed;
70
+ }
71
+ };
72
+ exports.HostValidationGuard = HostValidationGuard;
73
+ exports.HostValidationGuard = HostValidationGuard = HostValidationGuard_1 = __decorate([
74
+ (0, common_1.Injectable)(),
75
+ __param(0, (0, common_1.Inject)(config_1.APP_CONFIG)),
76
+ __metadata("design:paramtypes", [Object])
77
+ ], HostValidationGuard);
78
+ //# sourceMappingURL=host-validation.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-validation.guard.js","sourceRoot":"","sources":["../../../src/http/guards/host-validation.guard.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { CanActivate, ExecutionContext } from "@nestjs/common";
2
+ import { type AppConfig } from "../../config";
2
3
  export declare class OriginValidationGuard implements CanActivate {
3
4
  private readonly logger;
4
5
  private readonly allowedOrigins;
5
- constructor();
6
+ constructor(config: AppConfig);
6
7
  canActivate(context: ExecutionContext): boolean;
7
8
  private matchesPattern;
8
9
  }
@@ -8,17 +8,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
11
14
  var OriginValidationGuard_1;
12
15
  Object.defineProperty(exports, "__esModule", { value: true });
13
16
  exports.OriginValidationGuard = void 0;
14
17
  const common_1 = require("@nestjs/common");
18
+ const config_1 = require("../../config");
15
19
  let OriginValidationGuard = OriginValidationGuard_1 = class OriginValidationGuard {
16
20
  logger = new common_1.Logger(OriginValidationGuard_1.name);
17
21
  allowedOrigins;
18
- constructor() {
19
- const defaultOrigins = "http://localhost:*,http://127.0.0.1:*,https://localhost:*,https://127.0.0.1:*";
20
- const originsEnv = process.env.ALLOWED_ORIGINS || defaultOrigins;
21
- this.allowedOrigins = originsEnv.split(",").map((o) => o.trim());
22
+ constructor(config) {
23
+ this.allowedOrigins = config.allowedOrigins;
22
24
  }
23
25
  canActivate(context) {
24
26
  const request = context.switchToHttp().getRequest();
@@ -49,6 +51,7 @@ let OriginValidationGuard = OriginValidationGuard_1 = class OriginValidationGuar
49
51
  exports.OriginValidationGuard = OriginValidationGuard;
50
52
  exports.OriginValidationGuard = OriginValidationGuard = OriginValidationGuard_1 = __decorate([
51
53
  (0, common_1.Injectable)(),
52
- __metadata("design:paramtypes", [])
54
+ __param(0, (0, common_1.Inject)(config_1.APP_CONFIG)),
55
+ __metadata("design:paramtypes", [Object])
53
56
  ], OriginValidationGuard);
54
57
  //# sourceMappingURL=origin-validation.guard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"origin-validation.guard.js","sourceRoot":"","sources":["../../../src/http/guards/origin-validation.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAKwB;AAiBjB,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;IACf,MAAM,GAAG,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAChD,cAAc,CAAW;IAE1C;QACE,MAAM,cAAc,GAClB,+EAA+E,CAAC;QAClF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,cAAc,CAAC;QACjE,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAGjE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAC3C,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,MAAM,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IASO,cAAc,CAAC,MAAc,EAAE,OAAe;QAEpD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,YAAY,GAAG,OAAO;iBACzB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;iBACrB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AAxDY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;;GACA,qBAAqB,CAwDjC"}
1
+ {"version":3,"file":"origin-validation.guard.js","sourceRoot":"","sources":["../../../src/http/guards/origin-validation.guard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAMwB;AAExB,yCAAsD;AAmB/C,IAAM,qBAAqB,6BAA3B,MAAM,qBAAqB;IACf,MAAM,GAAG,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAChD,cAAc,CAAW;IAE1C,YAAgC,MAAiB;QAC/C,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;IAC9C,CAAC;IAED,WAAW,CAAC,OAAyB;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAW,CAAC;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAGjE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE,CAC3D,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAC3C,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8CAA8C,MAAM,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IASO,cAAc,CAAC,MAAc,EAAE,OAAe;QAEpD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAGD,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,YAAY,GAAG,OAAO;iBACzB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;iBACrB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,CAAC,CAAC;YAC9C,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAA;AArDY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKE,WAAA,IAAA,eAAM,EAAC,mBAAU,CAAC,CAAA;;GAJpB,qBAAqB,CAqDjC"}
package/dist/main-http.js CHANGED
@@ -1,13 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@nestjs/core");
4
+ const common_1 = require("@nestjs/common");
4
5
  const app_module_1 = require("./app.module");
5
6
  const bootstrap_1 = require("./bootstrap");
6
- const origin_validation_guard_1 = require("./http/guards/origin-validation.guard");
7
7
  const cli_1 = require("./cli");
8
8
  const cli_2 = require("./cli");
9
9
  const ngrok_service_1 = require("./services/ngrok.service");
10
10
  const config_1 = require("./config");
11
+ const host_validation_guard_1 = require("./http/guards/host-validation.guard");
11
12
  async function bootstrap() {
12
13
  (0, cli_1.checkForUpdates)();
13
14
  const options = (0, cli_1.parseCliArgs)();
@@ -28,7 +29,15 @@ async function bootstrap() {
28
29
  logger: loggerService,
29
30
  bufferLogs: true,
30
31
  });
31
- app.useGlobalGuards(new origin_validation_guard_1.OriginValidationGuard());
32
+ const validatedConfig = config_1.configSchema.parse((0, config_1.transformEnvToConfig)(configInput));
33
+ const boundHost = options.host;
34
+ if ((0, host_validation_guard_1.shouldWarnLoopbackOnly)(boundHost, validatedConfig.allowedHosts)) {
35
+ new common_1.Logger("HttpBootstrap").warn(`Server is bound to ${boundHost} but ALLOWED_HOSTS is not set. ` +
36
+ `For DNS-rebinding protection, only loopback Host headers ` +
37
+ `(localhost, 127.0.0.1, ::1) are accepted — requests via a LAN or ` +
38
+ `public hostname will be rejected with 403. Set ALLOWED_HOSTS ` +
39
+ `(comma-separated hostnames) to permit them.`);
40
+ }
32
41
  await app.listen(options.port, options.host);
33
42
  let ngrokUrl;
34
43
  if (options.ngrok) {
@@ -1 +1 @@
1
- {"version":3,"file":"main-http.js","sourceRoot":"","sources":["../src/main-http.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AACzC,2CAIqB;AACrB,mFAA8E;AAC9E,+BAKe;AACf,+BAAkC;AAClC,4DAAwD;AACxD,qCAA4C;AAE5C,KAAK,UAAU,SAAS;IAEtB,IAAA,qBAAe,GAAE,CAAC;IAElB,MAAM,OAAO,GAAG,IAAA,kBAAY,GAAE,CAAC;IAK/B,MAAM,GAAG,GAAG,IAAA,eAAS,EAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAKrC,MAAM,SAAS,GAAG,IAAA,sBAAgB,EAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;IAGpE,MAAM,WAAW,GAAG,IAAA,yBAAgB,EAAC;QACnC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;IAIH,MAAM,UAAU,GAAG,IAAA,4BAAgB,EACjC,2BAAe,CAAC,MAAM,EACtB,WAAW,CAAC,SAAS,IAAI,MAAM,CAChC,CAAC;IACF,MAAM,aAAa,GAAG,IAAA,+BAAmB,EAAC,UAAU,CAAC,CAAC;IAGtD,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;QACnE,MAAM,EAAE,aAAa;QACrB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IAGH,GAAG,CAAC,eAAe,CAAC,IAAI,+CAAqB,EAAE,CAAC,CAAC;IAEjD,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAG7C,IAAI,QAA4B,CAAC;IACjC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,4BAAY,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1D,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,GAAG,CAAC,KAAK,CACP,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC5E,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CACvC,CAAC;YACF,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,GAAG,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;YAC5D,GAAG,CAAC,KAAK,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAGD,IAAA,0BAAoB,EAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAID,SAAS,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACxB,MAAM,GAAG,GAAG,IAAA,eAAS,EAAC,KAAK,CAAC,CAAC;IAC7B,GAAG,CAAC,KAAK,CACP,oCAAoC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACtF,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CACvC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"main-http.js","sourceRoot":"","sources":["../src/main-http.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ export declare class ReviewStatsTool {
5
5
  private readonly logger;
6
6
  constructor(ankiClient: AnkiConnectClient);
7
7
  execute(params: {
8
- deck: string;
8
+ deck?: string;
9
9
  start_date: string;
10
10
  end_date?: string;
11
11
  }): Promise<{
@@ -105,5 +105,6 @@ export declare class ReviewStatsTool {
105
105
  } | undefined;
106
106
  isError?: boolean | undefined;
107
107
  } | ReviewStatsResult>;
108
+ private fetchCollectionReviews;
108
109
  private getTodayISO;
109
110
  }
@@ -26,16 +26,20 @@ let ReviewStatsTool = ReviewStatsTool_1 = class ReviewStatsTool {
26
26
  }
27
27
  async execute(params) {
28
28
  try {
29
- const { deck, start_date } = params;
29
+ const { start_date } = params;
30
+ const deck = params.deck && params.deck.length > 0 ? params.deck : undefined;
31
+ const deckLabel = deck ?? "All Decks";
30
32
  const end_date = params.end_date || this.getTodayISO();
31
- this.logger.log(`Getting review statistics from ${start_date} to ${end_date} for deck: ${deck}`);
33
+ this.logger.log(`Getting review statistics from ${start_date} to ${end_date} for deck: ${deckLabel}`);
32
34
  const startTimestamp = new Date(start_date).getTime();
33
35
  const endTimestamp = new Date(end_date).getTime() + MS_PER_DAY;
34
- this.logger.log(`Fetching detailed review data for deck: ${deck}...`);
35
- const reviews = await this.ankiClient.invoke("cardReviews", {
36
- startID: startTimestamp,
37
- deck: deck,
38
- });
36
+ this.logger.log(`Fetching detailed review data for deck: ${deckLabel}...`);
37
+ const reviews = deck
38
+ ? await this.ankiClient.invoke("cardReviews", {
39
+ startID: startTimestamp,
40
+ deck,
41
+ })
42
+ : await this.fetchCollectionReviews(startTimestamp);
39
43
  const filteredReviews = reviews.filter((review) => review[0] <= endTimestamp);
40
44
  this.logger.log("Calculating daily review counts from reviews...");
41
45
  const reviewsByDayMap = new Map();
@@ -66,7 +70,7 @@ let ReviewStatsTool = ReviewStatsTool_1 = class ReviewStatsTool {
66
70
  start: start_date,
67
71
  end: end_date,
68
72
  },
69
- deck: deck,
73
+ deck: deckLabel,
70
74
  reviews_by_day: reviewsByDay,
71
75
  summary: {
72
76
  total_reviews: totalReviews,
@@ -90,6 +94,36 @@ let ReviewStatsTool = ReviewStatsTool_1 = class ReviewStatsTool {
90
94
  });
91
95
  }
92
96
  }
97
+ async fetchCollectionReviews(startTimestamp) {
98
+ const cardIds = await this.ankiClient.invoke("findCards", {
99
+ query: "deck:*",
100
+ });
101
+ if (!cardIds || cardIds.length === 0) {
102
+ return [];
103
+ }
104
+ const reviewsByCard = await this.ankiClient.invoke("getReviewsOfCards", { cards: cardIds });
105
+ const tuples = [];
106
+ for (const [cardId, cardReviews] of Object.entries(reviewsByCard)) {
107
+ const cid = Number(cardId);
108
+ for (const r of cardReviews) {
109
+ if (r.id <= startTimestamp) {
110
+ continue;
111
+ }
112
+ tuples.push([
113
+ r.id,
114
+ cid,
115
+ r.usn,
116
+ r.ease,
117
+ r.ivl,
118
+ r.lastIvl,
119
+ r.factor,
120
+ r.time,
121
+ r.type,
122
+ ]);
123
+ }
124
+ }
125
+ return tuples;
126
+ }
93
127
  getTodayISO() {
94
128
  const today = new Date();
95
129
  return today.toISOString().split("T")[0];
@@ -101,12 +135,16 @@ __decorate([
101
135
  name: "review_stats",
102
136
  description: "Get review history analysis including temporal patterns, retention metrics, and study streak information. " +
103
137
  "Use this to analyze learning progress over time, identify review patterns, and track consistency. " +
104
- "Requires a start date and deck name; end date defaults to today.",
138
+ "Requires a start date; the deck is optional - omit it to analyze the entire collection (all decks). " +
139
+ "End date defaults to today.",
105
140
  parameters: zod_1.z
106
141
  .object({
107
142
  deck: zod_1.z
108
143
  .string()
109
- .describe("Deck name to filter reviews (REQUIRED - AnkiConnect API requires a deck)"),
144
+ .optional()
145
+ .describe("Deck name to filter reviews. Matches the EXACT deck only - subdecks are NOT included, " +
146
+ "so a parent deck still returns reviews for cards assigned directly to it (but not its subdecks' cards). " +
147
+ "Omit (or pass an empty string) to analyze the entire collection (all decks)."),
110
148
  start_date: zod_1.z
111
149
  .string()
112
150
  .regex(/^\d{4}-\d{2}-\d{2}$/, "Must be ISO date format: YYYY-MM-DD")
@@ -1 +1 @@
1
- {"version":3,"file":"review-stats.tool.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/tools/review-stats/review-stats.tool.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,8CAAuC;AACvC,6BAAwB;AACxB,iFAAsE;AACtE,6DAA6D;AAC7D,+DAA4E;AAI5E,MAAM,UAAU,GAAG,QAAQ,CAAC;AAMrB,IAAM,eAAe,uBAArB,MAAM,eAAe;IAGG;IAFZ,MAAM,GAAG,IAAI,eAAM,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAE3D,YAA6B,UAA6B;QAA7B,eAAU,GAAV,UAAU,CAAmB;IAAG,CAAC;IA0FxD,AAAN,KAAK,CAAC,OAAO,CAAC,MAIb;QACC,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC;YACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAEvD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,kCAAkC,UAAU,OAAO,QAAQ,cAAc,IAAI,EAAE,CAChF,CAAC;YAIF,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;YACtD,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,GAAG,UAAU,CAAC;YAG/D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,2CAA2C,IAAI,KAAK,CAAC,CAAC;YAEtE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAC1C,aAAa,EACb;gBACE,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,IAAI;aACX,CACF,CAAC;YAGF,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CACpC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,YAAY,CACtC,CAAC;YAGF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YACnE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;YAElD,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAClE,CAAC;YAGD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;iBACvD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;iBACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAIhD,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAGjE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,IAAA,8BAAgB,EAAC,aAAa,CAAC,CAAC;YAGlD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;YACrD,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YACnE,MAAM,aAAa,GACjB,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAGnE,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC5D,MAAM,MAAM,GACV,WAAW,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACjE,CAAC,CAAC,IAAI,CAAC;YACX,MAAM,MAAM,GACV,WAAW,CAAC,MAAM,GAAG,CAAC;gBACpB,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACjE,CAAC,CAAC,IAAI,CAAC;YAGX,MAAM,MAAM,GAAG,IAAA,6BAAe,EAAC,YAAY,CAAC,CAAC;YAE7C,MAAM,MAAM,GAAsB;gBAChC,MAAM,EAAE;oBACN,KAAK,EAAE,UAAU;oBACjB,GAAG,EAAE,QAAQ;iBACd;gBACD,IAAI,EAAE,IAAI;gBACV,cAAc,EAAE,YAAY;gBAC5B,OAAO,EAAE;oBACP,aAAa,EAAE,YAAY;oBAC3B,eAAe,EAAE,aAAa;oBAC9B,YAAY,EAAE,WAAW;oBACzB,OAAO,EAAE,MAAM;oBACf,OAAO,EAAE,MAAM;oBACf,MAAM;iBACP;gBACD,SAAS;aACV,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,6CAA6C,YAAY,kBAAkB;gBACzE,GAAG,WAAW,kBAAkB,CAAC,SAAS,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;gBACnF,GAAG,MAAM,aAAa,CACzB,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YAC5D,OAAO,IAAA,gCAAmB,EAAC,KAAK,EAAE;gBAChC,IAAI,EAAE,kHAAkH;aACzH,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAMO,WAAW;QACjB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;CACF,CAAA;AAnNY,0CAAe;AA6FpB;IAxFL,IAAA,eAAI,EAAC;QACJ,IAAI,EAAE,cAAc;QACpB,WAAW,EACT,4GAA4G;YAC5G,oGAAoG;YACpG,kEAAkE;QACpE,UAAU,EAAE,OAAC;aACV,MAAM,CAAC;YACN,IAAI,EAAE,OAAC;iBACJ,MAAM,EAAE;iBACR,QAAQ,CACP,0EAA0E,CAC3E;YACH,UAAU,EAAE,OAAC;iBACV,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;iBACnE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE;gBAC1C,OAAO,EAAE,sBAAsB;aAChC,CAAC;iBACD,QAAQ,CACP,6DAA6D,CAC9D;YACH,QAAQ,EAAE,OAAC;iBACR,MAAM,EAAE;iBACR,KAAK,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;iBACnE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE;gBAC1C,OAAO,EAAE,sBAAsB;aAChC,CAAC;iBACD,QAAQ,EAAE;iBACV,QAAQ,CAAC,8BAA8B,CAAC;SAC5C,CAAC;aACD,MAAM,CACL,CAAC,IAAI,EAAE,EAAE;YACP,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAChC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9D,CAAC,EACD;YACE,OAAO,EAAE,mDAAmD;YAC5D,IAAI,EAAE,CAAC,YAAY,CAAC;SACrB,CACF;QACH,YAAY,EAAE,OAAC,CAAC,MAAM,CAAC;YACrB,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;gBACf,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;gBACjB,GAAG,EAAE,OAAC,CAAC,MAAM,EAAE;aAChB,CAAC;YACF,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;YAChB,cAAc,EAAE,OAAC,CAAC,KAAK,CACrB,OAAC,CAAC,MAAM,CAAC;gBACP,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;gBAChB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;aAClB,CAAC,CACH;YACD,OAAO,EAAE,OAAC,CAAC,MAAM,CAAC;gBAChB,aAAa,EAAE,OAAC,CAAC,MAAM,EAAE;gBACzB,eAAe,EAAE,OAAC,CAAC,MAAM,EAAE;gBAC3B,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;gBACxB,OAAO,EAAE,OAAC;qBACP,MAAM,CAAC;oBACN,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;oBAChB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;iBAClB,CAAC;qBACD,QAAQ,EAAE;gBACb,OAAO,EAAE,OAAC;qBACP,MAAM,CAAC;oBACN,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;oBAChB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;iBAClB,CAAC;qBACD,QAAQ,EAAE;gBACb,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;aACnB,CAAC;YACF,SAAS,EAAE,OAAC,CAAC,MAAM,CAAC;gBAClB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;gBACnB,SAAS,EAAE,OAAC,CAAC,MAAM,CAAC;oBAClB,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;oBACjB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;oBAChB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;oBAChB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;iBACjB,CAAC;aACH,CAAC;SACH,CAAC;QACF,WAAW,EAAE;YACX,KAAK,EAAE,mBAAmB;YAC1B,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;SACrB;KACF,CAAC;;;;8CA6GD;0BAzMU,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAI8B,uCAAiB;GAH/C,eAAe,CAmN3B"}
1
+ {"version":3,"file":"review-stats.tool.js","sourceRoot":"","sources":["../../../../../../src/mcp/primitives/essential/tools/review-stats/review-stats.tool.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,16 @@ export interface CardReviewsParams {
8
8
  startID: number;
9
9
  deck?: string;
10
10
  }
11
+ export interface CardReviewObject {
12
+ id: number;
13
+ usn: number;
14
+ ease: number;
15
+ ivl: number;
16
+ lastIvl: number;
17
+ factor: number;
18
+ time: number;
19
+ type: number;
20
+ }
11
21
  export type CardReviewTuple = [
12
22
  timestamp: number,
13
23
  cardId: number,
@@ -18,7 +18,7 @@ class NgrokService {
18
18
  "Or download from: https://ngrok.com/download\n" +
19
19
  "Then setup auth: ngrok config add-authtoken <your-token>");
20
20
  }
21
- this.process = (0, child_process_1.spawn)("ngrok", ["http", port.toString()], {
21
+ this.process = (0, child_process_1.spawn)("ngrok", ["http", "--host-header=rewrite", port.toString()], {
22
22
  stdio: "pipe",
23
23
  });
24
24
  if (!this.cleanupHandlersRegistered) {
@@ -1 +1 @@
1
- {"version":3,"file":"ngrok.service.js","sourceRoot":"","sources":["../../src/services/ngrok.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngrok.service.js","sourceRoot":"","sources":["../../src/services/ngrok.service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "anki-mcp-http",
3
3
  "mcpName": "ai.ankimcp/anki-mcp-server",
4
- "version": "0.20.1",
4
+ "version": "0.22.0",
5
5
  "description": "Model Context Protocol server for Anki - enables AI assistants to interact with your Anki flashcards",
6
6
  "author": "Anatoly Tarnavsky",
7
7
  "private": false,
@@ -57,12 +57,12 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@modelcontextprotocol/sdk": "1.29.0",
60
- "@nestjs/common": "^11.1.26",
60
+ "@nestjs/common": "^11.1.27",
61
61
  "@nestjs/config": "^4.0.4",
62
- "@nestjs/core": "11.1.26",
62
+ "@nestjs/core": "11.1.27",
63
63
  "@nestjs/jwt": "^11.0.2",
64
64
  "@nestjs/passport": "^11.0.5",
65
- "@nestjs/platform-express": "^11.1.26",
65
+ "@nestjs/platform-express": "^11.1.27",
66
66
  "@rekog/mcp-nest": "^1.9.10",
67
67
  "async-mutex": "^0.5.0",
68
68
  "commander": "^15.0.0",
@@ -91,31 +91,31 @@
91
91
  "@modelcontextprotocol/inspector": "^0.22.0",
92
92
  "@nestjs/cli": "^11.0.23",
93
93
  "@nestjs/schematics": "^11.1.0",
94
- "@nestjs/testing": "^11.1.26",
94
+ "@nestjs/testing": "^11.1.27",
95
95
  "@types/express": "^5.0.6",
96
96
  "@types/jest": "^30.0.0",
97
97
  "@types/jsonwebtoken": "^9.0.10",
98
98
  "@types/mdast": "^4.0.4",
99
- "@types/node": "^25.9.3",
99
+ "@types/node": "^26.0.1",
100
100
  "@types/supertest": "^7.2.0",
101
101
  "@types/update-notifier": "^6.0.8",
102
102
  "@types/ws": "^8.18.1",
103
- "eslint": "^10.4.1",
103
+ "eslint": "^10.6.0",
104
104
  "eslint-config-prettier": "^10.1.8",
105
105
  "eslint-plugin-prettier": "^5.5.6",
106
- "globals": "^17.6.0",
106
+ "globals": "^17.7.0",
107
107
  "husky": "^9.1.7",
108
108
  "jest": "^30.4.2",
109
- "prettier": "^3.8.4",
110
- "sharp": "^0.35.0",
109
+ "prettier": "^3.9.1",
110
+ "sharp": "^0.35.2",
111
111
  "source-map-support": "^0.5.21",
112
112
  "supertest": "^7.2.2",
113
113
  "ts-jest": "^29.4.11",
114
- "ts-loader": "^9.6.0",
114
+ "ts-loader": "^9.6.2",
115
115
  "ts-node": "^10.9.2",
116
116
  "tsconfig-paths": "^4.2.0",
117
117
  "typescript": "^6.0.3",
118
- "typescript-eslint": "^8.61.0"
118
+ "typescript-eslint": "^8.62.0"
119
119
  },
120
120
  "jest": {
121
121
  "moduleFileExtensions": [
@@ -168,7 +168,7 @@
168
168
  ],
169
169
  "forceExit": true
170
170
  },
171
- "packageManager": "npm@11.16.0",
171
+ "packageManager": "npm@11.17.0",
172
172
  "engines": {
173
173
  "node": ">=22.12.0"
174
174
  },