Skip to content

Commit 8baeca0

Browse files
committed
Add new microCMS Management API tools and update server handling
- Introduced `getListMeta` and `getContentMeta` functions for retrieving lists and specific content with metadata. - Added `patchContentStatus` and `patchContentCreatedBy` functions to update content status and creator. - Updated `manifest.json` to include new tools: `microcms_get_list_meta`, `microcms_get_content_meta`, `microcms_patch_content_status`, and `microcms_patch_content_created_by`. - Enhanced server request handling to support the new functionalities.
1 parent 218fe1c commit 8baeca0

File tree

9 files changed

+354
-0
lines changed

9 files changed

+354
-0
lines changed

manifest.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,18 @@
2828
"name": "microcms_get_list",
2929
"description": "Get a list of content from microCMS with filtering and search capabilities"
3030
},
31+
{
32+
"name": "microcms_get_list_meta",
33+
"description": "Get a list of contents with metadata from microCMS Management API. Use ONLY when user message contains \"メタ\" or \"メタ情報\". Returns metadata like status, createdBy, updatedBy, reservationTime, closedAt, and customStatus."
34+
},
3135
{
3236
"name": "microcms_get_content",
3337
"description": "Get a specific content item from microCMS"
3438
},
39+
{
40+
"name": "microcms_get_content_meta",
41+
"description": "Get a specific content with metadata from microCMS Management API. Use ONLY when user message contains \"メタ\" or \"メタ情報\". Returns metadata like status, createdBy, updatedBy, reservationTime, closedAt, and customStatus."
42+
},
3543
{
3644
"name": "microcms_create_content_published",
3745
"description": "Create new published content in microCMS"
@@ -52,6 +60,14 @@
5260
"name": "microcms_patch_content",
5361
"description": "Partially update content in microCMS"
5462
},
63+
{
64+
"name": "microcms_patch_content_status",
65+
"description": "Change content publication status in microCMS (Management API). Can change status between PUBLISH and DRAFT"
66+
},
67+
{
68+
"name": "microcms_patch_content_created_by",
69+
"description": "Change content creator in microCMS (Management API). Updates the createdBy field of a content item to a specified member ID"
70+
},
5571
{
5672
"name": "microcms_delete_content",
5773
"description": "Delete content from microCMS"

src/client.ts

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,97 @@ export async function deleteMedia(mediaUrl: string): Promise<{ id: string }> {
160160
throw new Error(`Failed to delete media: ${response.status} ${response.statusText} - ${errorText}`);
161161
}
162162

163+
return await response.json();
164+
}
165+
166+
export async function patchContentStatus(
167+
endpoint: string,
168+
contentId: string,
169+
status: 'PUBLISH' | 'DRAFT'
170+
): Promise<void> {
171+
const url = `https://${config.serviceDomain}.microcms-management.io/api/v1/contents/${endpoint}/${contentId}/status`;
172+
173+
const response = await fetch(url, {
174+
method: 'PATCH',
175+
headers: {
176+
'X-MICROCMS-API-KEY': config.apiKey,
177+
'Content-Type': 'application/json',
178+
},
179+
body: JSON.stringify({ status: [status] }),
180+
});
181+
182+
if (!response.ok) {
183+
const errorText = await response.text();
184+
throw new Error(`Failed to patch content status: ${response.status} ${response.statusText} - ${errorText}`);
185+
}
186+
}
187+
188+
export async function patchContentCreatedBy(
189+
endpoint: string,
190+
contentId: string,
191+
memberId: string
192+
): Promise<{ id: string }> {
193+
const url = `https://${config.serviceDomain}.microcms-management.io/api/v1/contents/${endpoint}/${contentId}/createdBy`;
194+
195+
const response = await fetch(url, {
196+
method: 'PATCH',
197+
headers: {
198+
'X-MICROCMS-API-KEY': config.apiKey,
199+
'Content-Type': 'application/json',
200+
},
201+
body: JSON.stringify({ createdBy: memberId }),
202+
});
203+
204+
if (!response.ok) {
205+
const errorText = await response.text();
206+
throw new Error(`Failed to patch content createdBy: ${response.status} ${response.statusText} - ${errorText}`);
207+
}
208+
209+
return await response.json();
210+
}
211+
212+
export async function getListMeta(
213+
endpoint: string,
214+
options?: { limit?: number; offset?: number }
215+
): Promise<any> {
216+
const queryParams = new URLSearchParams();
217+
if (options?.limit) queryParams.append('limit', options.limit.toString());
218+
if (options?.offset) queryParams.append('offset', options.offset.toString());
219+
220+
const url = `https://${config.serviceDomain}.microcms-management.io/api/v1/contents/${endpoint}${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
221+
222+
const response = await fetch(url, {
223+
method: 'GET',
224+
headers: {
225+
'X-MICROCMS-API-KEY': config.apiKey,
226+
},
227+
});
228+
229+
if (!response.ok) {
230+
const errorText = await response.text();
231+
throw new Error(`Failed to get contents list: ${response.status} ${response.statusText} - ${errorText}`);
232+
}
233+
234+
return await response.json();
235+
}
236+
237+
export async function getContentManagement(
238+
endpoint: string,
239+
contentId: string
240+
): Promise<any> {
241+
const url = `https://${config.serviceDomain}.microcms-management.io/api/v1/contents/${endpoint}/${contentId}`;
242+
243+
const response = await fetch(url, {
244+
method: 'GET',
245+
headers: {
246+
'X-MICROCMS-API-KEY': config.apiKey,
247+
},
248+
});
249+
250+
if (!response.ok) {
251+
const errorText = await response.text();
252+
throw new Error(`Failed to get content: ${response.status} ${response.statusText} - ${errorText}`);
253+
}
254+
163255
return await response.json();
164256
}

