@prmichaelsen/remember-mcp 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/.env.example +65 -0
- package/AGENT.md +840 -0
- package/README.md +72 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/access-control-result-pattern.md +458 -0
- package/agent/design/action-audit-memory-types.md +637 -0
- package/agent/design/common-template-fields.md +282 -0
- package/agent/design/complete-tool-set.md +407 -0
- package/agent/design/content-types-expansion.md +521 -0
- package/agent/design/cross-database-id-strategy.md +358 -0
- package/agent/design/default-template-library.md +423 -0
- package/agent/design/firestore-wrapper-analysis.md +606 -0
- package/agent/design/llm-provider-abstraction.md +691 -0
- package/agent/design/location-handling-architecture.md +523 -0
- package/agent/design/memory-templates-design.md +364 -0
- package/agent/design/permissions-storage-architecture.md +680 -0
- package/agent/design/relationship-storage-strategy.md +361 -0
- package/agent/design/remember-mcp-implementation-tasks.md +417 -0
- package/agent/design/remember-mcp-progress.yaml +141 -0
- package/agent/design/requirements-enhancements.md +468 -0
- package/agent/design/requirements.md +56 -0
- package/agent/design/template-storage-strategy.md +412 -0
- package/agent/design/template-suggestion-system.md +853 -0
- package/agent/design/trust-escalation-prevention.md +343 -0
- package/agent/design/trust-system-implementation.md +592 -0
- package/agent/design/user-preferences.md +683 -0
- package/agent/design/weaviate-collection-strategy.md +461 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-project-foundation.md +121 -0
- package/agent/milestones/milestone-2-core-memory-system.md +150 -0
- package/agent/milestones/milestone-3-relationships-graph.md +116 -0
- package/agent/milestones/milestone-4-user-preferences.md +103 -0
- package/agent/milestones/milestone-5-template-system.md +126 -0
- package/agent/milestones/milestone-6-auth-multi-tenancy.md +124 -0
- package/agent/milestones/milestone-7-trust-permissions.md +133 -0
- package/agent/milestones/milestone-8-testing-quality.md +137 -0
- package/agent/milestones/milestone-9-deployment-documentation.md +147 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.md +1271 -0
- package/agent/patterns/firebase-admin-sdk-v8-usage.md +950 -0
- package/agent/patterns/firestore-users-pattern-best-practices.md +347 -0
- package/agent/patterns/library-services.md +454 -0
- package/agent/patterns/testing-colocated.md +316 -0
- package/agent/progress.yaml +395 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/task-1-initialize-project-structure.md +266 -0
- package/agent/tasks/task-2-install-dependencies.md +199 -0
- package/agent/tasks/task-3-setup-weaviate-client.md +330 -0
- package/agent/tasks/task-4-setup-firestore-client.md +362 -0
- package/agent/tasks/task-5-create-basic-mcp-server.md +114 -0
- package/agent/tasks/task-6-create-integration-tests.md +195 -0
- package/agent/tasks/task-7-finalize-milestone-1.md +363 -0
- package/agent/tasks/task-8-setup-utility-scripts.md +382 -0
- package/agent/tasks/task-9-create-server-factory.md +404 -0
- package/dist/config.d.ts +26 -0
- package/dist/constants/content-types.d.ts +60 -0
- package/dist/firestore/init.d.ts +14 -0
- package/dist/firestore/paths.d.ts +53 -0
- package/dist/firestore/paths.spec.d.ts +2 -0
- package/dist/server-factory.d.ts +40 -0
- package/dist/server-factory.js +1741 -0
- package/dist/server-factory.spec.d.ts +2 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.js +1690 -0
- package/dist/tools/create-memory.d.ts +94 -0
- package/dist/tools/delete-memory.d.ts +47 -0
- package/dist/tools/search-memory.d.ts +88 -0
- package/dist/types/memory.d.ts +183 -0
- package/dist/utils/logger.d.ts +7 -0
- package/dist/weaviate/client.d.ts +39 -0
- package/dist/weaviate/client.spec.d.ts +2 -0
- package/dist/weaviate/schema.d.ts +29 -0
- package/esbuild.build.js +60 -0
- package/esbuild.watch.js +25 -0
- package/jest.config.js +31 -0
- package/jest.e2e.config.js +17 -0
- package/package.json +68 -0
- package/src/.gitkeep +0 -0
- package/src/config.ts +56 -0
- package/src/constants/content-types.ts +454 -0
- package/src/firestore/init.ts +68 -0
- package/src/firestore/paths.spec.ts +75 -0
- package/src/firestore/paths.ts +124 -0
- package/src/server-factory.spec.ts +60 -0
- package/src/server-factory.ts +215 -0
- package/src/server.ts +243 -0
- package/src/tools/create-memory.ts +198 -0
- package/src/tools/delete-memory.ts +126 -0
- package/src/tools/search-memory.ts +216 -0
- package/src/types/memory.ts +276 -0
- package/src/utils/logger.ts +42 -0
- package/src/weaviate/client.spec.ts +58 -0
- package/src/weaviate/client.ts +114 -0
- package/src/weaviate/schema.ts +288 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
# Location Handling Architecture
|
|
2
|
+
|
|
3
|
+
**Concept**: Location data provided by tenant platform via cookies/headers
|
|
4
|
+
**Created**: 2026-02-11
|
|
5
|
+
**Status**: Design Specification
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Location data (GPS coordinates and address) will be provided by the tenant platform (agentbase.me) and passed to the remember-mcp server with each request. The MCP server does not determine location itself.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Architecture
|
|
16
|
+
|
|
17
|
+
### Request Flow
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
21
|
+
│ User's Browser/Mobile App │
|
|
22
|
+
│ - GPS coordinates from device │
|
|
23
|
+
│ - Address from geocoding service │
|
|
24
|
+
│ - Stored in cookies/local storage │
|
|
25
|
+
└────────────────────┬────────────────────────────────────────┘
|
|
26
|
+
│
|
|
27
|
+
│ HTTP Request with headers/cookies
|
|
28
|
+
│
|
|
29
|
+
┌────────────────────▼────────────────────────────────────────┐
|
|
30
|
+
│ agentbase.me Platform (Tenant Platform) │
|
|
31
|
+
│ - Reads location from cookies │
|
|
32
|
+
│ - Validates location data │
|
|
33
|
+
│ - Includes in MCP request context │
|
|
34
|
+
└────────────────────┬────────────────────────────────────────┘
|
|
35
|
+
│
|
|
36
|
+
│ MCP Request with location context
|
|
37
|
+
│
|
|
38
|
+
┌────────────────────▼────────────────────────────────────────┐
|
|
39
|
+
│ remember-mcp Server │
|
|
40
|
+
│ - Receives location in request context │
|
|
41
|
+
│ - Stores location with memory │
|
|
42
|
+
│ - Uses location for search/filtering │
|
|
43
|
+
└─────────────────────────────────────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Request Context Structure
|
|
49
|
+
|
|
50
|
+
### Location in Request Context
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
RequestContext {
|
|
54
|
+
// Authentication
|
|
55
|
+
user_id: string;
|
|
56
|
+
auth_token: string;
|
|
57
|
+
|
|
58
|
+
// Location (provided by platform)
|
|
59
|
+
location: {
|
|
60
|
+
// GPS Coordinates
|
|
61
|
+
gps: {
|
|
62
|
+
latitude: float; // e.g., 37.7749
|
|
63
|
+
longitude: float; // e.g., -122.4194
|
|
64
|
+
accuracy: float; // Accuracy in meters
|
|
65
|
+
altitude?: float; // Optional altitude
|
|
66
|
+
timestamp: datetime; // When location was captured
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Address (from geocoding)
|
|
70
|
+
address: {
|
|
71
|
+
formatted: string; // "123 Main St, San Francisco, CA 94102"
|
|
72
|
+
street?: string;
|
|
73
|
+
city?: string;
|
|
74
|
+
state?: string;
|
|
75
|
+
country?: string;
|
|
76
|
+
postal_code?: string;
|
|
77
|
+
timezone?: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Metadata
|
|
81
|
+
source: string; // "gps", "ip", "manual", "cached"
|
|
82
|
+
confidence: float; // 0-1, how confident in location accuracy
|
|
83
|
+
is_approximate: boolean; // True if using IP-based location
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Locale (provided by platform via cookie)
|
|
87
|
+
locale: {
|
|
88
|
+
language: string; // e.g., "en", "es", "fr", "ja"
|
|
89
|
+
country: string; // e.g., "US", "GB", "FR", "JP"
|
|
90
|
+
full_locale: string; // e.g., "en-US", "es-MX", "fr-FR"
|
|
91
|
+
timezone: string; // e.g., "America/Los_Angeles"
|
|
92
|
+
currency: string; // e.g., "USD", "EUR", "JPY"
|
|
93
|
+
date_format: string; // e.g., "MM/DD/YYYY", "DD/MM/YYYY"
|
|
94
|
+
time_format: string; // e.g., "12h", "24h"
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Other context
|
|
98
|
+
timestamp: datetime;
|
|
99
|
+
device_info: object;
|
|
100
|
+
session_id: string;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Platform Responsibilities (agentbase.me)
|
|
107
|
+
|
|
108
|
+
### 1. **Location Capture**
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Browser/Mobile App
|
|
112
|
+
class LocationService {
|
|
113
|
+
async getCurrentLocation(): Promise<Location> {
|
|
114
|
+
// Get GPS from device
|
|
115
|
+
const position = await navigator.geolocation.getCurrentPosition();
|
|
116
|
+
|
|
117
|
+
// Geocode to address
|
|
118
|
+
const address = await geocodeCoordinates(
|
|
119
|
+
position.coords.latitude,
|
|
120
|
+
position.coords.longitude
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
gps: {
|
|
125
|
+
latitude: position.coords.latitude,
|
|
126
|
+
longitude: position.coords.longitude,
|
|
127
|
+
accuracy: position.coords.accuracy,
|
|
128
|
+
timestamp: new Date()
|
|
129
|
+
},
|
|
130
|
+
address: address,
|
|
131
|
+
source: "gps",
|
|
132
|
+
confidence: 1.0,
|
|
133
|
+
is_approximate: false
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Fallback to IP-based location
|
|
138
|
+
async getApproximateLocation(): Promise<Location> {
|
|
139
|
+
const ipLocation = await getLocationFromIP();
|
|
140
|
+
return {
|
|
141
|
+
gps: ipLocation.coordinates,
|
|
142
|
+
address: ipLocation.address,
|
|
143
|
+
source: "ip",
|
|
144
|
+
confidence: 0.5,
|
|
145
|
+
is_approximate: true
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 2. **Location Storage**
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// Store in cookies for persistence
|
|
155
|
+
setCookie('user_location', JSON.stringify(location), {
|
|
156
|
+
maxAge: 3600, // 1 hour
|
|
157
|
+
secure: true,
|
|
158
|
+
sameSite: 'strict'
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Or in localStorage
|
|
162
|
+
localStorage.setItem('user_location', JSON.stringify(location));
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 3. **Location Injection**
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// When making MCP request
|
|
169
|
+
async function callMCPServer(tool: string, args: object) {
|
|
170
|
+
// Read location from cookies/storage
|
|
171
|
+
const location = getStoredLocation();
|
|
172
|
+
|
|
173
|
+
// Include in request context
|
|
174
|
+
const context = {
|
|
175
|
+
user_id: getCurrentUserId(),
|
|
176
|
+
auth_token: getAuthToken(),
|
|
177
|
+
location: location,
|
|
178
|
+
timestamp: new Date(),
|
|
179
|
+
device_info: getDeviceInfo(),
|
|
180
|
+
session_id: getSessionId()
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// Send to MCP server
|
|
184
|
+
return await mcpClient.callTool(tool, args, context);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## MCP Server Responsibilities (remember-mcp)
|
|
191
|
+
|
|
192
|
+
### 1. **Location Extraction**
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// In mcp-auth wrapper or server factory
|
|
196
|
+
function extractLocation(context: RequestContext): Location | null {
|
|
197
|
+
if (!context.location) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Validate location data
|
|
202
|
+
if (!isValidLocation(context.location)) {
|
|
203
|
+
logger.warn('Invalid location data received', { context });
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return context.location;
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 2. **Memory Creation with Location**
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// remember_create_memory tool
|
|
215
|
+
async function createMemory(args: CreateMemoryArgs, context: RequestContext) {
|
|
216
|
+
const location = extractLocation(context);
|
|
217
|
+
|
|
218
|
+
const memory = {
|
|
219
|
+
user_id: context.user_id,
|
|
220
|
+
content: args.content,
|
|
221
|
+
|
|
222
|
+
// Location from context
|
|
223
|
+
location: location || {
|
|
224
|
+
gps: null,
|
|
225
|
+
address: null,
|
|
226
|
+
source: "unavailable"
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
// Other fields...
|
|
230
|
+
created_at: new Date(),
|
|
231
|
+
context: {
|
|
232
|
+
conversation_id: args.conversation_id,
|
|
233
|
+
timestamp: context.timestamp,
|
|
234
|
+
// Location context
|
|
235
|
+
location_at_creation: location
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
return await weaviateClient.addDocument(memory);
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### 3. **Location-Based Search**
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// remember_search_memory with location filter
|
|
247
|
+
async function searchMemory(args: SearchMemoryArgs, context: RequestContext) {
|
|
248
|
+
const currentLocation = extractLocation(context);
|
|
249
|
+
|
|
250
|
+
if (args.filters?.near_current_location && currentLocation) {
|
|
251
|
+
// Search memories near current location
|
|
252
|
+
args.filters.location = {
|
|
253
|
+
near: currentLocation.gps,
|
|
254
|
+
radius_meters: args.filters.radius || 1000
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return await weaviateClient.searchDocuments(args);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Location Privacy & Security
|
|
265
|
+
|
|
266
|
+
### 1. **User Consent**
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
// Platform must get user consent
|
|
270
|
+
interface LocationPermissions {
|
|
271
|
+
enabled: boolean;
|
|
272
|
+
precision: 'exact' | 'approximate' | 'city' | 'none';
|
|
273
|
+
share_with_memories: boolean;
|
|
274
|
+
auto_update: boolean;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// User can control location sharing
|
|
278
|
+
const permissions = await getUserLocationPermissions(user_id);
|
|
279
|
+
|
|
280
|
+
if (!permissions.share_with_memories) {
|
|
281
|
+
// Don't include location in MCP requests
|
|
282
|
+
context.location = null;
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### 2. **Location Obfuscation**
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
// For privacy, user can choose to obfuscate location
|
|
290
|
+
function obfuscateLocation(location: Location, precision: string): Location {
|
|
291
|
+
switch (precision) {
|
|
292
|
+
case 'exact':
|
|
293
|
+
return location; // Full precision
|
|
294
|
+
|
|
295
|
+
case 'approximate':
|
|
296
|
+
// Round to ~100m precision
|
|
297
|
+
return {
|
|
298
|
+
...location,
|
|
299
|
+
gps: {
|
|
300
|
+
latitude: Math.round(location.gps.latitude * 1000) / 1000,
|
|
301
|
+
longitude: Math.round(location.gps.longitude * 1000) / 1000,
|
|
302
|
+
accuracy: 100
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
case 'city':
|
|
307
|
+
// Only city-level
|
|
308
|
+
return {
|
|
309
|
+
gps: null,
|
|
310
|
+
address: {
|
|
311
|
+
city: location.address.city,
|
|
312
|
+
state: location.address.state,
|
|
313
|
+
country: location.address.country
|
|
314
|
+
},
|
|
315
|
+
is_approximate: true
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
case 'none':
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### 3. **Location Validation**
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// MCP server validates location data
|
|
328
|
+
function isValidLocation(location: Location): boolean {
|
|
329
|
+
// Check GPS coordinates are valid
|
|
330
|
+
if (location.gps) {
|
|
331
|
+
if (location.gps.latitude < -90 || location.gps.latitude > 90) {
|
|
332
|
+
return false;
|
|
333
|
+
}
|
|
334
|
+
if (location.gps.longitude < -180 || location.gps.longitude > 180) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Check timestamp is recent (within 1 hour)
|
|
340
|
+
if (location.gps?.timestamp) {
|
|
341
|
+
const age = Date.now() - new Date(location.gps.timestamp).getTime();
|
|
342
|
+
if (age > 3600000) { // 1 hour
|
|
343
|
+
logger.warn('Location data is stale', { age });
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Location Update Strategies
|
|
355
|
+
|
|
356
|
+
### 1. **Real-Time Updates**
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// Platform continuously updates location
|
|
360
|
+
setInterval(async () => {
|
|
361
|
+
const location = await locationService.getCurrentLocation();
|
|
362
|
+
updateStoredLocation(location);
|
|
363
|
+
}, 60000); // Every minute
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 2. **On-Demand Updates**
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// Update location only when creating memory
|
|
370
|
+
async function createMemoryWithFreshLocation(args: CreateMemoryArgs) {
|
|
371
|
+
// Get fresh location
|
|
372
|
+
const location = await locationService.getCurrentLocation();
|
|
373
|
+
|
|
374
|
+
// Update stored location
|
|
375
|
+
updateStoredLocation(location);
|
|
376
|
+
|
|
377
|
+
// Create memory with fresh location
|
|
378
|
+
return await mcpClient.callTool('remember_create_memory', args, {
|
|
379
|
+
...context,
|
|
380
|
+
location
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### 3. **Cached with Expiry**
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
// Use cached location if recent enough
|
|
389
|
+
function getLocationForRequest(): Location | null {
|
|
390
|
+
const cached = getStoredLocation();
|
|
391
|
+
|
|
392
|
+
if (!cached) return null;
|
|
393
|
+
|
|
394
|
+
const age = Date.now() - new Date(cached.gps.timestamp).getTime();
|
|
395
|
+
|
|
396
|
+
// Use cached if < 5 minutes old
|
|
397
|
+
if (age < 300000) {
|
|
398
|
+
return cached;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Otherwise fetch fresh
|
|
402
|
+
return await locationService.getCurrentLocation();
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Benefits of Platform-Provided Location
|
|
409
|
+
|
|
410
|
+
### 1. **Separation of Concerns**
|
|
411
|
+
- MCP server focuses on memory management
|
|
412
|
+
- Platform handles location capture and privacy
|
|
413
|
+
- Clear responsibility boundaries
|
|
414
|
+
|
|
415
|
+
### 2. **Consistency**
|
|
416
|
+
- Same location data across all platform features
|
|
417
|
+
- Single source of truth for user location
|
|
418
|
+
- Consistent privacy controls
|
|
419
|
+
|
|
420
|
+
### 3. **Flexibility**
|
|
421
|
+
- Platform can use different location sources (GPS, WiFi, IP)
|
|
422
|
+
- Can implement platform-specific privacy rules
|
|
423
|
+
- Can cache and optimize location requests
|
|
424
|
+
|
|
425
|
+
### 4. **Security**
|
|
426
|
+
- Location permissions managed by platform
|
|
427
|
+
- No direct device access from MCP server
|
|
428
|
+
- Platform validates and sanitizes location data
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Implementation Checklist
|
|
433
|
+
|
|
434
|
+
### Platform (agentbase.me)
|
|
435
|
+
- [ ] Implement location capture service
|
|
436
|
+
- [ ] Store location in cookies/localStorage
|
|
437
|
+
- [ ] Add location to MCP request context
|
|
438
|
+
- [ ] Implement location privacy controls
|
|
439
|
+
- [ ] Add location obfuscation options
|
|
440
|
+
- [ ] Handle location permission denials
|
|
441
|
+
|
|
442
|
+
### MCP Server (remember-mcp)
|
|
443
|
+
- [ ] Extract location from request context
|
|
444
|
+
- [ ] Validate location data
|
|
445
|
+
- [ ] Store location with memories
|
|
446
|
+
- [ ] Implement location-based search
|
|
447
|
+
- [ ] Add location to context schema
|
|
448
|
+
- [ ] Handle missing location gracefully
|
|
449
|
+
|
|
450
|
+
### Testing
|
|
451
|
+
- [ ] Test with GPS location
|
|
452
|
+
- [ ] Test with IP-based location
|
|
453
|
+
- [ ] Test with no location
|
|
454
|
+
- [ ] Test location privacy levels
|
|
455
|
+
- [ ] Test stale location handling
|
|
456
|
+
- [ ] Test invalid location data
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Example: Complete Flow
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
// 1. User creates memory in browser
|
|
464
|
+
async function createMemoryInBrowser(content: string) {
|
|
465
|
+
// Platform gets current location
|
|
466
|
+
const location = await locationService.getCurrentLocation();
|
|
467
|
+
// Result: { gps: { lat: 37.7749, lng: -122.4194 }, address: "San Francisco, CA" }
|
|
468
|
+
|
|
469
|
+
// Platform stores in cookie
|
|
470
|
+
setCookie('user_location', JSON.stringify(location));
|
|
471
|
+
|
|
472
|
+
// Platform calls MCP server
|
|
473
|
+
const result = await mcpClient.callTool('remember_create_memory', {
|
|
474
|
+
content: content,
|
|
475
|
+
type: "note"
|
|
476
|
+
}, {
|
|
477
|
+
user_id: "user_123",
|
|
478
|
+
auth_token: "firebase_jwt_token",
|
|
479
|
+
location: location, // <-- Location included here
|
|
480
|
+
timestamp: new Date()
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
return result;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// 2. MCP server receives and processes
|
|
487
|
+
async function handleCreateMemory(args: any, context: RequestContext) {
|
|
488
|
+
// Extract location from context
|
|
489
|
+
const location = context.location;
|
|
490
|
+
// Result: { gps: { lat: 37.7749, lng: -122.4194 }, address: "San Francisco, CA" }
|
|
491
|
+
|
|
492
|
+
// Create memory with location
|
|
493
|
+
const memory = {
|
|
494
|
+
user_id: context.user_id,
|
|
495
|
+
content: args.content,
|
|
496
|
+
location: location, // <-- Stored with memory
|
|
497
|
+
created_at: new Date()
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
await weaviateClient.addDocument(memory);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// 3. Later: Search memories near current location
|
|
504
|
+
async function searchNearby() {
|
|
505
|
+
const currentLocation = getStoredLocation();
|
|
506
|
+
|
|
507
|
+
const results = await mcpClient.callTool('remember_search_memory', {
|
|
508
|
+
query: "restaurants",
|
|
509
|
+
filters: {
|
|
510
|
+
near_location: currentLocation.gps,
|
|
511
|
+
radius_meters: 5000 // 5km radius
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
// Returns memories created near current location
|
|
516
|
+
}
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
---
|
|
520
|
+
|
|
521
|
+
**Status**: Design Specification
|
|
522
|
+
**Implementation**: Platform provides location, MCP server consumes it
|
|
523
|
+
**Privacy**: User controls location precision and sharing
|