gearvn-pages-mcp-server 1.6.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/deploy-page.d.ts.map +1 -1
- package/dist/tools/deploy-page.js +10 -1
- package/dist/tools/deploy-page.js.map +1 -1
- package/dist/tools/get-page.d.ts +9 -0
- package/dist/tools/get-page.d.ts.map +1 -0
- package/dist/tools/get-page.js +38 -0
- package/dist/tools/get-page.js.map +1 -0
- package/dist/tools/list-pages.d.ts +1 -1
- package/dist/tools/list-pages.d.ts.map +1 -1
- package/dist/tools/list-pages.js +57 -4
- package/dist/tools/list-pages.js.map +1 -1
- package/dist/tools/update-page.d.ts.map +1 -1
- package/dist/tools/update-page.js +12 -4
- package/dist/tools/update-page.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +5 -2
- package/src/tools/deploy-page.ts +12 -1
- package/src/tools/get-page.ts +50 -0
- package/src/tools/list-pages.ts +61 -6
- package/src/tools/update-page.ts +13 -4
- package/src/types.ts +23 -0
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
5
|
import { DEPLOY_PAGE_TOOL, handleDeployPage } from "./tools/deploy-page.js";
|
|
6
6
|
import { LIST_PAGES_TOOL, handleListPages } from "./tools/list-pages.js";
|
|
7
|
+
import { GET_PAGE_TOOL, handleGetPage } from "./tools/get-page.js";
|
|
7
8
|
import { UPDATE_PAGE_TOOL, handleUpdatePage } from "./tools/update-page.js";
|
|
8
9
|
import { DELETE_PAGE_TOOL, handleDeletePage } from "./tools/delete-page.js";
|
|
9
10
|
// Create MCP server
|
|
@@ -18,7 +19,7 @@ const server = new Server({
|
|
|
18
19
|
// Handler for listing available tools
|
|
19
20
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
20
21
|
return {
|
|
21
|
-
tools: [DEPLOY_PAGE_TOOL, LIST_PAGES_TOOL, UPDATE_PAGE_TOOL, DELETE_PAGE_TOOL],
|
|
22
|
+
tools: [DEPLOY_PAGE_TOOL, LIST_PAGES_TOOL, GET_PAGE_TOOL, UPDATE_PAGE_TOOL, DELETE_PAGE_TOOL],
|
|
22
23
|
};
|
|
23
24
|
});
|
|
24
25
|
// Handler for tool calls
|
|
@@ -29,7 +30,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
29
30
|
return await handleDeployPage(args);
|
|
30
31
|
}
|
|
31
32
|
else if (name === "list-pages") {
|
|
32
|
-
return await handleListPages();
|
|
33
|
+
return await handleListPages(args);
|
|
34
|
+
}
|
|
35
|
+
else if (name === "get-page") {
|
|
36
|
+
return await handleGetPage(args);
|
|
33
37
|
}
|
|
34
38
|
else if (name === "update-page") {
|
|
35
39
|
return await handleUpdatePage(args);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,oBAAoB;AACpB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,yBAAyB;IAC/B,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,sCAAsC;AACtC,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE,CAAC,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-page.d.ts","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"deploy-page.d.ts","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,IAwC9B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO;;;;;GAoDnD"}
|
|
@@ -26,12 +26,16 @@ export const DEPLOY_PAGE_TOOL = {
|
|
|
26
26
|
},
|
|
27
27
|
description: "Optional array of tags to categorize the page (e.g., ['dashboard', 'finance']). Tags are case-insensitive for filtering.",
|
|
28
28
|
},
|
|
29
|
+
metadata: {
|
|
30
|
+
type: "object",
|
|
31
|
+
description: "Optional key-value metadata to store with the page. Can contain any JSON structure (strings, numbers, arrays, nested objects). Useful for storing additional information like author/owner, category/classification, related resources, or custom attributes for filtering. Example: { \"vendor\": \"Apple\", \"category\": \"product\", \"attendees\": [\"John\", \"Jane\"] }. This metadata is searchable via list-pages tool.",
|
|
32
|
+
},
|
|
29
33
|
},
|
|
30
34
|
required: ["title", "content", "slug"],
|
|
31
35
|
},
|
|
32
36
|
};
|
|
33
37
|
export async function handleDeployPage(args) {
|
|
34
|
-
const { title, content, slug, tags } = args;
|
|
38
|
+
const { title, content, slug, tags, metadata } = args;
|
|
35
39
|
// Validate inputs
|
|
36
40
|
if (!title || !content || !slug) {
|
|
37
41
|
throw new Error("Missing required parameters: title, content, and slug are required");
|
|
@@ -46,6 +50,10 @@ export async function handleDeployPage(args) {
|
|
|
46
50
|
if (tags && tags.length > 0) {
|
|
47
51
|
requestBody.tags = tags;
|
|
48
52
|
}
|
|
53
|
+
// Add metadata if provided
|
|
54
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
55
|
+
requestBody.metadata = metadata;
|
|
56
|
+
}
|
|
49
57
|
// Call the deploy API
|
|
50
58
|
const response = await callAPI("/v1/deploy", "POST", requestBody);
|
|
51
59
|
return {
|
|
@@ -57,6 +65,7 @@ export async function handleDeployPage(args) {
|
|
|
57
65
|
message: "Page deployed successfully",
|
|
58
66
|
url: response.url,
|
|
59
67
|
tags: tags || [],
|
|
68
|
+
metadata: metadata || {},
|
|
60
69
|
}, null, 2),
|
|
61
70
|
},
|
|
62
71
|
],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy-page.js","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,6sBAA6sB;IAC/sB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6FAA6F;aAChG;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,ypBAAypB;aAC5pB;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iDAAiD;oBACjD,8EAA8E;oBAC9E,2IAA2I;aAC9I;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;iBACf;gBACD,WAAW,EACT,0HAA0H;aAC7H;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;KACvC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy-page.js","sourceRoot":"","sources":["../../src/tools/deploy-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,6sBAA6sB;IAC/sB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6FAA6F;aAChG;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,ypBAAypB;aAC5pB;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iDAAiD;oBACjD,8EAA8E;oBAC9E,2IAA2I;aAC9I;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;iBACf;gBACD,WAAW,EACT,0HAA0H;aAC7H;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,kaAAka;aACra;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC;KACvC;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAsB,CAAC;IAExE,kBAAkB;IAClB,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAmB;QAClC,KAAK;QACL,OAAO;QACP,IAAI;KACL,CAAC;IAEF,uBAAuB;IACvB,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1B,CAAC;IAED,2BAA2B;IAC3B,IAAI,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjD,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,YAAY,EACZ,MAAM,EACN,WAAW,CACZ,CAAC;IAEF,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,4BAA4B;oBACrC,GAAG,EAAE,QAAQ,CAAC,GAAG;oBACjB,IAAI,EAAE,IAAI,IAAI,EAAE;oBAChB,QAAQ,EAAE,QAAQ,IAAI,EAAE;iBACzB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare const GET_PAGE_TOOL: Tool;
|
|
3
|
+
export declare function handleGetPage(args: unknown): Promise<{
|
|
4
|
+
content: {
|
|
5
|
+
type: "text";
|
|
6
|
+
text: string;
|
|
7
|
+
}[];
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=get-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page.d.ts","sourceRoot":"","sources":["../../src/tools/get-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,aAAa,EAAE,IAe3B,CAAC;AAEF,wBAAsB,aAAa,CAAC,IAAI,EAAE,OAAO;;;;;GA4BhD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { callAPI } from "../api.js";
|
|
2
|
+
export const GET_PAGE_TOOL = {
|
|
3
|
+
name: "get-page",
|
|
4
|
+
description: "Get the full content of a page by its slug. Returns the complete page data including HTML content, title, and tags. Use the exact slug from list-pages response (including timestamp suffix).",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
slug: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "The exact slug of the page to retrieve (must match the slug from list-pages response, including timestamp suffix)",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
required: ["slug"],
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export async function handleGetPage(args) {
|
|
17
|
+
const { slug } = args;
|
|
18
|
+
// Validate inputs
|
|
19
|
+
if (!slug) {
|
|
20
|
+
throw new Error("Missing required parameter: slug is required");
|
|
21
|
+
}
|
|
22
|
+
// Call the get-page API
|
|
23
|
+
const response = await callAPI("/v1/get-page", "POST", {
|
|
24
|
+
slug,
|
|
25
|
+
});
|
|
26
|
+
return {
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
29
|
+
type: "text",
|
|
30
|
+
text: JSON.stringify({
|
|
31
|
+
success: true,
|
|
32
|
+
page: response,
|
|
33
|
+
}, null, 2),
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=get-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-page.js","sourceRoot":"","sources":["../../src/tools/get-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,aAAa,GAAS;IACjC,IAAI,EAAE,UAAU;IAChB,WAAW,EACT,+LAA+L;IACjM,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,mHAAmH;aACtH;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAa;IAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,IAAmB,CAAC;IAErC,kBAAkB;IAClB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,wBAAwB;IACxB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAkB,cAAc,EAAE,MAAM,EAAE;QACtE,IAAI;KACL,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,QAAQ;iBACf,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
export declare const LIST_PAGES_TOOL: Tool;
|
|
3
|
-
export declare function handleListPages(): Promise<{
|
|
3
|
+
export declare function handleListPages(args?: unknown): Promise<{
|
|
4
4
|
content: {
|
|
5
5
|
type: "text";
|
|
6
6
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-pages.d.ts","sourceRoot":"","sources":["../../src/tools/list-pages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"list-pages.d.ts","sourceRoot":"","sources":["../../src/tools/list-pages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,eAAe,EAAE,IAmD7B,CAAC;AAEF,wBAAsB,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO;;;;;GAgCnD"}
|
package/dist/tools/list-pages.js
CHANGED
|
@@ -1,15 +1,68 @@
|
|
|
1
1
|
import { callAPI } from "../api.js";
|
|
2
2
|
export const LIST_PAGES_TOOL = {
|
|
3
3
|
name: "list-pages",
|
|
4
|
-
description:
|
|
4
|
+
description: `List all deployed pages with optional filtering and search capabilities.
|
|
5
|
+
|
|
6
|
+
FILTERING OPTIONS:
|
|
7
|
+
- Filter by tag: Use 'tags' parameter to find pages with a specific tag
|
|
8
|
+
- Search across fields: Use 'search' parameter to find pages containing the search term
|
|
9
|
+
|
|
10
|
+
SEARCH BEHAVIOR:
|
|
11
|
+
- Without 'key': Searches across ALL fields (title, slug, tags, and metadata values)
|
|
12
|
+
- With 'key': Searches only in the specified field
|
|
13
|
+
- key="title": Search in page title only
|
|
14
|
+
- key="slug": Search in page slug only
|
|
15
|
+
- key="tags": Search in tags array only
|
|
16
|
+
- key="metadata": Search in metadata values (all nested levels)
|
|
17
|
+
- With 'key=metadata' + 'metadata_key': Search in a specific metadata field only
|
|
18
|
+
|
|
19
|
+
EXAMPLES:
|
|
20
|
+
1. Find all pages: list-pages (no params)
|
|
21
|
+
2. Find pages tagged "marketing": list-pages with tags="marketing"
|
|
22
|
+
3. Find pages mentioning "dashboard": list-pages with search="dashboard"
|
|
23
|
+
4. Find pages with "admin" in title: list-pages with search="admin", key="title"
|
|
24
|
+
5. Find pages where vendor is "Apple": list-pages with search="Apple", key="metadata", metadata_key="vendor"
|
|
25
|
+
|
|
26
|
+
Returns: Array of page summaries (id, slug, title, url, tags, metadata, timestamps). Does not include page content.`,
|
|
5
27
|
inputSchema: {
|
|
6
28
|
type: "object",
|
|
7
|
-
properties: {
|
|
29
|
+
properties: {
|
|
30
|
+
tags: {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Filter by exact tag match (case-insensitive). Returns pages that have this tag.",
|
|
33
|
+
},
|
|
34
|
+
search: {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Search term to find pages. Case-insensitive partial match. Without 'key' param, searches across title, slug, tags, and all metadata values.",
|
|
37
|
+
},
|
|
38
|
+
key: {
|
|
39
|
+
type: "string",
|
|
40
|
+
enum: ["title", "tags", "slug", "metadata"],
|
|
41
|
+
description: "Specify which field to search in. Only used with 'search' param. If omitted, searches all fields.",
|
|
42
|
+
},
|
|
43
|
+
metadata_key: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "When key='metadata', specify a specific metadata field to search in. E.g., 'vendor' to search only in metadata.vendor",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
8
48
|
},
|
|
9
49
|
};
|
|
10
|
-
export async function handleListPages() {
|
|
50
|
+
export async function handleListPages(args) {
|
|
51
|
+
const { tags, search, key, metadata_key } = args || {};
|
|
52
|
+
// Build query parameters
|
|
53
|
+
const params = new URLSearchParams();
|
|
54
|
+
if (tags)
|
|
55
|
+
params.append("tags", tags);
|
|
56
|
+
if (search)
|
|
57
|
+
params.append("search", search);
|
|
58
|
+
if (key)
|
|
59
|
+
params.append("key", key);
|
|
60
|
+
if (metadata_key)
|
|
61
|
+
params.append("metadata_key", metadata_key);
|
|
62
|
+
const queryString = params.toString();
|
|
63
|
+
const endpoint = queryString ? `/v1/pages?${queryString}` : "/v1/pages";
|
|
11
64
|
// Call the list pages API
|
|
12
|
-
const response = await callAPI(
|
|
65
|
+
const response = await callAPI(endpoint, "GET");
|
|
13
66
|
return {
|
|
14
67
|
content: [
|
|
15
68
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-pages.js","sourceRoot":"","sources":["../../src/tools/list-pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,IAAI,EAAE,YAAY;IAClB,WAAW,
|
|
1
|
+
{"version":3,"file":"list-pages.js","sourceRoot":"","sources":["../../src/tools/list-pages.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,eAAe,GAAS;IACnC,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;oHAsBqG;IAClH,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iFAAiF;aACpF;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6IAA6I;aAChJ;YACD,GAAG,EAAE;gBACH,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;gBAC3C,WAAW,EACT,mGAAmG;aACtG;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,uHAAuH;aAC1H;SACF;KACF;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAc;IAClD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,EAAE,GAAI,IAAsB,IAAI,EAAE,CAAC;IAE1E,yBAAyB;IACzB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,IAAI,IAAI;QAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM;QAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,GAAG;QAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,YAAY;QAAE,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAE9D,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IACtC,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,aAAa,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IAExE,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAoB,QAAQ,EAAE,KAAK,CAAC,CAAC;IAEnE,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;iBACtB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-page.d.ts","sourceRoot":"","sources":["../../src/tools/update-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"update-page.d.ts","sourceRoot":"","sources":["../../src/tools/update-page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAI1D,eAAO,MAAM,gBAAgB,EAAE,IAqC9B,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO;;;;;GAyDnD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { callAPI } from "../api.js";
|
|
2
2
|
export const UPDATE_PAGE_TOOL = {
|
|
3
3
|
name: "update-page",
|
|
4
|
-
description: "Update an existing page by slug. You can update title, content, or
|
|
4
|
+
description: "Update an existing page by slug. You can update title, content, tags, or metadata individually or in combination. IMPORTANT: You must use the EXACT slug from list-pages response, including the timestamp suffix (e.g., 'my-page-1730229600'). At least one field (title, content, tags, or metadata) must be provided for update.",
|
|
5
5
|
inputSchema: {
|
|
6
6
|
type: "object",
|
|
7
7
|
properties: {
|
|
@@ -24,19 +24,24 @@ export const UPDATE_PAGE_TOOL = {
|
|
|
24
24
|
},
|
|
25
25
|
description: "Optional new array of tags to categorize the page (e.g., ['dashboard', 'finance']). This will replace existing tags. Tags are case-insensitive for filtering.",
|
|
26
26
|
},
|
|
27
|
+
metadata: {
|
|
28
|
+
type: "object",
|
|
29
|
+
description: "New metadata object to replace existing metadata. Note: This REPLACES the entire metadata object, not merges. To add a field, include all existing fields plus the new one. To remove a field, include all fields except the one to remove. Pass empty object {} to clear all metadata.",
|
|
30
|
+
},
|
|
27
31
|
},
|
|
28
32
|
required: ["slug"],
|
|
29
33
|
},
|
|
30
34
|
};
|
|
31
35
|
export async function handleUpdatePage(args) {
|
|
32
|
-
const { slug, title, content, tags } = args;
|
|
36
|
+
const { slug, title, content, tags, metadata } = args;
|
|
33
37
|
// Validate inputs
|
|
34
38
|
if (!slug) {
|
|
35
39
|
throw new Error("Missing required parameter: slug is required");
|
|
36
40
|
}
|
|
37
41
|
// Check if at least one field is provided
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
const hasMetadata = metadata && Object.keys(metadata).length > 0;
|
|
43
|
+
if (!title && !content && (!tags || tags.length === 0) && !hasMetadata) {
|
|
44
|
+
throw new Error("At least one field (title, content, tags, or metadata) must be provided for update");
|
|
40
45
|
}
|
|
41
46
|
// Build request body
|
|
42
47
|
const requestBody = {
|
|
@@ -51,6 +56,9 @@ export async function handleUpdatePage(args) {
|
|
|
51
56
|
if (tags && tags.length > 0) {
|
|
52
57
|
requestBody.tags = tags;
|
|
53
58
|
}
|
|
59
|
+
if (hasMetadata) {
|
|
60
|
+
requestBody.metadata = metadata;
|
|
61
|
+
}
|
|
54
62
|
// Call the update API
|
|
55
63
|
const response = await callAPI("/v1/pages", "PUT", requestBody);
|
|
56
64
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-page.js","sourceRoot":"","sources":["../../src/tools/update-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,
|
|
1
|
+
{"version":3,"file":"update-page.js","sourceRoot":"","sources":["../../src/tools/update-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,MAAM,CAAC,MAAM,gBAAgB,GAAS;IACpC,IAAI,EAAE,aAAa;IACnB,WAAW,EACT,qUAAqU;IACvU,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iHAAiH;aACpH;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kCAAkC;aAChD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6GAA6G;aAChH;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;iBACf;gBACD,WAAW,EACT,+JAA+J;aAClK;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,yRAAyR;aAC5R;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAa;IAClD,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,IAAsB,CAAC;IAExE,kBAAkB;IAClB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,0CAA0C;IAC1C,MAAM,WAAW,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAmB;QAClC,IAAI;KACL,CAAC;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,WAAW,CAAC,OAAO,GAAG,OAAO,CAAC;IAChC,CAAC;IACD,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1B,CAAC;IACD,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAClC,CAAC;IAED,sBAAsB;IACtB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAC5B,WAAW,EACX,KAAK,EACL,WAAW,CACZ,CAAC;IAEF,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,IAAI,EAAE,QAAQ,CAAC,IAAI;iBACpB,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface DeployPageArgs {
|
|
|
3
3
|
content: string;
|
|
4
4
|
slug: string;
|
|
5
5
|
tags?: string[];
|
|
6
|
+
metadata?: Record<string, unknown>;
|
|
6
7
|
}
|
|
7
8
|
export interface DeployPageResponse {
|
|
8
9
|
url: string;
|
|
@@ -13,6 +14,7 @@ export interface PageSummary {
|
|
|
13
14
|
title: string;
|
|
14
15
|
url: string;
|
|
15
16
|
tags?: string[];
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
16
18
|
created_at: string;
|
|
17
19
|
updated_at: string;
|
|
18
20
|
}
|
|
@@ -25,6 +27,7 @@ export interface UpdatePageArgs {
|
|
|
25
27
|
title?: string;
|
|
26
28
|
content?: string;
|
|
27
29
|
tags?: string[];
|
|
30
|
+
metadata?: Record<string, unknown>;
|
|
28
31
|
}
|
|
29
32
|
export interface UpdatePageResponse {
|
|
30
33
|
message: string;
|
|
@@ -36,4 +39,21 @@ export interface DeletePageArgs {
|
|
|
36
39
|
export interface DeletePageResponse {
|
|
37
40
|
message: string;
|
|
38
41
|
}
|
|
42
|
+
export interface GetPageArgs {
|
|
43
|
+
slug: string;
|
|
44
|
+
}
|
|
45
|
+
export interface GetPageResponse {
|
|
46
|
+
id: number;
|
|
47
|
+
slug: string;
|
|
48
|
+
title: string;
|
|
49
|
+
content: string;
|
|
50
|
+
tags?: string[];
|
|
51
|
+
metadata?: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
export interface ListPagesArgs {
|
|
54
|
+
tags?: string;
|
|
55
|
+
search?: string;
|
|
56
|
+
key?: "title" | "tags" | "slug" | "metadata";
|
|
57
|
+
metadata_key?: string;
|
|
58
|
+
}
|
|
39
59
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
9
9
|
import { DEPLOY_PAGE_TOOL, handleDeployPage } from "./tools/deploy-page.js";
|
|
10
10
|
import { LIST_PAGES_TOOL, handleListPages } from "./tools/list-pages.js";
|
|
11
|
+
import { GET_PAGE_TOOL, handleGetPage } from "./tools/get-page.js";
|
|
11
12
|
import { UPDATE_PAGE_TOOL, handleUpdatePage } from "./tools/update-page.js";
|
|
12
13
|
import { DELETE_PAGE_TOOL, handleDeletePage } from "./tools/delete-page.js";
|
|
13
14
|
|
|
@@ -27,7 +28,7 @@ const server = new Server(
|
|
|
27
28
|
// Handler for listing available tools
|
|
28
29
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
29
30
|
return {
|
|
30
|
-
tools: [DEPLOY_PAGE_TOOL, LIST_PAGES_TOOL, UPDATE_PAGE_TOOL, DELETE_PAGE_TOOL],
|
|
31
|
+
tools: [DEPLOY_PAGE_TOOL, LIST_PAGES_TOOL, GET_PAGE_TOOL, UPDATE_PAGE_TOOL, DELETE_PAGE_TOOL],
|
|
31
32
|
};
|
|
32
33
|
});
|
|
33
34
|
|
|
@@ -39,7 +40,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
39
40
|
if (name === "deploy-page") {
|
|
40
41
|
return await handleDeployPage(args);
|
|
41
42
|
} else if (name === "list-pages") {
|
|
42
|
-
return await handleListPages();
|
|
43
|
+
return await handleListPages(args);
|
|
44
|
+
} else if (name === "get-page") {
|
|
45
|
+
return await handleGetPage(args);
|
|
43
46
|
} else if (name === "update-page") {
|
|
44
47
|
return await handleUpdatePage(args);
|
|
45
48
|
} else if (name === "delete-page") {
|
package/src/tools/deploy-page.ts
CHANGED
|
@@ -34,13 +34,18 @@ export const DEPLOY_PAGE_TOOL: Tool = {
|
|
|
34
34
|
description:
|
|
35
35
|
"Optional array of tags to categorize the page (e.g., ['dashboard', 'finance']). Tags are case-insensitive for filtering.",
|
|
36
36
|
},
|
|
37
|
+
metadata: {
|
|
38
|
+
type: "object",
|
|
39
|
+
description:
|
|
40
|
+
"Optional key-value metadata to store with the page. Can contain any JSON structure (strings, numbers, arrays, nested objects). Useful for storing additional information like author/owner, category/classification, related resources, or custom attributes for filtering. Example: { \"vendor\": \"Apple\", \"category\": \"product\", \"attendees\": [\"John\", \"Jane\"] }. This metadata is searchable via list-pages tool.",
|
|
41
|
+
},
|
|
37
42
|
},
|
|
38
43
|
required: ["title", "content", "slug"],
|
|
39
44
|
},
|
|
40
45
|
};
|
|
41
46
|
|
|
42
47
|
export async function handleDeployPage(args: unknown) {
|
|
43
|
-
const { title, content, slug, tags } = args as DeployPageArgs;
|
|
48
|
+
const { title, content, slug, tags, metadata } = args as DeployPageArgs;
|
|
44
49
|
|
|
45
50
|
// Validate inputs
|
|
46
51
|
if (!title || !content || !slug) {
|
|
@@ -61,6 +66,11 @@ export async function handleDeployPage(args: unknown) {
|
|
|
61
66
|
requestBody.tags = tags;
|
|
62
67
|
}
|
|
63
68
|
|
|
69
|
+
// Add metadata if provided
|
|
70
|
+
if (metadata && Object.keys(metadata).length > 0) {
|
|
71
|
+
requestBody.metadata = metadata;
|
|
72
|
+
}
|
|
73
|
+
|
|
64
74
|
// Call the deploy API
|
|
65
75
|
const response = await callAPI<DeployPageResponse>(
|
|
66
76
|
"/v1/deploy",
|
|
@@ -78,6 +88,7 @@ export async function handleDeployPage(args: unknown) {
|
|
|
78
88
|
message: "Page deployed successfully",
|
|
79
89
|
url: response.url,
|
|
80
90
|
tags: tags || [],
|
|
91
|
+
metadata: metadata || {},
|
|
81
92
|
},
|
|
82
93
|
null,
|
|
83
94
|
2
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { callAPI } from "../api.js";
|
|
3
|
+
import { GetPageArgs, GetPageResponse } from "../types.js";
|
|
4
|
+
|
|
5
|
+
export const GET_PAGE_TOOL: Tool = {
|
|
6
|
+
name: "get-page",
|
|
7
|
+
description:
|
|
8
|
+
"Get the full content of a page by its slug. Returns the complete page data including HTML content, title, and tags. Use the exact slug from list-pages response (including timestamp suffix).",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
slug: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description:
|
|
15
|
+
"The exact slug of the page to retrieve (must match the slug from list-pages response, including timestamp suffix)",
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
required: ["slug"],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export async function handleGetPage(args: unknown) {
|
|
23
|
+
const { slug } = args as GetPageArgs;
|
|
24
|
+
|
|
25
|
+
// Validate inputs
|
|
26
|
+
if (!slug) {
|
|
27
|
+
throw new Error("Missing required parameter: slug is required");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Call the get-page API
|
|
31
|
+
const response = await callAPI<GetPageResponse>("/v1/get-page", "POST", {
|
|
32
|
+
slug,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{
|
|
38
|
+
type: "text" as const,
|
|
39
|
+
text: JSON.stringify(
|
|
40
|
+
{
|
|
41
|
+
success: true,
|
|
42
|
+
page: response,
|
|
43
|
+
},
|
|
44
|
+
null,
|
|
45
|
+
2
|
|
46
|
+
),
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
package/src/tools/list-pages.ts
CHANGED
|
@@ -1,20 +1,75 @@
|
|
|
1
1
|
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import { callAPI } from "../api.js";
|
|
3
|
-
import { ListPagesResponse } from "../types.js";
|
|
3
|
+
import { ListPagesArgs, ListPagesResponse } from "../types.js";
|
|
4
4
|
|
|
5
5
|
export const LIST_PAGES_TOOL: Tool = {
|
|
6
6
|
name: "list-pages",
|
|
7
|
-
description:
|
|
8
|
-
|
|
7
|
+
description: `List all deployed pages with optional filtering and search capabilities.
|
|
8
|
+
|
|
9
|
+
FILTERING OPTIONS:
|
|
10
|
+
- Filter by tag: Use 'tags' parameter to find pages with a specific tag
|
|
11
|
+
- Search across fields: Use 'search' parameter to find pages containing the search term
|
|
12
|
+
|
|
13
|
+
SEARCH BEHAVIOR:
|
|
14
|
+
- Without 'key': Searches across ALL fields (title, slug, tags, and metadata values)
|
|
15
|
+
- With 'key': Searches only in the specified field
|
|
16
|
+
- key="title": Search in page title only
|
|
17
|
+
- key="slug": Search in page slug only
|
|
18
|
+
- key="tags": Search in tags array only
|
|
19
|
+
- key="metadata": Search in metadata values (all nested levels)
|
|
20
|
+
- With 'key=metadata' + 'metadata_key': Search in a specific metadata field only
|
|
21
|
+
|
|
22
|
+
EXAMPLES:
|
|
23
|
+
1. Find all pages: list-pages (no params)
|
|
24
|
+
2. Find pages tagged "marketing": list-pages with tags="marketing"
|
|
25
|
+
3. Find pages mentioning "dashboard": list-pages with search="dashboard"
|
|
26
|
+
4. Find pages with "admin" in title: list-pages with search="admin", key="title"
|
|
27
|
+
5. Find pages where vendor is "Apple": list-pages with search="Apple", key="metadata", metadata_key="vendor"
|
|
28
|
+
|
|
29
|
+
Returns: Array of page summaries (id, slug, title, url, tags, metadata, timestamps). Does not include page content.`,
|
|
9
30
|
inputSchema: {
|
|
10
31
|
type: "object",
|
|
11
|
-
properties: {
|
|
32
|
+
properties: {
|
|
33
|
+
tags: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description:
|
|
36
|
+
"Filter by exact tag match (case-insensitive). Returns pages that have this tag.",
|
|
37
|
+
},
|
|
38
|
+
search: {
|
|
39
|
+
type: "string",
|
|
40
|
+
description:
|
|
41
|
+
"Search term to find pages. Case-insensitive partial match. Without 'key' param, searches across title, slug, tags, and all metadata values.",
|
|
42
|
+
},
|
|
43
|
+
key: {
|
|
44
|
+
type: "string",
|
|
45
|
+
enum: ["title", "tags", "slug", "metadata"],
|
|
46
|
+
description:
|
|
47
|
+
"Specify which field to search in. Only used with 'search' param. If omitted, searches all fields.",
|
|
48
|
+
},
|
|
49
|
+
metadata_key: {
|
|
50
|
+
type: "string",
|
|
51
|
+
description:
|
|
52
|
+
"When key='metadata', specify a specific metadata field to search in. E.g., 'vendor' to search only in metadata.vendor",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
12
55
|
},
|
|
13
56
|
};
|
|
14
57
|
|
|
15
|
-
export async function handleListPages() {
|
|
58
|
+
export async function handleListPages(args?: unknown) {
|
|
59
|
+
const { tags, search, key, metadata_key } = (args as ListPagesArgs) || {};
|
|
60
|
+
|
|
61
|
+
// Build query parameters
|
|
62
|
+
const params = new URLSearchParams();
|
|
63
|
+
if (tags) params.append("tags", tags);
|
|
64
|
+
if (search) params.append("search", search);
|
|
65
|
+
if (key) params.append("key", key);
|
|
66
|
+
if (metadata_key) params.append("metadata_key", metadata_key);
|
|
67
|
+
|
|
68
|
+
const queryString = params.toString();
|
|
69
|
+
const endpoint = queryString ? `/v1/pages?${queryString}` : "/v1/pages";
|
|
70
|
+
|
|
16
71
|
// Call the list pages API
|
|
17
|
-
const response = await callAPI<ListPagesResponse>(
|
|
72
|
+
const response = await callAPI<ListPagesResponse>(endpoint, "GET");
|
|
18
73
|
|
|
19
74
|
return {
|
|
20
75
|
content: [
|
package/src/tools/update-page.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { UpdatePageArgs, UpdatePageResponse } from "../types.js";
|
|
|
5
5
|
export const UPDATE_PAGE_TOOL: Tool = {
|
|
6
6
|
name: "update-page",
|
|
7
7
|
description:
|
|
8
|
-
"Update an existing page by slug. You can update title, content, or
|
|
8
|
+
"Update an existing page by slug. You can update title, content, tags, or metadata individually or in combination. IMPORTANT: You must use the EXACT slug from list-pages response, including the timestamp suffix (e.g., 'my-page-1730229600'). At least one field (title, content, tags, or metadata) must be provided for update.",
|
|
9
9
|
inputSchema: {
|
|
10
10
|
type: "object",
|
|
11
11
|
properties: {
|
|
@@ -31,13 +31,18 @@ export const UPDATE_PAGE_TOOL: Tool = {
|
|
|
31
31
|
description:
|
|
32
32
|
"Optional new array of tags to categorize the page (e.g., ['dashboard', 'finance']). This will replace existing tags. Tags are case-insensitive for filtering.",
|
|
33
33
|
},
|
|
34
|
+
metadata: {
|
|
35
|
+
type: "object",
|
|
36
|
+
description:
|
|
37
|
+
"New metadata object to replace existing metadata. Note: This REPLACES the entire metadata object, not merges. To add a field, include all existing fields plus the new one. To remove a field, include all fields except the one to remove. Pass empty object {} to clear all metadata.",
|
|
38
|
+
},
|
|
34
39
|
},
|
|
35
40
|
required: ["slug"],
|
|
36
41
|
},
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
export async function handleUpdatePage(args: unknown) {
|
|
40
|
-
const { slug, title, content, tags } = args as UpdatePageArgs;
|
|
45
|
+
const { slug, title, content, tags, metadata } = args as UpdatePageArgs;
|
|
41
46
|
|
|
42
47
|
// Validate inputs
|
|
43
48
|
if (!slug) {
|
|
@@ -45,9 +50,10 @@ export async function handleUpdatePage(args: unknown) {
|
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
// Check if at least one field is provided
|
|
48
|
-
|
|
53
|
+
const hasMetadata = metadata && Object.keys(metadata).length > 0;
|
|
54
|
+
if (!title && !content && (!tags || tags.length === 0) && !hasMetadata) {
|
|
49
55
|
throw new Error(
|
|
50
|
-
"At least one field (title, content, or
|
|
56
|
+
"At least one field (title, content, tags, or metadata) must be provided for update"
|
|
51
57
|
);
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -65,6 +71,9 @@ export async function handleUpdatePage(args: unknown) {
|
|
|
65
71
|
if (tags && tags.length > 0) {
|
|
66
72
|
requestBody.tags = tags;
|
|
67
73
|
}
|
|
74
|
+
if (hasMetadata) {
|
|
75
|
+
requestBody.metadata = metadata;
|
|
76
|
+
}
|
|
68
77
|
|
|
69
78
|
// Call the update API
|
|
70
79
|
const response = await callAPI<UpdatePageResponse>(
|
package/src/types.ts
CHANGED
|
@@ -3,6 +3,7 @@ export interface DeployPageArgs {
|
|
|
3
3
|
content: string;
|
|
4
4
|
slug: string;
|
|
5
5
|
tags?: string[];
|
|
6
|
+
metadata?: Record<string, unknown>;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export interface DeployPageResponse {
|
|
@@ -15,6 +16,7 @@ export interface PageSummary {
|
|
|
15
16
|
title: string;
|
|
16
17
|
url: string;
|
|
17
18
|
tags?: string[];
|
|
19
|
+
metadata?: Record<string, unknown>;
|
|
18
20
|
created_at: string;
|
|
19
21
|
updated_at: string;
|
|
20
22
|
}
|
|
@@ -29,6 +31,7 @@ export interface UpdatePageArgs {
|
|
|
29
31
|
title?: string;
|
|
30
32
|
content?: string;
|
|
31
33
|
tags?: string[];
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
export interface UpdatePageResponse {
|
|
@@ -43,3 +46,23 @@ export interface DeletePageArgs {
|
|
|
43
46
|
export interface DeletePageResponse {
|
|
44
47
|
message: string;
|
|
45
48
|
}
|
|
49
|
+
|
|
50
|
+
export interface GetPageArgs {
|
|
51
|
+
slug: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface GetPageResponse {
|
|
55
|
+
id: number;
|
|
56
|
+
slug: string;
|
|
57
|
+
title: string;
|
|
58
|
+
content: string;
|
|
59
|
+
tags?: string[];
|
|
60
|
+
metadata?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface ListPagesArgs {
|
|
64
|
+
tags?: string;
|
|
65
|
+
search?: string;
|
|
66
|
+
key?: "title" | "tags" | "slug" | "metadata";
|
|
67
|
+
metadata_key?: string;
|
|
68
|
+
}
|