src/server.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@ import {
66
} from '@modelcontextprotocol/sdk/types.js';
77

88
import { getListTool, handleGetList } from './tools/get-list.js';
9+
import { getListMetaTool, handleGetListMeta as handleGetListMeta } from './tools/get-list-meta.js';
910
import { getContentTool, handleGetContent } from './tools/get-content.js';
11+
import { getContentMetaTool, handleGetContentMeta } from './tools/get-content-meta.js';
1012
import { createContentPublishedTool, handleCreateContentPublished } from './tools/create-content-published.js';
1113
import { createContentDraftTool, handleCreateContentDraft } from './tools/create-content-draft.js';
1214
import { updateContentPublishedTool, handleUpdateContentPublished } from './tools/update-content-published.js';
1315
import { updateContentDraftTool, handleUpdateContentDraft } from './tools/update-content-draft.js';
1416
import { patchContentTool, handlePatchContent } from './tools/patch-content.js';
17+
import { patchContentStatusTool, handlePatchContentStatus } from './tools/patch-content-status.js';
18+
import { patchContentCreatedByTool, handlePatchContentCreatedBy } from './tools/patch-content-created-by.js';
1519
import { deleteContentTool, handleDeleteContent } from './tools/delete-content.js';
1620
import { getMediaTool, handleGetMedia } from './tools/get-media.js';
1721
import { uploadMediaTool, handleUploadMedia } from './tools/upload-media.js';
@@ -38,12 +42,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
3842
return {
3943
tools: [
4044
getListTool,
45+
getListMetaTool,
4146
getContentTool,
47+
getContentMetaTool,
4248
createContentPublishedTool,
4349
createContentDraftTool,
4450
updateContentPublishedTool,
4551
updateContentDraftTool,
4652
patchContentTool,
53+
patchContentStatusTool,
54+
patchContentCreatedByTool,
4755
deleteContentTool,
4856
getMediaTool,
4957
uploadMediaTool,
@@ -66,9 +74,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
6674
case 'microcms_get_list':
6775
result = await handleGetList(params);
6876
break;
77+
case 'microcms_get_list_meta':
78+
result = await handleGetListMeta(params);
79+
break;
6980
case 'microcms_get_content':
7081
result = await handleGetContent(params);
7182
break;
83+
case 'microcms_get_content_meta':
84+
result = await handleGetContentMeta(params);
85+
break;
7286
case 'microcms_create_content_published':
7387
result = await handleCreateContentPublished(params);
7488
break;
@@ -84,6 +98,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
8498
case 'microcms_patch_content':
8599
result = await handlePatchContent(params);
86100
break;
101+
case 'microcms_patch_content_status':
102+
result = await handlePatchContentStatus(params as ToolParameters & { status: 'PUBLISH' | 'DRAFT' });
103+
break;
104+
case 'microcms_patch_content_created_by':
105+
result = await handlePatchContentCreatedBy(params as ToolParameters & { createdBy: string });
106+
break;
87107
case 'microcms_delete_content':
88108
result = await handleDeleteContent(params);
89109
break;

src/tools/get-content-meta.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
2+
import { getContentManagement } from '../client.js';
3+
import type { ToolParameters } from '../types.js';
4+
5+
export const getContentMetaTool: Tool = {
6+
name: 'microcms_get_content_meta',
7+
description: 'Get a specific content with metadata from microCMS Management API. IMPORTANT: Use this tool ONLY when the user message contains "メタ" (meta) or "メタ情報" (metadata). This API returns metadata information such as status, createdBy, updatedBy, reservationTime, closedAt, and customStatus that are not available in the regular content API. For regular content retrieval, use microcms_get_content instead.',
8+
inputSchema: {
9+
type: 'object',
10+
properties: {
11+
endpoint: {
12+
type: 'string',
13+
description: 'Content type name (e.g., "blogs", "news")',
14+
},
15+
contentId: {
16+
type: 'string',
17+
description: 'Content ID to retrieve',
18+
},
19+
},
20+
required: ['endpoint', 'contentId'],
21+
},
22+
};
23+
24+
export async function handleGetContentMeta(params: ToolParameters) {
25+
const { endpoint, contentId } = params;
26+
27+
if (!endpoint) {
28+
throw new Error('endpoint is required');
29+
}
30+
31+
if (!contentId) {
32+
throw new Error('contentId is required');
33+
}
34+
35+
return await getContentManagement(endpoint, contentId);
36+
}
37+
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
2+
import { getListMeta } from '../client.js';
3+
import type { ToolParameters } from '../types.js';
4+
5+
export const getListMetaTool: Tool = {
6+
name: 'microcms_get_list_meta',
7+
description: 'Get a list of contents with metadata from microCMS Management API. IMPORTANT: Use this tool ONLY when the user message contains "メタ" (meta) or "メタ情報" (metadata). This API returns metadata information such as status, createdBy, updatedBy, reservationTime, closedAt, and customStatus that are not available in the regular content API. For regular content retrieval, use microcms_get_list instead.',
8+
inputSchema: {
9+
type: 'object',
10+
properties: {
11+
endpoint: {
12+
type: 'string',
13+
description: 'Content type name (e.g., "blogs", "news")',
14+
},
15+
limit: {
16+
type: 'number',
17+
description: 'Number of contents to retrieve (default: 10, max: 100)',
18+
minimum: 1,
19+
maximum: 100,
20+
},
21+
offset: {
22+
type: 'number',
23+
description: 'Offset for pagination (default: 0)',
24+
minimum: 0,
25+
},
26+
},
27+
required: ['endpoint'],
28+
},
29+
};
30+
31+
export async function handleGetListMeta(params: ToolParameters) {
32+
const { endpoint, limit, offset } = params;
33+
34+
if (!endpoint) {
35+
throw new Error('endpoint is required');
36+
}
37+
38+
const options: { limit?: number; offset?: number } = {};
39+
if (limit !== undefined) options.limit = limit;
40+
if (offset !== undefined) options.offset = offset;
41+
42+
return await getListMeta(endpoint, options);
43+
}
44+

src/tools/get-list-meta.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
2+
import { getListMeta } from '../client.js';
3+
import type { ToolParameters } from '../types.js';
4+
5+
export const getListMetaTool: Tool = {
6+
name: 'microcms_get_list_meta',
7+
description: 'Get a list of contents with metadata from microCMS Management API. IMPORTANT: Use this tool ONLY when the user message contains "メタ" (meta) or "メタ情報" (metadata). This API returns metadata information such as status, createdBy, updatedBy, reservationTime, closedAt, and customStatus that are not available in the regular content API. For regular content retrieval, use microcms_get_list instead.',
8+
inputSchema: {
9+
type: 'object',
10+
properties: {
11+
endpoint: {
12+
type: 'string',
13+
description: 'Content type name (e.g., "blogs", "news")',
14+
},
15+
limit: {
16+
type: 'number',
17+
description: 'Number of contents to retrieve (default: 10, max: 100)',
18+
minimum: 1,
19+
maximum: 100,
20+
},
21+
offset: {
22+
type: 'number',
23+
description: 'Offset for pagination (default: 0)',
24+
minimum: 0,
25+
},
26+
},
27+
required: ['endpoint'],
28+
},
29+
};
30+
31+
export async function handleGetListMeta(params: ToolParameters) {
32+
const { endpoint, limit, offset } = params;
33+
34+
if (!endpoint) {
35+
throw new Error('endpoint is required');
36+
}
37+
38+
const options: { limit?: number; offset?: number } = {};
39+
if (limit !== undefined) options.limit = limit;
40+
if (offset !== undefined) options.offset = offset;
41+
42+
return await getListMeta(endpoint, options);
43+
}
44+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
2+
import { patchContentCreatedBy } from '../client.js';
3+
import type { ToolParameters } from '../types.js';
4+
5+
export const patchContentCreatedByTool: Tool = {
6+
name: 'microcms_patch_content_created_by',
7+
description: 'Change content creator in microCMS (Management API). Updates the createdBy field of a content item to a specified member ID. Member ID can be found in the member detail screen in the management console.',
8+
inputSchema: {
9+
type: 'object',
10+
properties: {
11+
endpoint: {
12+
type: 'string',
13+
description: 'Content type name (e.g., "blogs", "news")',
14+
},
15+
contentId: {
16+
type: 'string',
17+
description: 'Content ID to change creator',
18+
},
19+
createdBy: {
20+
type: 'string',
21+
description: 'Member ID to set as the creator. Member ID can be found in the member detail screen in the management console.',
22+
},
23+
},
24+
required: ['endpoint', 'contentId', 'createdBy'],
25+
},
26+
};
27+
28+
export async function handlePatchContentCreatedBy(
29+
params: ToolParameters & { createdBy: string }
30+
) {
31+
const { endpoint, contentId, createdBy } = params;
32+
33+
if (!endpoint) {
34+
throw new Error('endpoint is required');
35+
}
36+
37+
if (!contentId) {
38+
throw new Error('contentId is required');
39+
}
40+
41+
if (!createdBy) {
42+
throw new Error('createdBy is required');
43+
}
44+
45+
const result = await patchContentCreatedBy(endpoint, contentId, createdBy);
46+
return { message: `Content ${contentId} creator changed to ${createdBy}`, id: result.id };
47+
}
48+

0 commit comments

Comments
 (0)