@digitalsamba/embedded-api-mcp-server
Version:
Digital Samba Embedded API MCP Server - Model Context Protocol server for Digital Samba's Embedded API
262 lines • 11.3 kB
JavaScript
/**
* Digital Samba MCP Server - Content Resources
*
* This module implements read-only resources for accessing content libraries,
* folders, files, and hierarchies within Digital Samba.
*
* Resources provided:
* - libraries: List all content libraries
* - library: Get details of a specific library
* - library-hierarchy: Get complete hierarchy of a library
* - library-folders: List folders in a library
* - library-folder: Get details of a specific folder
* - library-files: List files in a library
* - library-file: Get details of a specific file
*
* @module resources/content
* @author Digital Samba Team
* @version 1.0.0
*/
// External dependencies
// import { z } from 'zod'; // Removed: unused
// MCP SDK imports
// import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; // TODO: Direct MCP server integration
import { ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
import logger from "../../logger.js";
/**
* Register content resources
*
* @returns Array of MCP Resource definitions
*/
export function registerContentResources() {
return [
{
uri: "digitalsamba://libraries",
name: "libraries",
description: '[Content Data] List all content libraries in your account. Use to access: "show libraries", "content libraries", "file storage", "document libraries", "content repositories". Returns array of library objects with names, IDs, and file counts. Browse available content storage spaces.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}",
name: "library",
description: '[Content Data] Get detailed information about a specific library. Use to access: "library details", "library info", "content library settings", "library configuration", "library metadata". Requires library ID. Returns complete library information and statistics.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}/hierarchy",
name: "library-hierarchy",
description: '[Content Data] Get complete folder and file hierarchy of a library. Use to access: "library structure", "folder tree", "content organization", "library hierarchy", "folder structure". Requires library ID. Returns nested structure showing all folders and their relationships.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}/folders",
name: "library-folders",
description: '[Content Data] List all folders in a library. Use to access: "library folders", "content folders", "folder list", "library directories", "folder directory". Requires library ID. Returns flat list of all folders with names, IDs, and parent relationships.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}/folders/{folderId}",
name: "library-folder",
description: '[Content Data] Get details of a specific folder in a library. Use to access: "folder details", "folder info", "folder contents", "folder metadata", "specific folder data". Requires library ID and folder ID. Returns folder information and contained files.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}/files",
name: "library-files",
description: '[Content Data] List all files in a library. Use to access: "library files", "content files", "file list", "uploaded files", "document list". Requires library ID. Returns array of file objects with names, sizes, types, and folder locations.',
mimeType: "application/json",
},
{
uri: "digitalsamba://libraries/{id}/files/{fileId}",
name: "library-file",
description: '[Content Data] Get detailed information about a specific file. Use to access: "file details", "file info", "file metadata", "document info", "file properties". Requires library ID and file ID. Returns complete file information including size, type, upload date, and access URLs.',
mimeType: "application/json",
},
];
}
/**
* Handle content resource requests
*
* @param {string} uri - The resource URI
* @param {DigitalSambaApiClient} apiClient - The Digital Samba API client
* @returns {Promise<any>} The resource content
*/
export async function handleContentResource(uri, apiClient) {
const parts = uri.split("/");
// Parse library ID from URI like digitalsamba://libraries/{id}
const getLibraryId = () => {
const libraryIndex = parts.indexOf("libraries");
return libraryIndex !== -1 && parts[libraryIndex + 1]
? parts[libraryIndex + 1]
: null;
};
// Parse folder ID from URI like digitalsamba://libraries/{id}/folders/{folderId}
const getFolderId = () => {
const folderIndex = parts.indexOf("folders");
return folderIndex !== -1 && parts[folderIndex + 1]
? parts[folderIndex + 1]
: null;
};
// Parse file ID from URI like digitalsamba://libraries/{id}/files/{fileId}
const getFileId = () => {
const fileIndex = parts.indexOf("files");
return fileIndex !== -1 && parts[fileIndex + 1]
? parts[fileIndex + 1]
: null;
};
try {
// List all libraries
if (uri === "digitalsamba://libraries") {
logger.info("Listing all libraries");
const response = await apiClient.listLibraries({ limit: 100 });
return {
content: [
{
type: "text",
text: JSON.stringify({
libraries: response.data,
total_count: response.total_count,
summary: `Found ${response.data.length} libraries`,
}, null, 2),
},
],
};
}
const libraryId = getLibraryId();
if (!libraryId) {
throw new McpError(ErrorCode.InvalidRequest, "Invalid resource URI format");
}
// Get library hierarchy
if (uri.includes("/hierarchy")) {
logger.info("Getting library hierarchy", { libraryId });
const hierarchy = await apiClient.getLibraryHierarchy(libraryId);
return {
content: [
{
type: "text",
text: JSON.stringify({
library_id: libraryId,
hierarchy: hierarchy,
summary: "Complete library hierarchy retrieved",
}, null, 2),
},
],
};
}
// Get specific folder
const folderId = getFolderId();
if (folderId) {
logger.info("Getting folder details", { libraryId, folderId });
const folder = await apiClient.getLibraryFolder(libraryId, folderId);
return {
content: [
{
type: "text",
text: JSON.stringify({
library_id: libraryId,
folder: folder,
summary: `Folder details for ID: ${folderId}`,
}, null, 2),
},
],
};
}
// List library folders
if (uri.includes("/folders")) {
logger.info("Listing library folders", { libraryId });
const response = await apiClient.listLibraryFolders(libraryId, {
limit: 100,
});
return {
content: [
{
type: "text",
text: JSON.stringify({
library_id: libraryId,
folders: response.data,
total_count: response.total_count,
summary: `Found ${response.data.length} folders in library`,
}, null, 2),
},
],
};
}
// Get specific file
const fileId = getFileId();
if (fileId) {
logger.info("Getting file details", { libraryId, fileId });
const file = await apiClient.getLibraryFile(libraryId, fileId);
return {
content: [
{
type: "text",
text: JSON.stringify({
library_id: libraryId,
file: file,
summary: `File details for ID: ${fileId}`,
}, null, 2),
},
],
};
}
// List library files
if (uri.includes("/files")) {
logger.info("Listing library files", { libraryId });
const files = await apiClient.listLibraryFiles(libraryId, { limit: 100 });
return {
content: [
{
type: "text",
text: JSON.stringify({
library_id: libraryId,
files: files,
total_count: files.length,
summary: `Found ${files.length} files in library`,
}, null, 2),
},
],
};
}
// Get specific library
logger.info("Getting library details", { libraryId });
const library = await apiClient.getLibrary(libraryId);
return {
content: [
{
type: "text",
text: JSON.stringify({
library: library,
summary: `Library details for ID: ${libraryId}`,
}, null, 2),
},
],
};
}
catch (error) {
logger.error("Error handling content resource", {
uri,
error: error instanceof Error ? error.message : String(error),
});
const errorMessage = error instanceof Error ? error.message : String(error);
let displayMessage = `Error accessing content resource: ${errorMessage}`;
if (errorMessage.includes("404") || errorMessage.includes("not found")) {
displayMessage = `Resource not found: ${uri}`;
}
else if (errorMessage.includes("401") || errorMessage.includes("403")) {
displayMessage = "Authentication failed. Please check your API key.";
}
return {
content: [
{
type: "text",
text: JSON.stringify({
error: displayMessage,
uri: uri,
timestamp: new Date().toISOString(),
}, null, 2),
},
],
};
}
}
//# sourceMappingURL=index.js.map