@mnemoverse/mcp-memory-server 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 ADDED
@@ -0,0 +1,131 @@
1
+ # @mnemoverse/mcp-memory-server
2
+
3
+ Persistent AI memory for Claude Code, Cursor, VS Code, and any MCP client.
4
+
5
+ Your agent remembers everything — across sessions, projects, and tools. One memory, everywhere.
6
+
7
+ ## Quick Start
8
+
9
+ ### 1. Get a free API key
10
+
11
+ Sign up at [console.mnemoverse.com](https://console.mnemoverse.com) — takes 30 seconds, no credit card.
12
+
13
+ ### 2. Connect to your AI tool
14
+
15
+ **Claude Code:**
16
+
17
+ ```bash
18
+ claude mcp add mnemoverse -e MNEMOVERSE_API_KEY=mk_live_YOUR_KEY -- npx @mnemoverse/mcp-memory-server
19
+ ```
20
+
21
+ **Cursor** — add to `.cursor/mcp.json`:
22
+
23
+ ```json
24
+ {
25
+ "mcpServers": {
26
+ "mnemoverse": {
27
+ "command": "npx",
28
+ "args": ["@mnemoverse/mcp-memory-server"],
29
+ "env": {
30
+ "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY"
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ **VS Code** — add to settings.json:
38
+
39
+ ```json
40
+ {
41
+ "mcp": {
42
+ "servers": {
43
+ "mnemoverse": {
44
+ "command": "npx",
45
+ "args": ["@mnemoverse/mcp-memory-server"],
46
+ "env": {
47
+ "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY"
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ **Windsurf** — add to `~/.codeium/windsurf/mcp_config.json`:
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "mnemoverse": {
61
+ "command": "npx",
62
+ "args": ["@mnemoverse/mcp-memory-server"],
63
+ "env": {
64
+ "MNEMOVERSE_API_KEY": "mk_live_YOUR_KEY"
65
+ }
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### 3. Done
72
+
73
+ Your AI now has persistent memory. Try:
74
+
75
+ > "Remember that I prefer Railway for deployments"
76
+
77
+ Then in a new session:
78
+
79
+ > "Where should I deploy this?"
80
+
81
+ It remembers.
82
+
83
+ ## Tools
84
+
85
+ | Tool | What it does |
86
+ |------|-------------|
87
+ | `memory_write` | Store a memory — insight, preference, lesson learned |
88
+ | `memory_read` | Search memories by natural language query |
89
+ | `memory_feedback` | Rate memories as helpful or not (improves future recall) |
90
+ | `memory_stats` | Check how many memories stored, which domains exist |
91
+
92
+ ## Ideas: What to Remember
93
+
94
+ - **User preferences**: "I use dark mode", "I prefer Tailwind over CSS modules"
95
+ - **Project context**: "This project uses PostgreSQL + Prisma", "Deploy to Railway"
96
+ - **Lessons learned**: "Always run tests before push on this repo"
97
+ - **Decisions made**: "We chose REST over GraphQL because of caching simplicity"
98
+ - **People & roles**: "Alice is the designer, Bob owns the API"
99
+ - **Past mistakes**: "Don't deploy on Fridays — learned this the hard way"
100
+
101
+ ## Universal Memory
102
+
103
+ The same API key works across all tools. Write a memory in Claude Code — read it in Cursor. Learn something in VS Code — your GPT Custom Action knows it too.
104
+
105
+ ```
106
+ ┌── Claude Code (this MCP server)
107
+ ├── Cursor (this MCP server)
108
+ Mnemoverse API ──├── VS Code (this MCP server)
109
+ (one memory) ├── GPT (Custom Actions)
110
+ ├── Python SDK (pip install mnemoverse)
111
+ └── REST API (curl)
112
+ ```
113
+
114
+ ## Configuration
115
+
116
+ | Env Variable | Required | Default |
117
+ |-------------|----------|---------|
118
+ | `MNEMOVERSE_API_KEY` | Yes | — |
119
+ | `MNEMOVERSE_API_URL` | No | `https://core.mnemoverse.com/api/v1` |
120
+
121
+ ## Links
122
+
123
+ - [Documentation](https://mnemoverse.com/docs/api/mcp-server)
124
+ - [Python SDK](https://mnemoverse.com/docs/api/python-sdk)
125
+ - [API Reference](https://mnemoverse.com/docs/api/reference)
126
+ - [Console (get API key)](https://console.mnemoverse.com)
127
+ - [GitHub](https://github.com/mnemoverse/mcp-memory-server)
128
+
129
+ ## License
130
+
131
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { z } from "zod";
5
+ const API_URL = process.env.MNEMOVERSE_API_URL || "https://core.mnemoverse.com/api/v1";
6
+ const API_KEY = process.env.MNEMOVERSE_API_KEY || "";
7
+ if (!API_KEY) {
8
+ console.error("Error: MNEMOVERSE_API_KEY environment variable is required.\n" +
9
+ "Get your free key at https://console.mnemoverse.com");
10
+ process.exit(1);
11
+ }
12
+ async function apiFetch(path, options = {}) {
13
+ const res = await fetch(`${API_URL}${path}`, {
14
+ ...options,
15
+ headers: {
16
+ "Content-Type": "application/json",
17
+ "X-Api-Key": API_KEY,
18
+ ...(options.headers || {}),
19
+ },
20
+ });
21
+ if (!res.ok) {
22
+ const text = await res.text();
23
+ throw new Error(`Mnemoverse API error ${res.status}: ${text}`);
24
+ }
25
+ return res.json();
26
+ }
27
+ // --- Server setup ---
28
+ const server = new McpServer({
29
+ name: "mnemoverse-memory",
30
+ version: "0.1.0",
31
+ });
32
+ // --- Tool: memory_write ---
33
+ server.tool("memory_write", "Store a memory — insight, pattern, preference, or fact. Persists across sessions. Use this when the user teaches you something worth remembering, or when you learn a lesson from a task.", {
34
+ content: z
35
+ .string()
36
+ .min(1)
37
+ .max(10000)
38
+ .describe("The memory to store — what happened, what was learned"),
39
+ concepts: z
40
+ .array(z.string())
41
+ .optional()
42
+ .describe("Key concepts for linking related memories (e.g. ['deploy', 'friday', 'staging'])"),
43
+ domain: z
44
+ .string()
45
+ .optional()
46
+ .describe("Namespace to organize memories (e.g. 'engineering', 'user:alice', 'project:acme')"),
47
+ }, async ({ content, concepts, domain }) => {
48
+ const result = await apiFetch("/memory/write", {
49
+ method: "POST",
50
+ body: JSON.stringify({
51
+ content,
52
+ concepts: concepts || [],
53
+ domain: domain || "general",
54
+ }),
55
+ });
56
+ const r = result;
57
+ if (r.stored) {
58
+ return {
59
+ content: [
60
+ {
61
+ type: "text",
62
+ text: `Stored (importance: ${r.importance.toFixed(2)}). ID: ${r.atom_id}`,
63
+ },
64
+ ],
65
+ };
66
+ }
67
+ return {
68
+ content: [
69
+ {
70
+ type: "text",
71
+ text: `Filtered — ${r.reason} (importance: ${r.importance.toFixed(2)})`,
72
+ },
73
+ ],
74
+ };
75
+ });
76
+ // --- Tool: memory_read ---
77
+ server.tool("memory_read", "Search memories by natural language query. Returns the most relevant stored memories. Use this before starting a task to check if you already know something about it.", {
78
+ query: z
79
+ .string()
80
+ .min(1)
81
+ .max(5000)
82
+ .describe("Natural language query — what are you looking for?"),
83
+ top_k: z
84
+ .number()
85
+ .int()
86
+ .min(1)
87
+ .max(50)
88
+ .optional()
89
+ .describe("Max results to return (default: 5)"),
90
+ domain: z
91
+ .string()
92
+ .optional()
93
+ .describe("Filter by domain namespace"),
94
+ }, async ({ query, top_k, domain }) => {
95
+ const result = await apiFetch("/memory/read", {
96
+ method: "POST",
97
+ body: JSON.stringify({
98
+ query,
99
+ top_k: top_k || 5,
100
+ domain: domain || undefined,
101
+ include_associations: true,
102
+ }),
103
+ });
104
+ const r = result;
105
+ if (r.items.length === 0) {
106
+ return {
107
+ content: [
108
+ { type: "text", text: "No memories found for this query." },
109
+ ],
110
+ };
111
+ }
112
+ const lines = r.items.map((item, i) => `${i + 1}. [${(item.relevance * 100).toFixed(0)}%] ${item.content}` +
113
+ (item.concepts.length > 0
114
+ ? ` (${item.concepts.join(", ")})`
115
+ : ""));
116
+ return {
117
+ content: [
118
+ {
119
+ type: "text",
120
+ text: lines.join("\n\n") + `\n\n(${r.search_time_ms.toFixed(0)}ms)`,
121
+ },
122
+ ],
123
+ };
124
+ });
125
+ // --- Tool: memory_feedback ---
126
+ server.tool("memory_feedback", "Report whether a retrieved memory was helpful. Positive feedback makes memories easier to find next time. Negative feedback lets them fade. Call this after using memories from memory_read.", {
127
+ atom_ids: z
128
+ .array(z.string())
129
+ .min(1)
130
+ .describe("IDs of memories to give feedback on (from memory_read results)"),
131
+ outcome: z
132
+ .number()
133
+ .min(-1)
134
+ .max(1)
135
+ .describe("How helpful was this? 1.0 = very helpful, 0 = neutral, -1.0 = harmful/wrong"),
136
+ }, async ({ atom_ids, outcome }) => {
137
+ const result = await apiFetch("/memory/feedback", {
138
+ method: "POST",
139
+ body: JSON.stringify({ atom_ids, outcome }),
140
+ });
141
+ const r = result;
142
+ return {
143
+ content: [
144
+ {
145
+ type: "text",
146
+ text: `Feedback recorded for ${r.updated_count} memor${r.updated_count === 1 ? "y" : "ies"}.`,
147
+ },
148
+ ],
149
+ };
150
+ });
151
+ // --- Tool: memory_stats ---
152
+ server.tool("memory_stats", "Get memory statistics — how many memories are stored, which domains exist, average quality scores. Useful for understanding the current state of memory.", {}, async () => {
153
+ const result = await apiFetch("/memory/stats");
154
+ const r = result;
155
+ const text = [
156
+ `Memories: ${r.total_atoms} (${r.episodes} episodes, ${r.prototypes} prototypes)`,
157
+ `Associations: ${r.hebbian_edges} Hebbian edges`,
158
+ `Domains: ${r.domains.length > 0 ? r.domains.join(", ") : "general"}`,
159
+ `Avg quality: valence ${r.avg_valence.toFixed(2)}, importance ${r.avg_importance.toFixed(2)}`,
160
+ ].join("\n");
161
+ return { content: [{ type: "text", text }] };
162
+ });
163
+ // --- Start ---
164
+ async function main() {
165
+ const transport = new StdioServerTransport();
166
+ await server.connect(transport);
167
+ }
168
+ main().catch((err) => {
169
+ console.error("MCP server error:", err);
170
+ process.exit(1);
171
+ });
172
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,52 @@
1
+ # Mnemoverse MCP Memory Server
2
+
3
+ > Persistent AI memory via Model Context Protocol. Store and recall memories across sessions.
4
+
5
+ ## Tools
6
+
7
+ ### memory_write
8
+ Store a memory — insight, pattern, preference, or fact. Persists across sessions.
9
+
10
+ Parameters:
11
+ - content (string, required): The memory to store — what happened, what was learned. 1-10000 chars.
12
+ - concepts (string[], optional): Key concepts for linking related memories. Example: ["deploy", "friday", "staging"]
13
+ - domain (string, optional): Namespace to organize memories. Example: "engineering", "user:alice"
14
+
15
+ Returns: {stored: boolean, atom_id: string|null, importance: number, reason: string}
16
+
17
+ ### memory_read
18
+ Search memories by natural language query. Returns most relevant stored memories ranked by relevance.
19
+
20
+ Parameters:
21
+ - query (string, required): Natural language query — what are you looking for? 1-5000 chars.
22
+ - top_k (integer, optional, default 5): Max results to return. Range: 1-50.
23
+ - domain (string, optional): Filter by domain namespace.
24
+
25
+ Returns: List of memories with relevance scores, concepts, and domain.
26
+
27
+ ### memory_feedback
28
+ Report whether a retrieved memory was helpful. Positive feedback strengthens recall. Negative lets memories fade.
29
+
30
+ Parameters:
31
+ - atom_ids (string[], required): IDs of memories to give feedback on.
32
+ - outcome (number, required): How helpful? Range: -1.0 (harmful) to 1.0 (very helpful).
33
+
34
+ Returns: {updated_count: number}
35
+
36
+ ### memory_stats
37
+ Get memory statistics — count, domains, quality scores.
38
+
39
+ Parameters: none
40
+
41
+ Returns: {total_atoms, episodes, prototypes, hebbian_edges, domains, avg_valence, avg_importance}
42
+
43
+ ## Setup
44
+ Environment: MNEMOVERSE_API_KEY (required), MNEMOVERSE_API_URL (optional, default https://core.mnemoverse.com/api/v1)
45
+ Transport: stdio
46
+ Command: npx @mnemoverse/mcp-memory-server
47
+
48
+ ## Links
49
+ - Docs: https://mnemoverse.com/docs/api/mcp-server
50
+ - API Reference: https://mnemoverse.com/docs/api/reference
51
+ - Console: https://console.mnemoverse.com
52
+ - Source: https://github.com/mnemoverse/mcp-memory-server
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@mnemoverse/mcp-memory-server",
3
+ "version": "0.1.0",
4
+ "description": "MCP server for Mnemoverse Memory API — persistent AI memory across Claude Code, Cursor, VS Code, and any MCP client",
5
+ "type": "module",
6
+ "bin": {
7
+ "mcp-memory-server": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "dev": "tsc --watch",
14
+ "start": "node dist/index.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "mcp",
19
+ "memory",
20
+ "ai",
21
+ "claude",
22
+ "cursor",
23
+ "mnemoverse",
24
+ "persistent-memory",
25
+ "model-context-protocol"
26
+ ],
27
+ "author": "Mnemoverse <hello@mnemoverse.com>",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/mnemoverse/mcp-memory-server"
32
+ },
33
+ "homepage": "https://mnemoverse.com/docs/api/mcp-server",
34
+ "dependencies": {
35
+ "@modelcontextprotocol/sdk": "^1.12.1"
36
+ },
37
+ "devDependencies": {
38
+ "typescript": "^5.8.3",
39
+ "@types/node": "^22.15.3"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ }
44
+ }
package/src/index.ts ADDED
@@ -0,0 +1,251 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { z } from "zod";
6
+
7
+ const API_URL =
8
+ process.env.MNEMOVERSE_API_URL || "https://core.mnemoverse.com/api/v1";
9
+ const API_KEY = process.env.MNEMOVERSE_API_KEY || "";
10
+
11
+ if (!API_KEY) {
12
+ console.error(
13
+ "Error: MNEMOVERSE_API_KEY environment variable is required.\n" +
14
+ "Get your free key at https://console.mnemoverse.com"
15
+ );
16
+ process.exit(1);
17
+ }
18
+
19
+ async function apiFetch(
20
+ path: string,
21
+ options: RequestInit = {}
22
+ ): Promise<unknown> {
23
+ const res = await fetch(`${API_URL}${path}`, {
24
+ ...options,
25
+ headers: {
26
+ "Content-Type": "application/json",
27
+ "X-Api-Key": API_KEY,
28
+ ...((options.headers as Record<string, string>) || {}),
29
+ },
30
+ });
31
+
32
+ if (!res.ok) {
33
+ const text = await res.text();
34
+ throw new Error(`Mnemoverse API error ${res.status}: ${text}`);
35
+ }
36
+
37
+ return res.json();
38
+ }
39
+
40
+ // --- Server setup ---
41
+
42
+ const server = new McpServer({
43
+ name: "mnemoverse-memory",
44
+ version: "0.1.0",
45
+ });
46
+
47
+ // --- Tool: memory_write ---
48
+
49
+ server.tool(
50
+ "memory_write",
51
+ "Store a memory — insight, pattern, preference, or fact. Persists across sessions. Use this when the user teaches you something worth remembering, or when you learn a lesson from a task.",
52
+ {
53
+ content: z
54
+ .string()
55
+ .min(1)
56
+ .max(10000)
57
+ .describe("The memory to store — what happened, what was learned"),
58
+ concepts: z
59
+ .array(z.string())
60
+ .optional()
61
+ .describe("Key concepts for linking related memories (e.g. ['deploy', 'friday', 'staging'])"),
62
+ domain: z
63
+ .string()
64
+ .optional()
65
+ .describe("Namespace to organize memories (e.g. 'engineering', 'user:alice', 'project:acme')"),
66
+ },
67
+ async ({ content, concepts, domain }) => {
68
+ const result = await apiFetch("/memory/write", {
69
+ method: "POST",
70
+ body: JSON.stringify({
71
+ content,
72
+ concepts: concepts || [],
73
+ domain: domain || "general",
74
+ }),
75
+ });
76
+
77
+ const r = result as {
78
+ stored: boolean;
79
+ atom_id: string | null;
80
+ importance: number;
81
+ reason: string;
82
+ };
83
+
84
+ if (r.stored) {
85
+ return {
86
+ content: [
87
+ {
88
+ type: "text" as const,
89
+ text: `Stored (importance: ${r.importance.toFixed(2)}). ID: ${r.atom_id}`,
90
+ },
91
+ ],
92
+ };
93
+ }
94
+ return {
95
+ content: [
96
+ {
97
+ type: "text" as const,
98
+ text: `Filtered — ${r.reason} (importance: ${r.importance.toFixed(2)})`,
99
+ },
100
+ ],
101
+ };
102
+ }
103
+ );
104
+
105
+ // --- Tool: memory_read ---
106
+
107
+ server.tool(
108
+ "memory_read",
109
+ "Search memories by natural language query. Returns the most relevant stored memories. Use this before starting a task to check if you already know something about it.",
110
+ {
111
+ query: z
112
+ .string()
113
+ .min(1)
114
+ .max(5000)
115
+ .describe("Natural language query — what are you looking for?"),
116
+ top_k: z
117
+ .number()
118
+ .int()
119
+ .min(1)
120
+ .max(50)
121
+ .optional()
122
+ .describe("Max results to return (default: 5)"),
123
+ domain: z
124
+ .string()
125
+ .optional()
126
+ .describe("Filter by domain namespace"),
127
+ },
128
+ async ({ query, top_k, domain }) => {
129
+ const result = await apiFetch("/memory/read", {
130
+ method: "POST",
131
+ body: JSON.stringify({
132
+ query,
133
+ top_k: top_k || 5,
134
+ domain: domain || undefined,
135
+ include_associations: true,
136
+ }),
137
+ });
138
+
139
+ const r = result as {
140
+ items: Array<{
141
+ content: string;
142
+ relevance: number;
143
+ concepts: string[];
144
+ domain: string;
145
+ }>;
146
+ search_time_ms: number;
147
+ };
148
+
149
+ if (r.items.length === 0) {
150
+ return {
151
+ content: [
152
+ { type: "text" as const, text: "No memories found for this query." },
153
+ ],
154
+ };
155
+ }
156
+
157
+ const lines = r.items.map(
158
+ (item, i) =>
159
+ `${i + 1}. [${(item.relevance * 100).toFixed(0)}%] ${item.content}` +
160
+ (item.concepts.length > 0
161
+ ? ` (${item.concepts.join(", ")})`
162
+ : "")
163
+ );
164
+
165
+ return {
166
+ content: [
167
+ {
168
+ type: "text" as const,
169
+ text: lines.join("\n\n") + `\n\n(${r.search_time_ms.toFixed(0)}ms)`,
170
+ },
171
+ ],
172
+ };
173
+ }
174
+ );
175
+
176
+ // --- Tool: memory_feedback ---
177
+
178
+ server.tool(
179
+ "memory_feedback",
180
+ "Report whether a retrieved memory was helpful. Positive feedback makes memories easier to find next time. Negative feedback lets them fade. Call this after using memories from memory_read.",
181
+ {
182
+ atom_ids: z
183
+ .array(z.string())
184
+ .min(1)
185
+ .describe("IDs of memories to give feedback on (from memory_read results)"),
186
+ outcome: z
187
+ .number()
188
+ .min(-1)
189
+ .max(1)
190
+ .describe("How helpful was this? 1.0 = very helpful, 0 = neutral, -1.0 = harmful/wrong"),
191
+ },
192
+ async ({ atom_ids, outcome }) => {
193
+ const result = await apiFetch("/memory/feedback", {
194
+ method: "POST",
195
+ body: JSON.stringify({ atom_ids, outcome }),
196
+ });
197
+
198
+ const r = result as { updated_count: number };
199
+
200
+ return {
201
+ content: [
202
+ {
203
+ type: "text" as const,
204
+ text: `Feedback recorded for ${r.updated_count} memor${r.updated_count === 1 ? "y" : "ies"}.`,
205
+ },
206
+ ],
207
+ };
208
+ }
209
+ );
210
+
211
+ // --- Tool: memory_stats ---
212
+
213
+ server.tool(
214
+ "memory_stats",
215
+ "Get memory statistics — how many memories are stored, which domains exist, average quality scores. Useful for understanding the current state of memory.",
216
+ {},
217
+ async () => {
218
+ const result = await apiFetch("/memory/stats");
219
+
220
+ const r = result as {
221
+ total_atoms: number;
222
+ episodes: number;
223
+ prototypes: number;
224
+ hebbian_edges: number;
225
+ domains: string[];
226
+ avg_valence: number;
227
+ avg_importance: number;
228
+ };
229
+
230
+ const text = [
231
+ `Memories: ${r.total_atoms} (${r.episodes} episodes, ${r.prototypes} prototypes)`,
232
+ `Associations: ${r.hebbian_edges} Hebbian edges`,
233
+ `Domains: ${r.domains.length > 0 ? r.domains.join(", ") : "general"}`,
234
+ `Avg quality: valence ${r.avg_valence.toFixed(2)}, importance ${r.avg_importance.toFixed(2)}`,
235
+ ].join("\n");
236
+
237
+ return { content: [{ type: "text" as const, text }] };
238
+ }
239
+ );
240
+
241
+ // --- Start ---
242
+
243
+ async function main() {
244
+ const transport = new StdioServerTransport();
245
+ await server.connect(transport);
246
+ }
247
+
248
+ main().catch((err) => {
249
+ console.error("MCP server error:", err);
250
+ process.exit(1);
251
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "moduleResolution": "Node16",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "declaration": true,
12
+ "sourceMap": true
13
+ },
14
+ "include": ["src/**/*"]
15
+ }