limitless-ai-mcp-server
Version:
MCP server for integrating Limitless AI Pendant recordings with AI assistants
134 lines • 4.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResourceManager = void 0;
const logger_1 = require("../utils/logger");
class ResourceManager {
client;
static RESOURCE_TEMPLATES = [
{
uriTemplate: 'lifelog://recent',
name: 'Recent Lifelogs',
description: 'Access recent lifelog recordings',
mimeType: 'application/json',
},
{
uriTemplate: 'lifelog://{date}',
name: 'Lifelogs by Date',
description: 'Access lifelogs from a specific date (YYYY-MM-DD)',
mimeType: 'application/json',
},
{
uriTemplate: 'lifelog://{date}/{id}',
name: 'Specific Lifelog',
description: 'Access a specific lifelog by date and ID',
mimeType: 'application/json',
},
];
constructor(client) {
this.client = client;
}
/**
* List available resources based on the URI pattern
*/
async listResources(uri) {
logger_1.logger.debug('Listing resources', { uri });
if (!uri || uri === 'lifelog://') {
// Return templates when listing root
return ResourceManager.RESOURCE_TEMPLATES.map((template) => ({
uri: template.uriTemplate,
name: template.name,
description: template.description,
mimeType: template.mimeType,
}));
}
const resources = [];
// Handle different URI patterns
if (uri === 'lifelog://recent') {
// List recent lifelogs as resources
const lifelogs = await this.client.listRecentLifelogs({ limit: 20 });
resources.push(...this.lifelogsToResources(lifelogs));
}
else if (uri.match(/^lifelog:\/\/\d{4}-\d{2}-\d{2}$/)) {
// List lifelogs for a specific date
const date = uri.replace('lifelog://', '');
const lifelogs = await this.client.listLifelogsByDate(date);
resources.push(...this.lifelogsToResources(lifelogs, date));
}
return resources;
}
/**
* Read a specific resource by URI
*/
async readResource(uri) {
logger_1.logger.debug('Reading resource', { uri });
// Parse URI patterns
const recentMatch = uri.match(/^lifelog:\/\/recent$/);
const dateMatch = uri.match(/^lifelog:\/\/(\d{4}-\d{2}-\d{2})$/);
const specificMatch = uri.match(/^lifelog:\/\/(\d{4}-\d{2}-\d{2})\/(.+)$/);
if (recentMatch) {
// Return recent lifelogs
return await this.client.listRecentLifelogs({ limit: 10 });
}
else if (dateMatch) {
// Return all lifelogs for a date
const date = dateMatch[1];
return await this.client.listLifelogsByDate(date);
}
else if (specificMatch) {
// Return specific lifelog
const [, date, id] = specificMatch;
// First get lifelogs for the date to find the specific one
const lifelogs = await this.client.listLifelogsByDate(date);
const lifelog = lifelogs.find((log) => log.id === id);
if (!lifelog) {
logger_1.logger.warn('Lifelog not found', { uri, date, id });
return null;
}
// Get full details
return await this.client.getLifelogById(id);
}
logger_1.logger.warn('Unknown resource URI pattern', { uri });
return null;
}
/**
* Get resource templates
*/
getTemplates() {
return ResourceManager.RESOURCE_TEMPLATES;
}
/**
* Convert lifelogs to resources
*/
lifelogsToResources(lifelogs, datePrefix) {
return lifelogs.map((lifelog) => {
const date = datePrefix || lifelog.startTime.split('T')[0];
return {
uri: `lifelog://${date}/${lifelog.id}`,
name: lifelog.title,
description: `Lifelog from ${lifelog.startTime} to ${lifelog.endTime}`,
mimeType: 'application/json',
metadata: {
id: lifelog.id,
startTime: lifelog.startTime,
endTime: lifelog.endTime,
hasMarkdown: !!lifelog.markdown,
contentCount: lifelog.contents?.length || 0,
},
};
});
}
/**
* Validate a resource URI
*/
isValidUri(uri) {
const patterns = [
/^lifelog:\/\/$/,
/^lifelog:\/\/recent$/,
/^lifelog:\/\/\d{4}-\d{2}-\d{2}$/,
/^lifelog:\/\/\d{4}-\d{2}-\d{2}\/.+$/,
];
return patterns.some((pattern) => pattern.test(uri));
}
}
exports.ResourceManager = ResourceManager;
//# sourceMappingURL=manager.js.map