Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,15 @@ program
console.log(`Added tags to draft ${uuid}`);
});

program
.command('remove-tags <uuid> <tags...>')
.description('Remove tags from a draft')
.action(async (uuid: string, tags: string[]) => {
const success = await drafts.removeTagsFromDraft(uuid, tags);
if (!success) fail(`Failed to remove tags from draft ${uuid}`);
console.log(`Removed tags from draft ${uuid}`);
});

program
.command('search <query>')
.description('Search drafts by content')
Expand Down
32 changes: 32 additions & 0 deletions src/drafts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,38 @@ export async function addTagsToDraft(uuid: string, tags: string[]): Promise<bool
return result === 'SUCCESS';
}

/**
* Remove tags from a draft
*/
export async function removeTagsFromDraft(uuid: string, tags: string[]): Promise<boolean> {
const escapedUuid = escapeAppleScriptString(uuid);
const tagsToRemove = tags.map(t => `"${escapeAppleScriptString(t)}"`).join(', ');

const script = `
tell application "Drafts"
try
set targetDraft to draft id "${escapedUuid}"
set tagsToRemove to {${tagsToRemove}}
set currentTags to tag list of targetDraft
set newTags to {}
repeat with t in currentTags
set tagName to contents of t
if tagsToRemove does not contain tagName then
set end of newTags to tagName
end if
end repeat
set tag list of targetDraft to newTags
return "SUCCESS"
on error errMsg
return "ERROR: " & errMsg
end try
end tell
`;

const result = await executeAppleScript(script);
return result === 'SUCCESS';
}

/**
* Run an action on a draft
*/
Expand Down
42 changes: 42 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,32 @@ const TOOLS: Tool[] = [
openWorldHint: false,
},
},
{
name: 'drafts_remove_tags',
description: 'Remove tags from an existing draft',
inputSchema: {
type: 'object',
properties: {
uuid: {
type: 'string',
description: 'The UUID of the draft',
},
tags: {
type: 'array',
items: { type: 'string' },
description: 'Tags to remove from the draft',
},
},
required: ['uuid', 'tags'],
},
annotations: {
title: 'Remove Tags',
readOnlyHint: false,
destructiveHint: true,
idempotentHint: true,
openWorldHint: false,
},
},
{
name: 'drafts_search',
description: 'Search for drafts using a query string',
Expand Down Expand Up @@ -656,6 +682,22 @@ class DraftsMCPServer {
};
}

case 'drafts_remove_tags': {
const { uuid, tags } = args as { uuid: string; tags: string[] };
const success = await drafts.removeTagsFromDraft(uuid, tags);
return {
content: [
{
type: 'text',
text: success
? `Removed tags from draft ${uuid}`
: `Failed to remove tags from draft ${uuid}`,
},
],
isError: !success,
};
}

case 'drafts_search': {
const { query } = args as { query: string };
const results = await drafts.searchDrafts(query);
Expand Down