@intangle/mcp-server 1.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/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # @intangle/mcp-server
2
+
3
+ Model Context Protocol server for [Intangle](https://intangle.ai) - AI memory that persists across conversations.
4
+
5
+ ## What is Intangle?
6
+
7
+ Intangle provides persistent memory for AI assistants like Claude. Your conversations, context, and knowledge are stored and instantly accessible across all your AI interactions.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install -g @intangle/mcp-server
13
+ ```
14
+
15
+ ## Setup
16
+
17
+ 1. **Get your API key** from [intangle.app](https://intangle.app) after signing up in "Settings" -> "Connect"
18
+
19
+ 2. **Configure Claude Desktop** by adding to your `claude_desktop_config.json`:
20
+
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "intangle": {
25
+ "command": "npx",
26
+ "args": ["@intangle/mcp-server"],
27
+ "env": {
28
+ "MCP_API_KEY": "your-api-key-here",
29
+ "NEXT_APP_URL": "https://intangle.app"
30
+ }
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ > **Note**: The config file location varies by OS:
37
+ > - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
38
+ > - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
39
+ > - Linux: `~/.config/Claude/claude_desktop_config.json`
40
+
41
+ 3. **Restart Claude Desktop** to load the MCP server
42
+
43
+ ## Usage
44
+
45
+ Once configured, Claude will automatically have access to your Intangle memory. You can:
46
+
47
+ - **Store memories**: "Remember that I prefer TypeScript over JavaScript"
48
+ - **Search memories**: "What did we discuss about the authentication system?"
49
+ - **Organize with topics**: Memories are automatically tagged and organized
50
+ - **Access across conversations**: All memories persist between chat sessions
51
+
52
+ ## Available Tools
53
+
54
+ The MCP server provides these tools to Claude:
55
+
56
+ - `add_memory` - Store new memories with topics
57
+ - `search_memories` - Search across all your memories
58
+ - `get_recent_memories` - Retrieve recent memories
59
+ - `list_spaces` - View available memory spaces
60
+ - `get_space_info` - Get details about a specific space
61
+ - `get_entities` - Extract entities from memories
62
+ - `delete_memory` - Remove specific memories
63
+
64
+ ## Features
65
+
66
+ - **Multi-space support**: Organize memories into separate spaces (personal, work, projects)
67
+ - **Intelligent search**: Combines semantic search with text matching
68
+ - **Entity extraction**: Automatically identifies people, places, and concepts
69
+ - **Temporal awareness**: Tracks when events happened vs when they were recorded
70
+
71
+ ## Development
72
+
73
+ ### Local Development
74
+
75
+ ```bash
76
+ # Clone the repository
77
+ git clone https://github.com/intangle/mcp-server
78
+ cd mcp-server
79
+
80
+ # Install dependencies
81
+ npm install
82
+
83
+ # Build the TypeScript code
84
+ npm run build
85
+
86
+ # Run in development mode
87
+ npm run dev
88
+ ```
89
+
90
+ ### Environment Variables
91
+
92
+ - `MCP_API_KEY`: Your Intangle API key
93
+ - `NEXT_APP_URL`: The Intangle API endpoint (default: https://app.intangle.ai)
94
+
95
+ ## Troubleshooting
96
+
97
+ If Claude can't access your memories:
98
+
99
+ 1. Verify your API key is correct
100
+ 2. Check that the MCP server is listed in Claude's tool menu
101
+ 3. Ensure you have an active internet connection
102
+ 4. Try restarting Claude Desktop
103
+
104
+ ## Support
105
+
106
+ - Documentation: [intangle.ai/docs](https://intangle.ai/docs)
107
+ - Issues: [github.com/intangle/mcp-server/issues](https://github.com/intangle/mcp-server/issues)
108
+ - Email: support@intangle.ai
109
+
110
+ ## License
111
+
112
+ MIT
package/biome.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3
+ "vcs": {
4
+ "enabled": false,
5
+ "clientKind": "git",
6
+ "useIgnoreFile": false
7
+ },
8
+ "files": {
9
+ "ignoreUnknown": false
10
+ },
11
+ "formatter": {
12
+ "enabled": true,
13
+ "formatWithErrors": false,
14
+ "indentStyle": "space",
15
+ "indentWidth": 2,
16
+ "lineEnding": "lf",
17
+ "lineWidth": 80,
18
+ "attributePosition": "auto"
19
+ },
20
+ "linter": {
21
+ "enabled": true,
22
+ "rules": {
23
+ "recommended": true
24
+ }
25
+ },
26
+ "javascript": {
27
+ "formatter": {
28
+ "jsxQuoteStyle": "double",
29
+ "quoteProperties": "asNeeded",
30
+ "trailingCommas": "es5",
31
+ "semicolons": "asNeeded",
32
+ "arrowParentheses": "always",
33
+ "bracketSpacing": true,
34
+ "bracketSameLine": false,
35
+ "quoteStyle": "double",
36
+ "attributePosition": "auto"
37
+ }
38
+ }
39
+ }
package/dist/index.js ADDED
@@ -0,0 +1,292 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Endure MCP Server - Exposes Endure memory functionality through MCP
4
+ */
5
+ import { config } from "dotenv";
6
+ import fetch from "node-fetch";
7
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
8
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
10
+ // Load environment variables from .env and .env.local
11
+ config({ quiet: true });
12
+ config({ path: ".env.local", quiet: true });
13
+ // Base URL for API calls to Next.js app
14
+ const API_BASE_URL = process.env.NEXT_APP_URL || "https://intangle.app";
15
+ const MCP_API_KEY = process.env.MCP_API_KEY;
16
+ // No space configuration needed - AI discovers spaces dynamically
17
+ if (!MCP_API_KEY) {
18
+ console.error("Error: MCP_API_KEY environment variable is required");
19
+ console.error("Please set your Intangle API key in the Claude Desktop configuration");
20
+ process.exit(1);
21
+ }
22
+ console.log("Intangle MCP Server starting - connecting to", API_BASE_URL);
23
+ async function makeApiCall(endpoint, data) {
24
+ const response = await fetch(`${API_BASE_URL}/api/mcp/${endpoint}`, {
25
+ method: "POST",
26
+ headers: {
27
+ "Content-Type": "application/json",
28
+ Authorization: `Bearer ${MCP_API_KEY}`,
29
+ },
30
+ body: JSON.stringify(data),
31
+ });
32
+ if (!response.ok) {
33
+ throw new Error(`API call failed: ${response.status} ${response.statusText}`);
34
+ }
35
+ return response.json();
36
+ }
37
+ const server = new Server({
38
+ name: "intangle-memory",
39
+ version: "1.0.0",
40
+ }, {
41
+ capabilities: {
42
+ tools: {},
43
+ },
44
+ });
45
+ const TOOLS = [
46
+ {
47
+ name: "add_memory",
48
+ description: "Store information in the user's memory graph with flexible topics. REQUIRES space_id parameter.",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {
52
+ space_id: {
53
+ type: "string",
54
+ description: "REQUIRED: Space to store memory in (use list_spaces to see available options)",
55
+ },
56
+ title: {
57
+ type: "string",
58
+ description: "Title/summary of the memory",
59
+ },
60
+ content: {
61
+ type: "string",
62
+ description: "Detailed content of the memory",
63
+ },
64
+ topics: {
65
+ type: "array",
66
+ items: { type: "string" },
67
+ description: "Flexible topics/tags for organization (e.g., ['coding', 'react'])",
68
+ },
69
+ },
70
+ required: ["space_id", "title", "content"],
71
+ },
72
+ },
73
+ {
74
+ name: "search_memories",
75
+ description: "Search through stored memories using advanced hybrid search (semantic + text + entity relationships). ALWAYS provide either space_id OR space_ids parameter - this is mandatory for all searches.",
76
+ inputSchema: {
77
+ type: "object",
78
+ properties: {
79
+ space_id: {
80
+ type: "string",
81
+ description: "REQUIRED (or use space_ids): Space to search in (use list_spaces to see available options)",
82
+ },
83
+ space_ids: {
84
+ type: "array",
85
+ items: { type: "string" },
86
+ description: "REQUIRED (or use space_id): Multiple spaces to search across",
87
+ },
88
+ query: {
89
+ type: "string",
90
+ description: "Search query for finding relevant memories",
91
+ },
92
+ topics: {
93
+ type: "array",
94
+ items: { type: "string" },
95
+ description: "Filter by specific topics",
96
+ },
97
+ max_results: {
98
+ type: "number",
99
+ description: "Maximum number of results to return",
100
+ default: 10,
101
+ },
102
+ },
103
+ required: ["query"],
104
+ },
105
+ },
106
+ {
107
+ name: "get_recent_memories",
108
+ description: "Get the most recent memories stored in the system. REQUIRES space_id parameter.",
109
+ inputSchema: {
110
+ type: "object",
111
+ properties: {
112
+ space_id: {
113
+ type: "string",
114
+ description: "REQUIRED: Space to get memories from (use list_spaces to see available options)",
115
+ },
116
+ topics: {
117
+ type: "array",
118
+ items: { type: "string" },
119
+ description: "Filter by specific topics",
120
+ },
121
+ limit: {
122
+ type: "number",
123
+ description: "Number of recent memories to retrieve",
124
+ default: 20,
125
+ },
126
+ },
127
+ required: ["space_id"],
128
+ },
129
+ },
130
+ {
131
+ name: "get_entities",
132
+ description: "Get extracted entities (people, places, concepts) from memories",
133
+ inputSchema: {
134
+ type: "object",
135
+ properties: {
136
+ memory_id: {
137
+ type: "string",
138
+ description: "Optional memory ID to get entities for specific memory",
139
+ },
140
+ },
141
+ },
142
+ },
143
+ {
144
+ name: "delete_memory",
145
+ description: "Delete a specific memory item",
146
+ inputSchema: {
147
+ type: "object",
148
+ properties: {
149
+ memory_id: {
150
+ type: "string",
151
+ description: "ID of the memory to delete",
152
+ },
153
+ },
154
+ required: ["memory_id"],
155
+ },
156
+ },
157
+ {
158
+ name: "debug_memory_structure",
159
+ description: "Debug tool to inspect the current memory structure in the database",
160
+ inputSchema: {
161
+ type: "object",
162
+ properties: {},
163
+ },
164
+ },
165
+ {
166
+ name: "list_spaces",
167
+ description: "Get all available spaces with their descriptions and memory counts",
168
+ inputSchema: {
169
+ type: "object",
170
+ properties: {},
171
+ },
172
+ },
173
+ {
174
+ name: "get_space_info",
175
+ description: "Get detailed information about a specific space",
176
+ inputSchema: {
177
+ type: "object",
178
+ properties: {
179
+ space_id: {
180
+ type: "string",
181
+ description: "ID of space to get info for",
182
+ },
183
+ },
184
+ required: ["space_id"],
185
+ },
186
+ },
187
+ ];
188
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
189
+ tools: TOOLS,
190
+ }));
191
+ async function handleAddMemory(args) {
192
+ // Require space_id to be provided
193
+ if (!args.space_id) {
194
+ throw new Error("space_id is required. Use list_spaces to see available options.");
195
+ }
196
+ const memoryData = {
197
+ topics: [],
198
+ ...args,
199
+ };
200
+ return makeApiCall("add-memory", memoryData);
201
+ }
202
+ async function handleSearchMemories(args) {
203
+ const { space_id, space_ids, query, topics, max_results = 10, } = args;
204
+ // Require either space_id or space_ids
205
+ if (!space_id && (!space_ids || space_ids.length === 0)) {
206
+ throw new Error("Either space_id or space_ids is required. Use list_spaces to see available options.");
207
+ }
208
+ return makeApiCall("search-memories", {
209
+ space_id,
210
+ space_ids,
211
+ query,
212
+ topics,
213
+ max_results,
214
+ });
215
+ }
216
+ async function handleGetRecentMemories(args) {
217
+ const { space_id, topics, limit = 20, } = args;
218
+ // Require space_id to be provided
219
+ if (!space_id) {
220
+ throw new Error("space_id is required. Use list_spaces to see available options.");
221
+ }
222
+ return makeApiCall("get-recent-memories", {
223
+ space_id,
224
+ topics,
225
+ limit,
226
+ });
227
+ }
228
+ async function handleGetEntities(args) {
229
+ const { memory_id } = args;
230
+ return makeApiCall("get-entities", { memory_id });
231
+ }
232
+ async function handleDeleteMemory(args) {
233
+ const { memory_id } = args;
234
+ return makeApiCall("delete-memory", { memory_id });
235
+ }
236
+ async function handleDebugStructure() {
237
+ return makeApiCall("debug-structure", {});
238
+ }
239
+ async function handleListSpaces() {
240
+ return makeApiCall("list-spaces", {});
241
+ }
242
+ async function handleGetSpaceInfo(args) {
243
+ const { space_id } = args;
244
+ return makeApiCall("get-space-info", { space_id });
245
+ }
246
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
247
+ const { name, arguments: args } = request.params;
248
+ try {
249
+ let result;
250
+ switch (name) {
251
+ case "add_memory":
252
+ result = await handleAddMemory(args);
253
+ break;
254
+ case "search_memories":
255
+ result = await handleSearchMemories(args);
256
+ break;
257
+ case "get_recent_memories":
258
+ result = await handleGetRecentMemories(args);
259
+ break;
260
+ case "get_entities":
261
+ result = await handleGetEntities(args);
262
+ break;
263
+ case "delete_memory":
264
+ result = await handleDeleteMemory(args);
265
+ break;
266
+ case "debug_memory_structure":
267
+ result = await handleDebugStructure();
268
+ break;
269
+ case "list_spaces":
270
+ result = await handleListSpaces();
271
+ break;
272
+ case "get_space_info":
273
+ result = await handleGetSpaceInfo(args);
274
+ break;
275
+ default:
276
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
277
+ }
278
+ return {
279
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
280
+ };
281
+ }
282
+ catch (error) {
283
+ throw new McpError(ErrorCode.InternalError, `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`);
284
+ }
285
+ });
286
+ async function main() {
287
+ const transport = new StdioServerTransport();
288
+ await server.connect(transport);
289
+ }
290
+ main().catch(() => {
291
+ process.exit(1);
292
+ });
package/index.ts ADDED
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Endure MCP Server - Exposes Endure memory functionality through MCP
5
+ */
6
+
7
+ import { config } from "dotenv";
8
+ import fetch from "node-fetch";
9
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
10
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
11
+ import {
12
+ CallToolRequestSchema,
13
+ ErrorCode,
14
+ ListToolsRequestSchema,
15
+ McpError,
16
+ } from "@modelcontextprotocol/sdk/types.js";
17
+
18
+ // Load environment variables from .env and .env.local
19
+ config({ quiet: true });
20
+ config({ path: ".env.local", quiet: true });
21
+
22
+ // Base URL for API calls to Next.js app
23
+ const API_BASE_URL = process.env.NEXT_APP_URL || "https://intangle.app";
24
+ const MCP_API_KEY = process.env.MCP_API_KEY;
25
+
26
+ // No space configuration needed - AI discovers spaces dynamically
27
+
28
+ if (!MCP_API_KEY) {
29
+ console.error("Error: MCP_API_KEY environment variable is required");
30
+ console.error("Please set your Intangle API key in the Claude Desktop configuration");
31
+ process.exit(1);
32
+ }
33
+
34
+ console.log("Intangle MCP Server starting - connecting to", API_BASE_URL);
35
+
36
+ async function makeApiCall(endpoint: string, data: any) {
37
+ const response = await fetch(`${API_BASE_URL}/api/mcp/${endpoint}`, {
38
+ method: "POST",
39
+ headers: {
40
+ "Content-Type": "application/json",
41
+ Authorization: `Bearer ${MCP_API_KEY}`,
42
+ },
43
+ body: JSON.stringify(data),
44
+ });
45
+
46
+ if (!response.ok) {
47
+ throw new Error(
48
+ `API call failed: ${response.status} ${response.statusText}`,
49
+ );
50
+ }
51
+
52
+ return response.json();
53
+ }
54
+
55
+ const server = new Server(
56
+ {
57
+ name: "intangle-memory",
58
+ version: "1.0.0",
59
+ },
60
+ {
61
+ capabilities: {
62
+ tools: {},
63
+ },
64
+ },
65
+ );
66
+
67
+ const TOOLS = [
68
+ {
69
+ name: "add_memory",
70
+ description:
71
+ "Store information in the user's memory graph with flexible topics. REQUIRES space_id parameter.",
72
+ inputSchema: {
73
+ type: "object",
74
+ properties: {
75
+ space_id: {
76
+ type: "string",
77
+ description:
78
+ "REQUIRED: Space to store memory in (use list_spaces to see available options)",
79
+ },
80
+ title: {
81
+ type: "string",
82
+ description: "Title/summary of the memory",
83
+ },
84
+ content: {
85
+ type: "string",
86
+ description: "Detailed content of the memory",
87
+ },
88
+ topics: {
89
+ type: "array",
90
+ items: { type: "string" },
91
+ description:
92
+ "Flexible topics/tags for organization (e.g., ['coding', 'react'])",
93
+ },
94
+ },
95
+ required: ["space_id", "title", "content"],
96
+ },
97
+ },
98
+ {
99
+ name: "search_memories",
100
+ description:
101
+ "Search through stored memories using advanced hybrid search (semantic + text + entity relationships). ALWAYS provide either space_id OR space_ids parameter - this is mandatory for all searches.",
102
+ inputSchema: {
103
+ type: "object",
104
+ properties: {
105
+ space_id: {
106
+ type: "string",
107
+ description:
108
+ "REQUIRED (or use space_ids): Space to search in (use list_spaces to see available options)",
109
+ },
110
+ space_ids: {
111
+ type: "array",
112
+ items: { type: "string" },
113
+ description:
114
+ "REQUIRED (or use space_id): Multiple spaces to search across",
115
+ },
116
+ query: {
117
+ type: "string",
118
+ description: "Search query for finding relevant memories",
119
+ },
120
+ topics: {
121
+ type: "array",
122
+ items: { type: "string" },
123
+ description: "Filter by specific topics",
124
+ },
125
+ max_results: {
126
+ type: "number",
127
+ description: "Maximum number of results to return",
128
+ default: 10,
129
+ },
130
+ },
131
+ required: ["query"],
132
+ },
133
+ },
134
+ {
135
+ name: "get_recent_memories",
136
+ description:
137
+ "Get the most recent memories stored in the system. REQUIRES space_id parameter.",
138
+ inputSchema: {
139
+ type: "object",
140
+ properties: {
141
+ space_id: {
142
+ type: "string",
143
+ description:
144
+ "REQUIRED: Space to get memories from (use list_spaces to see available options)",
145
+ },
146
+ topics: {
147
+ type: "array",
148
+ items: { type: "string" },
149
+ description: "Filter by specific topics",
150
+ },
151
+ limit: {
152
+ type: "number",
153
+ description: "Number of recent memories to retrieve",
154
+ default: 20,
155
+ },
156
+ },
157
+ required: ["space_id"],
158
+ },
159
+ },
160
+ {
161
+ name: "get_entities",
162
+ description:
163
+ "Get extracted entities (people, places, concepts) from memories",
164
+ inputSchema: {
165
+ type: "object",
166
+ properties: {
167
+ memory_id: {
168
+ type: "string",
169
+ description: "Optional memory ID to get entities for specific memory",
170
+ },
171
+ },
172
+ },
173
+ },
174
+ {
175
+ name: "delete_memory",
176
+ description: "Delete a specific memory item",
177
+ inputSchema: {
178
+ type: "object",
179
+ properties: {
180
+ memory_id: {
181
+ type: "string",
182
+ description: "ID of the memory to delete",
183
+ },
184
+ },
185
+ required: ["memory_id"],
186
+ },
187
+ },
188
+ {
189
+ name: "debug_memory_structure",
190
+ description:
191
+ "Debug tool to inspect the current memory structure in the database",
192
+ inputSchema: {
193
+ type: "object",
194
+ properties: {},
195
+ },
196
+ },
197
+ {
198
+ name: "list_spaces",
199
+ description:
200
+ "Get all available spaces with their descriptions and memory counts",
201
+ inputSchema: {
202
+ type: "object",
203
+ properties: {},
204
+ },
205
+ },
206
+ {
207
+ name: "get_space_info",
208
+ description: "Get detailed information about a specific space",
209
+ inputSchema: {
210
+ type: "object",
211
+ properties: {
212
+ space_id: {
213
+ type: "string",
214
+ description: "ID of space to get info for",
215
+ },
216
+ },
217
+ required: ["space_id"],
218
+ },
219
+ },
220
+ ];
221
+
222
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
223
+ tools: TOOLS,
224
+ }));
225
+
226
+ async function handleAddMemory(args: any) {
227
+ // Require space_id to be provided
228
+ if (!args.space_id) {
229
+ throw new Error(
230
+ "space_id is required. Use list_spaces to see available options.",
231
+ );
232
+ }
233
+
234
+ const memoryData = {
235
+ topics: [],
236
+ ...args,
237
+ };
238
+ return makeApiCall("add-memory", memoryData);
239
+ }
240
+
241
+ async function handleSearchMemories(args: any) {
242
+ const {
243
+ space_id,
244
+ space_ids,
245
+ query,
246
+ topics,
247
+ max_results = 10,
248
+ } = args as {
249
+ space_id?: string;
250
+ space_ids?: string[];
251
+ query: string;
252
+ topics?: string[];
253
+ max_results?: number;
254
+ };
255
+
256
+ // Require either space_id or space_ids
257
+ if (!space_id && (!space_ids || space_ids.length === 0)) {
258
+ throw new Error(
259
+ "Either space_id or space_ids is required. Use list_spaces to see available options.",
260
+ );
261
+ }
262
+
263
+ return makeApiCall("search-memories", {
264
+ space_id,
265
+ space_ids,
266
+ query,
267
+ topics,
268
+ max_results,
269
+ });
270
+ }
271
+
272
+ async function handleGetRecentMemories(args: any) {
273
+ const {
274
+ space_id,
275
+ topics,
276
+ limit = 20,
277
+ } = args as {
278
+ space_id?: string;
279
+ topics?: string[];
280
+ limit?: number;
281
+ };
282
+
283
+ // Require space_id to be provided
284
+ if (!space_id) {
285
+ throw new Error(
286
+ "space_id is required. Use list_spaces to see available options.",
287
+ );
288
+ }
289
+
290
+ return makeApiCall("get-recent-memories", {
291
+ space_id,
292
+ topics,
293
+ limit,
294
+ });
295
+ }
296
+
297
+ async function handleGetEntities(args: any) {
298
+ const { memory_id } = args as { memory_id?: string };
299
+
300
+ return makeApiCall("get-entities", { memory_id });
301
+ }
302
+
303
+ async function handleDeleteMemory(args: any) {
304
+ const { memory_id } = args as {
305
+ memory_id: string;
306
+ };
307
+
308
+ return makeApiCall("delete-memory", { memory_id });
309
+ }
310
+
311
+ async function handleDebugStructure() {
312
+ return makeApiCall("debug-structure", {});
313
+ }
314
+
315
+ async function handleListSpaces() {
316
+ return makeApiCall("list-spaces", {});
317
+ }
318
+
319
+ async function handleGetSpaceInfo(args: any) {
320
+ const { space_id } = args as { space_id: string };
321
+ return makeApiCall("get-space-info", { space_id });
322
+ }
323
+
324
+ server.setRequestHandler(CallToolRequestSchema, async (request: any) => {
325
+ const { name, arguments: args } = request.params;
326
+
327
+ try {
328
+ let result: any;
329
+
330
+ switch (name) {
331
+ case "add_memory":
332
+ result = await handleAddMemory(args);
333
+ break;
334
+ case "search_memories":
335
+ result = await handleSearchMemories(args);
336
+ break;
337
+ case "get_recent_memories":
338
+ result = await handleGetRecentMemories(args);
339
+ break;
340
+ case "get_entities":
341
+ result = await handleGetEntities(args);
342
+ break;
343
+ case "delete_memory":
344
+ result = await handleDeleteMemory(args);
345
+ break;
346
+ case "debug_memory_structure":
347
+ result = await handleDebugStructure();
348
+ break;
349
+ case "list_spaces":
350
+ result = await handleListSpaces();
351
+ break;
352
+ case "get_space_info":
353
+ result = await handleGetSpaceInfo(args);
354
+ break;
355
+ default:
356
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
357
+ }
358
+
359
+ return {
360
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
361
+ };
362
+ } catch (error) {
363
+ throw new McpError(
364
+ ErrorCode.InternalError,
365
+ `Error executing tool ${name}: ${error instanceof Error ? error.message : String(error)}`,
366
+ );
367
+ }
368
+ });
369
+
370
+ async function main() {
371
+ const transport = new StdioServerTransport();
372
+ await server.connect(transport);
373
+ }
374
+
375
+ main().catch(() => {
376
+ process.exit(1);
377
+ });
Binary file
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@intangle/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "Model Context Protocol server for Intangle - AI memory that persists across conversations",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node dist/index.js",
9
+ "dev": "tsx watch index.ts",
10
+ "build": "tsc",
11
+ "lint": "biome check .",
12
+ "lint:fix": "biome check --fix .",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "bin": {
16
+ "intangle-mcp": "./dist/index.js"
17
+ },
18
+ "keywords": [
19
+ "mcp",
20
+ "model-context-protocol",
21
+ "claude",
22
+ "claude-code",
23
+ "ai",
24
+ "memory",
25
+ "knowledge-management",
26
+ "intangle",
27
+ "claude-desktop",
28
+ "anthropic"
29
+ ],
30
+ "author": "Intangle",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/intangle/mcp-server"
35
+ },
36
+ "homepage": "https://intangle.app",
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.0.0",
42
+ "dotenv": "^17.2.0",
43
+ "node-fetch": "^3.3.2"
44
+ },
45
+ "devDependencies": {
46
+ "@biomejs/biome": "^1.9.4",
47
+ "@types/node": "^22.0.0",
48
+ "@types/node-fetch": "^2.6.12",
49
+ "tsx": "^4.0.0",
50
+ "typescript": "^5.0.0"
51
+ }
52
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "node",
6
+ "outDir": "./dist",
7
+ "rootDir": "./",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "esModuleInterop": true,
11
+ "allowSyntheticDefaultImports": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true
15
+ },
16
+ "include": ["**/*.ts"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }