mirror of
https://github.com/jlengrand/ghost-mcp.git
synced 2026-03-10 00:11:21 +00:00
219 lines
8.3 KiB
TypeScript
219 lines
8.3 KiB
TypeScript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
import { ghostApiClient } from './ghostApi';
|
|
import { Post, User, Member, Tier, Offer, Newsletter } from './models'; // Import data models
|
|
|
|
// Type definitions compatible with MCP SDK resource handler expectations
|
|
type Variables = Record<string, string | string[]>;
|
|
type ReadResourceTemplateCallback = (uri: URL, variables: Variables) => Promise<any>;
|
|
|
|
// Handler for the user resource
|
|
export const handleUserResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const userId = variables.user_id as string; // Access parameter from variables
|
|
if (!userId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing user_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch user data by ID
|
|
// const user: User = await ghostApiClient.users.read({ id: userId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(user, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `User resource requested for ID: ${userId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching user ${variables.user_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the member resource
|
|
export const handleMemberResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const memberId = variables.member_id as string; // Access parameter from variables
|
|
if (!memberId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing member_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch member data by ID
|
|
// const member: Member = await ghostApiClient.members.read({ id: memberId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(member, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Member resource requested for ID: ${memberId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching member ${variables.member_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the tier resource
|
|
export const handleTierResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const tierId = variables.tier_id as string; // Access parameter from variables
|
|
if (!tierId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing tier_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch tier data by ID
|
|
// const tier: Tier = await ghostApiClient.tiers.read({ id: tierId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(tier, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Tier resource requested for ID: ${tierId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching tier ${variables.tier_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the offer resource
|
|
export const handleOfferResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const offerId = variables.offer_id as string; // Access parameter from variables
|
|
if (!offerId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing offer_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch offer data by ID
|
|
// const offer: Offer = await ghostApiClient.offers.read({ id: offerId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(offer, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Offer resource requested for ID: ${offerId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching offer ${variables.offer_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the newsletter resource
|
|
export const handleNewsletterResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const newsletterId = variables.newsletter_id as string; // Access parameter from variables
|
|
if (!newsletterId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing newsletter_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch newsletter data by ID
|
|
// const newsletter: Newsletter = await ghostApiClient.newsletters.read({ id: newsletterId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(newsletter, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Newsletter resource requested for ID: ${newsletterId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching newsletter ${variables.newsletter_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the post resource
|
|
export const handlePostResource: ReadResourceTemplateCallback = async (uri: URL, variables: Variables): Promise<any> => {
|
|
try {
|
|
const postId = variables.post_id as string; // Access parameter from variables
|
|
if (!postId) {
|
|
// TODO: Return a structured MCP error for missing parameter
|
|
throw new Error("Missing post_id parameter");
|
|
}
|
|
// TODO: Use ghostApiClient to fetch post data by ID
|
|
// const post: Post = await ghostApiClient.posts.read({ id: postId });
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(post, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Post resource requested for ID: ${postId}`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching post ${variables.post_id}:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
// Handler for the blog info resource
|
|
export async function handleBlogInfoResource(uri: URL): Promise<any> {
|
|
try {
|
|
// TODO: Use ghostApiClient to fetch blog info
|
|
// const blogInfo = await ghostApiClient.site.read();
|
|
// return {
|
|
// contents: [{
|
|
// uri: uri.href,
|
|
// text: JSON.stringify(blogInfo, null, 2), // Or format as needed
|
|
// mimeType: 'application/json'
|
|
// }]
|
|
// };
|
|
return {
|
|
contents: [{
|
|
uri: uri.href,
|
|
text: `Blog info resource requested`,
|
|
mimeType: 'text/plain'
|
|
}]
|
|
};
|
|
} catch (error) {
|
|
console.error(`Error fetching blog info:`, error);
|
|
// TODO: Return an error result in the MCP format
|
|
throw error;
|
|
}
|
|
} |