import { MCPTool } from './index.js';
import { ChangerawrClient } from '../client/changerawr-client.js';
import { validateAndNormalizeArgs } from '../utils/validation.js';
export const listChangelogEntresTool: MCPTool = {
name: 'list_changelog_entries',
description: 'List changelog entries for a project',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
published: {
type: 'boolean',
description: 'Filter by published status (true=published, false=unpublished)',
},
limit: {
type: 'number',
description: 'Maximum number of entries to return',
default: 50,
},
cursor: {
type: 'string',
description: 'Pagination cursor for next page',
},
},
required: ['projectId'],
},
async execute(args: {
projectId: string;
published?: boolean;
limit?: number;
cursor?: string;
}, client: ChangerawrClient) {
try {
const validatedArgs = validateAndNormalizeArgs(args, this.inputSchema);
console.error(`Fetching changelog entries for project: ${validatedArgs.projectId}`);
const result = await client.listChangelogEntries(validatedArgs.projectId, {
published: validatedArgs.published,
limit: validatedArgs.limit,
cursor: validatedArgs.cursor,
});
return {
success: true,
data: result.entries,
pagination: {
nextCursor: result.nextCursor,
hasMore: !!result.nextCursor,
},
message: `Found ${result.entries.length} changelog entries`,
};
} catch (error) {
console.error('listChangelogEntresTool error:', error);
throw error;
}
},
};
export const getChangelogEntryTool: MCPTool = {
name: 'get_changelog_entry',
description: 'Get details of a specific changelog entry',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
entryId: {
type: 'string',
description: 'The ID of the changelog entry',
},
},
required: ['projectId', 'entryId'],
},
async execute(args: { projectId: string; entryId: string }, client: ChangerawrClient) {
try {
const validatedArgs = validateAndNormalizeArgs(args, this.inputSchema);
console.error(`Fetching changelog entry: ${validatedArgs.entryId} from project: ${validatedArgs.projectId}`);
const entry = await client.getChangelogEntry(validatedArgs.projectId, validatedArgs.entryId);
return {
success: true,
data: entry,
message: `Retrieved changelog entry: ${entry.title}`,
};
} catch (error) {
console.error('getChangelogEntryTool error:', error);
throw error;
}
},
};
export const createChangelogEntryTool: MCPTool = {
name: 'create_changelog_entry',
description: 'Create a new changelog entry as a draft (unpublished)',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
title: {
type: 'string',
description: 'The title of the changelog entry',
},
content: {
type: 'string',
description: 'The markdown content of the changelog entry',
},
version: {
type: 'string',
description: 'Version number (e.g., v1.2.0)',
},
tags: {
type: 'array',
items: { type: 'string' },
description: 'Tag names to associate with this entry',
default: [],
},
},
required: ['projectId', 'title', 'content'],
},
async execute(args: {
projectId: string;
title: string;
content: string;
version?: string;
tags?: string[];
}, client: ChangerawrClient) {
try {
const validatedArgs = validateAndNormalizeArgs(args, this.inputSchema);
console.error(`Creating changelog entry for project: ${validatedArgs.projectId}`);
const entryData = {
title: validatedArgs.title,
content: validatedArgs.content,
version: validatedArgs.version,
tags: validatedArgs.tags || [],
};
const entry = await client.createChangelogEntry(validatedArgs.projectId, entryData);
return {
success: true,
data: entry,
message: `Created changelog entry: ${entry.title} (saved as draft - use publish_changelog_entry to make it public)`,
};
} catch (error) {
console.error('createChangelogEntryTool error:', error);
throw error;
}
},
};
export const updateChangelogEntryTool: MCPTool = {
name: 'update_changelog_entry',
description: 'Update an existing changelog entry',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
entryId: {
type: 'string',
description: 'The ID of the changelog entry to update',
},
title: {
type: 'string',
description: 'The new title of the changelog entry',
},
content: {
type: 'string',
description: 'The new markdown content of the changelog entry',
},
version: {
type: 'string',
description: 'The new version number',
},
tags: {
type: 'array',
items: { type: 'string' },
description: 'Tags to associate with this entry',
},
},
required: ['projectId', 'entryId'],
},
async execute(args: {
projectId: string;
entryId: string;
title?: string;
content?: string;
version?: string;
tags?: string[];
}, client: ChangerawrClient) {
const { projectId, entryId, ...updateData } = args;
const entry = await client.updateChangelogEntry(projectId, entryId, updateData);
return {
success: true,
data: entry,
message: `Updated changelog entry: ${entry.title}`,
};
},
};
export const publishChangelogEntryTool: MCPTool = {
name: 'publish_changelog_entry',
description: 'Publish a changelog entry to make it visible to users (admin access)',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
entryId: {
type: 'string',
description: 'The ID of the changelog entry to publish',
},
},
required: ['projectId', 'entryId'],
},
async execute(args: { projectId: string; entryId: string }, client: ChangerawrClient) {
const entry = await client.publishChangelogEntry(args.projectId, args.entryId);
return {
success: true,
data: entry,
message: `Published changelog entry: ${entry.title} - now visible to users`,
};
},
};
export const unpublishChangelogEntryTool: MCPTool = {
name: 'unpublish_changelog_entry',
description: 'Unpublish a changelog entry to hide it from users (admin access)',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
entryId: {
type: 'string',
description: 'The ID of the changelog entry to unpublish',
},
},
required: ['projectId', 'entryId'],
},
async execute(args: { projectId: string; entryId: string }, client: ChangerawrClient) {
const entry = await client.unpublishChangelogEntry(args.projectId, args.entryId);
return {
success: true,
data: entry,
message: `Unpublished changelog entry: ${entry.title} - hidden from users`,
};
},
};
export const deleteChangelogEntryTool: MCPTool = {
name: 'delete_changelog_entry',
description: 'Delete a changelog entry permanently (admin access)',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
entryId: {
type: 'string',
description: 'The ID of the changelog entry to delete',
},
},
required: ['projectId', 'entryId'],
},
async execute(args: { projectId: string; entryId: string }, client: ChangerawrClient) {
await client.deleteChangelogEntry(args.projectId, args.entryId);
return {
success: true,
message: `Changelog entry deleted permanently (admin access)`,
};
},
};
export const createAndPublishChangelogEntryTool: MCPTool = {
name: 'create_and_publish_changelog_entry',
description: 'Create a new changelog entry and publish it immediately',
inputSchema: {
type: 'object',
properties: {
projectId: {
type: 'string',
description: 'The ID of the project',
},
title: {
type: 'string',
description: 'The title of the changelog entry',
},
content: {
type: 'string',
description: 'The markdown content of the changelog entry',
},
version: {
type: 'string',
description: 'Version number (e.g., v1.2.0)',
},
tags: {
type: 'array',
items: { type: 'string' },
description: 'Tag names to associate with this entry',
default: [],
},
},
required: ['projectId', 'title', 'content'],
},
async execute(args: {
projectId: string;
title: string;
content: string;
version?: string;
tags?: string[];
}, client: ChangerawrClient) {
// First create the entry
const entryData = {
title: args.title,
content: args.content,
version: args.version,
tags: args.tags,
};
let entry = await client.createChangelogEntry(args.projectId, entryData);
// Then publish it
try {
entry = await client.publishChangelogEntry(args.projectId, entry.id);
return {
success: true,
data: entry,
message: `Created and published changelog entry: ${entry.title}`,
};
} catch (error) {
// If publish fails, still return the created entry but note the failure
return {
success: true,
data: entry,
message: `Created changelog entry: ${entry.title}, but failed to publish: ${error}`,
};
}
},
};