Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3948cd6966 | |||
| cef658ce19 |
@@ -73,6 +73,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Comprehensive input schema definitions
|
||||
- Security audit of parameter handling
|
||||
|
||||
## [1.1.9] - 2026-04-30
|
||||
|
||||
### Fixed
|
||||
- **Images returned as MCP image content type**: Updated binary file handling so image files (PNG, JPG, JPEG, GIF, WEBP, SVG) are returned as `{ type: "image", data: "<base64>", mimeType: "..." }` per the MCP 2025-11-25 spec for image content in tool results
|
||||
- Non-image binary files (PDF, ZIP, DOCX, etc.) continue to use the embedded resource format `{ type: "resource", resource: { uri, mimeType, blob } }`
|
||||
|
||||
## [1.1.8] - 2026-04-30
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": "0.3",
|
||||
"name": "obsidian-mcp",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.9",
|
||||
"display_name": "Obsidian CLI Bundle",
|
||||
"description": "MCP Bundle for Obsidian CLI - Enable AI assistants to manage Obsidian vaults through conversational interface",
|
||||
"long_description": "This MCP bundle provides a comprehensive set of tools for AI assistants to interact with and manage Obsidian vaults. It includes capabilities for creating, reading, updating, and deleting notes, managing links and tags, handling tasks, and more. With this bundle, AI assistants can seamlessly integrate with Obsidian to help users organize their knowledge and workflows.",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "obsidian-mcp",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.9",
|
||||
"description": "MCP Bundle for Obsidian CLI - Enable AI assistants to manage Obsidian vaults through Model Context Protocol",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -64,6 +64,10 @@ function getMimeType(filePath: string): string {
|
||||
return MIME_TYPES[ext] ?? 'application/octet-stream';
|
||||
}
|
||||
|
||||
function isImageMimeType(mimeType: string): boolean {
|
||||
return mimeType.startsWith('image/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all file operation tools
|
||||
*/
|
||||
@@ -175,7 +179,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
|
||||
// T031: Read note tool
|
||||
server.registerTool(
|
||||
'obsidian_read_note',
|
||||
'Read the content of a note from the Obsidian vault. Specify either the note name (file) or full path (path). For large files (e.g. PDFs), use max_chars and offset to read in chunks and avoid exceeding context limits. Binary files (ZIP, images, PDFs, etc.) are automatically detected and returned as an MCP embedded resource with a uri, mimeType, and base64-encoded blob field instead of plain text.',
|
||||
'Read the content of a note from the Obsidian vault. Specify either the note name (file) or full path (path). For large files (e.g. PDFs), use max_chars and offset to read in chunks and avoid exceeding context limits. Binary files are automatically detected: images (PNG, JPG, GIF, WEBP, SVG) are returned as MCP image content (type: "image") with base64-encoded data and mimeType; all other binary files (ZIP, PDF, DOCX, etc.) are returned as MCP embedded resource content (type: "resource") with uri, mimeType, and base64-encoded blob.',
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -198,7 +202,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
|
||||
},
|
||||
},
|
||||
createToolHandler(
|
||||
'Read the content of a note. Binary files are returned as an MCP embedded resource (type: "resource") with uri, mimeType, and a base64-encoded blob field.',
|
||||
'Read the content of a note. Images (PNG, JPG, GIF, WEBP, SVG) are returned as MCP image content (type: "image") with base64-encoded data. Other binary files are returned as MCP embedded resource content (type: "resource") with uri, mimeType, and base64-encoded blob.',
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -233,12 +237,28 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
|
||||
const result = await executeObsidianCommandBinary('read', cmdArgs);
|
||||
handleCLIResult(result, { operation: 'read_note', identifier: sanitized.file || sanitized.path });
|
||||
|
||||
// Detect binary content from the raw buffer and return as MCP resource
|
||||
// Detect binary content from the raw buffer and return as spec-appropriate MCP content
|
||||
if (result.stdoutBuffer && isBinaryContent(result.stdoutBuffer)) {
|
||||
const identifier = sanitized.file || sanitized.path as string;
|
||||
const mimeType = getMimeType(identifier);
|
||||
const base64 = result.stdoutBuffer.toString('base64');
|
||||
|
||||
// Images use the MCP image content type per spec
|
||||
if (isImageMimeType(mimeType)) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'image' as const,
|
||||
data: base64,
|
||||
mimeType,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// All other binary files use the embedded resource content type per spec
|
||||
const vaultName = process.env.OBSIDIAN_VAULT ?? 'vault';
|
||||
const uri = `obsidian://${encodeURIComponent(vaultName)}/${encodeURIComponent(identifier)}`;
|
||||
const mimeType = getMimeType(identifier);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
@@ -246,7 +266,7 @@ export async function registerFileOperationTools(server: ObsidianMCPServer): Pro
|
||||
resource: {
|
||||
uri,
|
||||
mimeType,
|
||||
blob: result.stdoutBuffer.toString('base64'),
|
||||
blob: base64,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -18,6 +18,8 @@ export interface ToolInput {
|
||||
export interface ToolOutput {
|
||||
content: Array<
|
||||
| { type: 'text'; text: string }
|
||||
| { type: 'image'; data: string; mimeType: string }
|
||||
| { type: 'audio'; data: string; mimeType: string }
|
||||
| { type: 'resource'; resource: { uri: string; mimeType?: string; blob: string } }
|
||||
>;
|
||||
isError?: false;
|
||||
|
||||
Reference in New Issue
Block a user