pmwiki-mcp 1.0.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/README.md ADDED
@@ -0,0 +1,153 @@
1
+ # PmWiki MCP Server
2
+
3
+ A [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that enables AI agents like Claude to interact with a PmWiki instance.
4
+
5
+ ## Features
6
+
7
+ - **wiki_find_pages** - Search for pages by name or content
8
+ - **wiki_read_page** - Read page content (raw, markdown, or HTML)
9
+ - **wiki_create_page** - Create new wiki pages
10
+ - **wiki_edit_page** - Edit existing wiki pages
11
+ - **wiki_list_pages** - List pages in a group
12
+
13
+ ## Installation
14
+
15
+ ### Using npx (recommended)
16
+
17
+ No installation needed - just configure Claude Desktop:
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "pmwiki": {
23
+ "command": "npx",
24
+ "args": ["-y", "pmwiki-mcp"],
25
+ "env": {
26
+ "PMWIKI_URL": "https://your-wiki-url.com",
27
+ "PMWIKI_MCP_KEY": "your-mcp-key-here"
28
+ }
29
+ }
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### Global installation
35
+
36
+ ```bash
37
+ npm install -g pmwiki-mcp
38
+ ```
39
+
40
+ ## Configuration
41
+
42
+ The server requires two environment variables:
43
+
44
+ | Variable | Description |
45
+ |----------|-------------|
46
+ | `PMWIKI_URL` | Base URL of your wiki (e.g., `https://wiki.example.com`) |
47
+ | `PMWIKI_MCP_KEY` | MCP authentication key (generated via `?action=mcpkeygen`) |
48
+
49
+ ## Server Setup
50
+
51
+ Your PmWiki installation needs the MCP cookbook (`cookbook/mcp.php`) which provides the API endpoints:
52
+
53
+ 1. Copy `cookbook/mcp.php` to your wiki's cookbook directory
54
+ 2. Add to `local/config.php`:
55
+ ```php
56
+ include_once("$FarmD/cookbook/mcp.php");
57
+ ```
58
+ 3. Generate an MCP key by visiting `?action=mcpkeygen` while logged in as admin
59
+ 4. Save the key securely - it provides full read/write access to all pages
60
+
61
+ ## Tools
62
+
63
+ ### wiki_find_pages
64
+
65
+ Search for wiki pages by name or content.
66
+
67
+ **Parameters:**
68
+ - `query` (required) - Search query
69
+ - `group` (optional) - Limit search to a specific group
70
+ - `nameOnly` (optional) - Only search page names, not content
71
+ - `limit` (optional) - Maximum results (default: 50)
72
+
73
+ **Example:**
74
+ ```
75
+ Search for pages about "authentication"
76
+ ```
77
+
78
+ ### wiki_read_page
79
+
80
+ Read a wiki page's content.
81
+
82
+ **Parameters:**
83
+ - `pagename` (required) - Page name (e.g., "Main.HomePage" or "Main/HomePage")
84
+ - `format` (optional) - Output format: `raw`, `markdown`, or `html` (default: raw)
85
+
86
+ **Example:**
87
+ ```
88
+ Read the page Main/AdminPage in markdown format
89
+ ```
90
+
91
+ ### wiki_create_page
92
+
93
+ Create a new wiki page.
94
+
95
+ **Parameters:**
96
+ - `pagename` (required) - Page name
97
+ - `content` (required) - Page content in PmWiki markup
98
+ - `summary` (optional) - Edit summary
99
+
100
+ **Example:**
101
+ ```
102
+ Create page Main.NewPage with content "!! Welcome\n\nThis is a new page."
103
+ ```
104
+
105
+ ### wiki_edit_page
106
+
107
+ Edit an existing wiki page.
108
+
109
+ **Parameters:**
110
+ - `pagename` (required) - Page name
111
+ - `content` (required) - New page content
112
+ - `summary` (optional) - Edit summary
113
+
114
+ ### wiki_list_pages
115
+
116
+ List wiki pages in a group.
117
+
118
+ **Parameters:**
119
+ - `group` (optional) - Group name (lists all if omitted)
120
+ - `limit` (optional) - Maximum pages (default: 100)
121
+
122
+ **Example:**
123
+ ```
124
+ List all pages in the Main group
125
+ ```
126
+
127
+ ## Security
128
+
129
+ - The MCP key provides full access to all wiki pages - protect it like a password
130
+ - All requests are logged to `wiki.d/.mcplog`
131
+ - Rate limiting prevents abuse (60 requests per minute per IP)
132
+ - HTTPS is strongly recommended for production use
133
+
134
+ ## Development
135
+
136
+ ```bash
137
+ # Clone the repository
138
+ git clone https://github.com/milee98/pmwiki.git
139
+ cd pmwiki/pmwiki-mcp
140
+
141
+ # Install dependencies
142
+ npm install
143
+
144
+ # Build
145
+ npm run build
146
+
147
+ # Run locally
148
+ PMWIKI_URL=https://wiki.example.com PMWIKI_MCP_KEY=xxx npm start
149
+ ```
150
+
151
+ ## License
152
+
153
+ MIT
@@ -0,0 +1,73 @@
1
+ /**
2
+ * HTTP client for PmWiki MCP API
3
+ */
4
+ import { Config } from '../config.js';
5
+ export interface WikiPage {
6
+ pagename: string;
7
+ title: string;
8
+ text: string;
9
+ format: string;
10
+ time?: number;
11
+ author?: string;
12
+ group: string;
13
+ name: string;
14
+ }
15
+ export interface PageListItem {
16
+ pagename: string;
17
+ group: string;
18
+ name: string;
19
+ title: string;
20
+ time?: number;
21
+ author?: string;
22
+ }
23
+ export interface SearchResult {
24
+ pagename: string;
25
+ group: string;
26
+ name: string;
27
+ title: string;
28
+ time?: number;
29
+ matchType: 'name' | 'content' | 'both';
30
+ snippet?: string;
31
+ }
32
+ export interface ApiResponse<T> {
33
+ success: boolean;
34
+ error?: string;
35
+ [key: string]: unknown;
36
+ }
37
+ export declare class WikiClient {
38
+ private baseUrl;
39
+ private mcpKey;
40
+ constructor(config: Config);
41
+ private request;
42
+ /**
43
+ * Read a wiki page
44
+ */
45
+ readPage(pagename: string, format?: 'raw' | 'markdown' | 'html'): Promise<WikiPage>;
46
+ /**
47
+ * List pages in a group
48
+ */
49
+ listPages(group?: string, limit?: number): Promise<PageListItem[]>;
50
+ /**
51
+ * Search for pages
52
+ */
53
+ searchPages(query: string, options?: {
54
+ group?: string;
55
+ nameOnly?: boolean;
56
+ limit?: number;
57
+ }): Promise<SearchResult[]>;
58
+ /**
59
+ * Create a new page
60
+ */
61
+ createPage(pagename: string, content: string, summary?: string): Promise<{
62
+ pagename: string;
63
+ action: string;
64
+ }>;
65
+ /**
66
+ * Edit an existing page
67
+ */
68
+ editPage(pagename: string, content: string, summary?: string): Promise<{
69
+ pagename: string;
70
+ action: string;
71
+ }>;
72
+ }
73
+ //# sourceMappingURL=wikiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wikiClient.d.ts","sourceRoot":"","sources":["../../src/api/wikiClient.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;YAKZ,OAAO;IA2CrB;;OAEG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,KAAK,GAAG,UAAU,GAAG,MAAc,GAC1C,OAAO,CAAC,QAAQ,CAAC;IAiBpB;;OAEG;IACG,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAWxE;;OAEG;IACG,WAAW,CACf,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;KACX,GACL,OAAO,CAAC,YAAY,EAAE,CAAC;IAY1B;;OAEG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBhD;;OAEG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAgBjD"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * HTTP client for PmWiki MCP API
3
+ */
4
+ export class WikiClient {
5
+ baseUrl;
6
+ mcpKey;
7
+ constructor(config) {
8
+ this.baseUrl = config.wikiUrl;
9
+ this.mcpKey = config.mcpKey;
10
+ }
11
+ async request(action, params = {}, method = 'GET', body) {
12
+ const url = new URL(this.baseUrl);
13
+ url.searchParams.set('action', action);
14
+ url.searchParams.set('mcpkey', this.mcpKey);
15
+ for (const [key, value] of Object.entries(params)) {
16
+ url.searchParams.set(key, value);
17
+ }
18
+ const options = {
19
+ method,
20
+ headers: {
21
+ Accept: 'application/json',
22
+ },
23
+ };
24
+ if (method === 'POST' && body) {
25
+ options.headers = {
26
+ ...options.headers,
27
+ 'Content-Type': 'application/x-www-form-urlencoded',
28
+ };
29
+ const formData = new URLSearchParams();
30
+ for (const [key, value] of Object.entries(body)) {
31
+ formData.set(key, value);
32
+ }
33
+ options.body = formData.toString();
34
+ }
35
+ const response = await fetch(url.toString(), options);
36
+ const data = (await response.json());
37
+ if (!response.ok || data.error) {
38
+ throw new Error(data.error || `HTTP ${response.status}`);
39
+ }
40
+ return data;
41
+ }
42
+ /**
43
+ * Read a wiki page
44
+ */
45
+ async readPage(pagename, format = 'raw') {
46
+ const response = await this.request('mcpread', { page: pagename, format });
47
+ return {
48
+ pagename: response.pagename,
49
+ title: response.title,
50
+ text: response.text,
51
+ format: response.format,
52
+ time: response.time,
53
+ author: response.author,
54
+ group: response.group,
55
+ name: response.name,
56
+ };
57
+ }
58
+ /**
59
+ * List pages in a group
60
+ */
61
+ async listPages(group, limit) {
62
+ const params = {};
63
+ if (group)
64
+ params.group = group;
65
+ if (limit)
66
+ params.limit = String(limit);
67
+ const response = await this.request('mcplist', params);
68
+ return response.pages;
69
+ }
70
+ /**
71
+ * Search for pages
72
+ */
73
+ async searchPages(query, options = {}) {
74
+ const params = { q: query };
75
+ if (options.group)
76
+ params.group = options.group;
77
+ if (options.nameOnly)
78
+ params.nameonly = '1';
79
+ if (options.limit)
80
+ params.limit = String(options.limit);
81
+ const response = await this.request('mcpsearch', params);
82
+ return response.results;
83
+ }
84
+ /**
85
+ * Create a new page
86
+ */
87
+ async createPage(pagename, content, summary) {
88
+ const body = {
89
+ page: pagename,
90
+ content,
91
+ };
92
+ if (summary)
93
+ body.summary = summary;
94
+ const response = await this.request('mcpwrite', {}, 'POST', body);
95
+ if (response.action !== 'created') {
96
+ throw new Error(`Page already exists: ${pagename}`);
97
+ }
98
+ return {
99
+ pagename: response.pagename,
100
+ action: response.action,
101
+ };
102
+ }
103
+ /**
104
+ * Edit an existing page
105
+ */
106
+ async editPage(pagename, content, summary) {
107
+ const body = {
108
+ page: pagename,
109
+ content,
110
+ };
111
+ if (summary)
112
+ body.summary = summary;
113
+ const response = await this.request('mcpwrite', {}, 'POST', body);
114
+ return {
115
+ pagename: response.pagename,
116
+ action: response.action,
117
+ };
118
+ }
119
+ }
120
+ //# sourceMappingURL=wikiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wikiClient.js","sourceRoot":"","sources":["../../src/api/wikiClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Configuration for PmWiki MCP server
3
+ *
4
+ * Environment variables:
5
+ * PMWIKI_URL - Base URL of the wiki (e.g., https://wiki.mjlee.xyz)
6
+ * PMWIKI_MCP_KEY - MCP authentication key
7
+ */
8
+ export interface Config {
9
+ wikiUrl: string;
10
+ mcpKey: string;
11
+ }
12
+ export declare function getConfig(): Config;
13
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,SAAS,IAAI,MAAM,CAmBlC"}
package/dist/config.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Configuration for PmWiki MCP server
3
+ *
4
+ * Environment variables:
5
+ * PMWIKI_URL - Base URL of the wiki (e.g., https://wiki.mjlee.xyz)
6
+ * PMWIKI_MCP_KEY - MCP authentication key
7
+ */
8
+ export function getConfig() {
9
+ const wikiUrl = process.env.PMWIKI_URL;
10
+ const mcpKey = process.env.PMWIKI_MCP_KEY;
11
+ if (!wikiUrl) {
12
+ throw new Error('PMWIKI_URL environment variable is required');
13
+ }
14
+ if (!mcpKey) {
15
+ throw new Error('PMWIKI_MCP_KEY environment variable is required');
16
+ }
17
+ // Normalize URL (remove trailing slash)
18
+ const normalizedUrl = wikiUrl.replace(/\/+$/, '');
19
+ return {
20
+ wikiUrl: normalizedUrl,
21
+ mcpKey,
22
+ };
23
+ }
24
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,UAAU,SAAS;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,wCAAwC;IACxC,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAElD,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,MAAM;KACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PmWiki MCP Server
4
+ *
5
+ * Provides Model Context Protocol tools for interacting with a PmWiki instance.
6
+ *
7
+ * Environment variables:
8
+ * PMWIKI_URL - Base URL of the wiki (e.g., https://wiki.mjlee.xyz)
9
+ * PMWIKI_MCP_KEY - MCP authentication key
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
package/dist/index.js ADDED
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PmWiki MCP Server
4
+ *
5
+ * Provides Model Context Protocol tools for interacting with a PmWiki instance.
6
+ *
7
+ * Environment variables:
8
+ * PMWIKI_URL - Base URL of the wiki (e.g., https://wiki.mjlee.xyz)
9
+ * PMWIKI_MCP_KEY - MCP authentication key
10
+ */
11
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
12
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
13
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
14
+ import { getConfig } from './config.js';
15
+ import { WikiClient } from './api/wikiClient.js';
16
+ import { findPages, findPagesTool } from './tools/findPages.js';
17
+ import { readPage, readPageTool } from './tools/readPage.js';
18
+ import { createPage, createPageTool } from './tools/createPage.js';
19
+ import { editPage, editPageTool } from './tools/editPage.js';
20
+ import { listPages, listPagesTool } from './tools/listPages.js';
21
+ const config = getConfig();
22
+ const client = new WikiClient(config);
23
+ const server = new Server({
24
+ name: 'pmwiki-mcp',
25
+ version: '1.0.0',
26
+ }, {
27
+ capabilities: {
28
+ tools: {},
29
+ },
30
+ });
31
+ // List available tools
32
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
33
+ return {
34
+ tools: [
35
+ findPagesTool,
36
+ readPageTool,
37
+ createPageTool,
38
+ editPageTool,
39
+ listPagesTool,
40
+ ],
41
+ };
42
+ });
43
+ // Handle tool calls
44
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
45
+ const { name, arguments: args } = request.params;
46
+ try {
47
+ let result;
48
+ switch (name) {
49
+ case 'wiki_find_pages':
50
+ result = await findPages(client, args);
51
+ break;
52
+ case 'wiki_read_page':
53
+ result = await readPage(client, args);
54
+ break;
55
+ case 'wiki_create_page':
56
+ result = await createPage(client, args);
57
+ break;
58
+ case 'wiki_edit_page':
59
+ result = await editPage(client, args);
60
+ break;
61
+ case 'wiki_list_pages':
62
+ result = await listPages(client, args);
63
+ break;
64
+ default:
65
+ throw new Error(`Unknown tool: ${name}`);
66
+ }
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: JSON.stringify(result, null, 2),
72
+ },
73
+ ],
74
+ };
75
+ }
76
+ catch (error) {
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: JSON.stringify({ error: message }, null, 2),
83
+ },
84
+ ],
85
+ isError: true,
86
+ };
87
+ }
88
+ });
89
+ // Start the server
90
+ async function main() {
91
+ const transport = new StdioServerTransport();
92
+ await server.connect(transport);
93
+ console.error('PmWiki MCP server started');
94
+ }
95
+ main().catch((error) => {
96
+ console.error('Fatal error:', error);
97
+ process.exit(1);
98
+ });
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,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;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;AAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAEtC,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,uBAAuB;AACvB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;IAC1D,OAAO;QACL,KAAK,EAAE;YACL,aAAa;YACb,YAAY;YACZ,cAAc;YACd,YAAY;YACZ,aAAa;SACd;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,oBAAoB;AACpB,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAEjD,IAAI,CAAC;QACH,IAAI,MAAe,CAAC;QAEpB,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,IAAuC,CAAC,CAAC;gBAC1E,MAAM;YAER,KAAK,gBAAgB;gBACnB,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAsC,CAAC,CAAC;gBACxE,MAAM;YAER,KAAK,kBAAkB;gBACrB,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,IAAwC,CAAC,CAAC;gBAC5E,MAAM;YAER,KAAK,gBAAgB;gBACnB,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAsC,CAAC,CAAC;gBACxE,MAAM;YAER,KAAK,iBAAiB;gBACpB,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,IAAuC,CAAC,CAAC;gBAC1E,MAAM;YAER;gBACE,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;iBACtC;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBAClD;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;AAC7C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * wiki_create_page tool - Create a new wiki page
3
+ */
4
+ import { z } from 'zod';
5
+ import { WikiClient } from '../api/wikiClient.js';
6
+ export declare const createPageSchema: z.ZodObject<{
7
+ pagename: z.ZodString;
8
+ content: z.ZodString;
9
+ summary: z.ZodOptional<z.ZodString>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ content: string;
12
+ pagename: string;
13
+ summary?: string | undefined;
14
+ }, {
15
+ content: string;
16
+ pagename: string;
17
+ summary?: string | undefined;
18
+ }>;
19
+ export type CreatePageInput = z.infer<typeof createPageSchema>;
20
+ export interface CreatePageResult {
21
+ pagename: string;
22
+ action: string;
23
+ message: string;
24
+ }
25
+ export declare function createPage(client: WikiClient, input: CreatePageInput): Promise<CreatePageResult>;
26
+ export declare const createPageTool: {
27
+ name: string;
28
+ description: string;
29
+ inputSchema: {
30
+ type: "object";
31
+ properties: {
32
+ pagename: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ content: {
37
+ type: string;
38
+ description: string;
39
+ };
40
+ summary: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ };
45
+ required: string[];
46
+ };
47
+ };
48
+ //# sourceMappingURL=createPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPage.d.ts","sourceRoot":"","sources":["../../src/tools/createPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAM3B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAa3B;AAED,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;CAsB1B,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * wiki_create_page tool - Create a new wiki page
3
+ */
4
+ import { z } from 'zod';
5
+ export const createPageSchema = z.object({
6
+ pagename: z
7
+ .string()
8
+ .describe('Page name in Group.Name or Group/Name format'),
9
+ content: z.string().describe('Page content in PmWiki markup format'),
10
+ summary: z.string().optional().describe('Edit summary describing the change'),
11
+ });
12
+ export async function createPage(client, input) {
13
+ // Normalize pagename (convert / to .)
14
+ const pagename = input.pagename.replace('/', '.');
15
+ const result = await client.createPage(pagename, input.content, input.summary);
16
+ return {
17
+ pagename: result.pagename,
18
+ action: result.action,
19
+ message: `Page ${result.pagename} created successfully`,
20
+ };
21
+ }
22
+ export const createPageTool = {
23
+ name: 'wiki_create_page',
24
+ description: 'Create a new wiki page. Fails if the page already exists (use wiki_edit_page to update existing pages).',
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: {
28
+ pagename: {
29
+ type: 'string',
30
+ description: 'Page name in Group.Name or Group/Name format',
31
+ },
32
+ content: {
33
+ type: 'string',
34
+ description: 'Page content in PmWiki markup format',
35
+ },
36
+ summary: {
37
+ type: 'string',
38
+ description: 'Edit summary describing the change (optional)',
39
+ },
40
+ },
41
+ required: ['pagename', 'content'],
42
+ },
43
+ };
44
+ //# sourceMappingURL=createPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPage.js","sourceRoot":"","sources":["../../src/tools/createPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;IACpE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC9E,CAAC,CAAC;AAUH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAkB,EAClB,KAAsB;IAEtB,sCAAsC;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,UAAU,CACpC,QAAQ,EACR,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,CACd,CAAC;IACF,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,QAAQ,MAAM,CAAC,QAAQ,uBAAuB;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,yGAAyG;IAC3G,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sCAAsC;aACpD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,+CAA+C;aAC7D;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;KAClC;CACF,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * wiki_edit_page tool - Edit an existing wiki page
3
+ */
4
+ import { z } from 'zod';
5
+ import { WikiClient } from '../api/wikiClient.js';
6
+ export declare const editPageSchema: z.ZodObject<{
7
+ pagename: z.ZodString;
8
+ content: z.ZodString;
9
+ summary: z.ZodOptional<z.ZodString>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ content: string;
12
+ pagename: string;
13
+ summary?: string | undefined;
14
+ }, {
15
+ content: string;
16
+ pagename: string;
17
+ summary?: string | undefined;
18
+ }>;
19
+ export type EditPageInput = z.infer<typeof editPageSchema>;
20
+ export interface EditPageResult {
21
+ pagename: string;
22
+ action: string;
23
+ message: string;
24
+ }
25
+ export declare function editPage(client: WikiClient, input: EditPageInput): Promise<EditPageResult>;
26
+ export declare const editPageTool: {
27
+ name: string;
28
+ description: string;
29
+ inputSchema: {
30
+ type: "object";
31
+ properties: {
32
+ pagename: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ content: {
37
+ type: string;
38
+ description: string;
39
+ };
40
+ summary: {
41
+ type: string;
42
+ description: string;
43
+ };
44
+ };
45
+ required: string[];
46
+ };
47
+ };
48
+ //# sourceMappingURL=editPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editPage.d.ts","sourceRoot":"","sources":["../../src/tools/editPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,eAAO,MAAM,cAAc;;;;;;;;;;;;EAMzB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,cAAc,CAAC,CASzB;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;CAsBxB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * wiki_edit_page tool - Edit an existing wiki page
3
+ */
4
+ import { z } from 'zod';
5
+ export const editPageSchema = z.object({
6
+ pagename: z
7
+ .string()
8
+ .describe('Page name in Group.Name or Group/Name format'),
9
+ content: z.string().describe('New page content in PmWiki markup format'),
10
+ summary: z.string().optional().describe('Edit summary describing the change'),
11
+ });
12
+ export async function editPage(client, input) {
13
+ // Normalize pagename (convert / to .)
14
+ const pagename = input.pagename.replace('/', '.');
15
+ const result = await client.editPage(pagename, input.content, input.summary);
16
+ return {
17
+ pagename: result.pagename,
18
+ action: result.action,
19
+ message: `Page ${result.pagename} ${result.action} successfully`,
20
+ };
21
+ }
22
+ export const editPageTool = {
23
+ name: 'wiki_edit_page',
24
+ description: 'Edit an existing wiki page. Replaces the entire page content. If the page does not exist, it will be created.',
25
+ inputSchema: {
26
+ type: 'object',
27
+ properties: {
28
+ pagename: {
29
+ type: 'string',
30
+ description: 'Page name in Group.Name or Group/Name format',
31
+ },
32
+ content: {
33
+ type: 'string',
34
+ description: 'New page content in PmWiki markup format',
35
+ },
36
+ summary: {
37
+ type: 'string',
38
+ description: 'Edit summary describing the change (optional)',
39
+ },
40
+ },
41
+ required: ['pagename', 'content'],
42
+ },
43
+ };
44
+ //# sourceMappingURL=editPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editPage.js","sourceRoot":"","sources":["../../src/tools/editPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;IACxE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC9E,CAAC,CAAC;AAUH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAkB,EAClB,KAAoB;IAEpB,sCAAsC;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7E,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,QAAQ,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,MAAM,eAAe;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,+GAA+G;IACjH,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0CAA0C;aACxD;YACD,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,+CAA+C;aAC7D;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;KAClC;CACF,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * wiki_find_pages tool - Search for pages by name or content
3
+ */
4
+ import { z } from 'zod';
5
+ import { WikiClient, SearchResult } from '../api/wikiClient.js';
6
+ export declare const findPagesSchema: z.ZodObject<{
7
+ query: z.ZodString;
8
+ group: z.ZodOptional<z.ZodString>;
9
+ nameOnly: z.ZodOptional<z.ZodBoolean>;
10
+ limit: z.ZodOptional<z.ZodNumber>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ query: string;
13
+ group?: string | undefined;
14
+ limit?: number | undefined;
15
+ nameOnly?: boolean | undefined;
16
+ }, {
17
+ query: string;
18
+ group?: string | undefined;
19
+ limit?: number | undefined;
20
+ nameOnly?: boolean | undefined;
21
+ }>;
22
+ export type FindPagesInput = z.infer<typeof findPagesSchema>;
23
+ export declare function findPages(client: WikiClient, input: FindPagesInput): Promise<SearchResult[]>;
24
+ export declare const findPagesTool: {
25
+ name: string;
26
+ description: string;
27
+ inputSchema: {
28
+ type: "object";
29
+ properties: {
30
+ query: {
31
+ type: string;
32
+ description: string;
33
+ };
34
+ group: {
35
+ type: string;
36
+ description: string;
37
+ };
38
+ nameOnly: {
39
+ type: string;
40
+ description: string;
41
+ };
42
+ limit: {
43
+ type: string;
44
+ description: string;
45
+ };
46
+ };
47
+ required: string[];
48
+ };
49
+ };
50
+ //# sourceMappingURL=findPages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findPages.d.ts","sourceRoot":"","sources":["../../src/tools/findPages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEhE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;EAW1B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE7D,wBAAsB,SAAS,CAC7B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC,CAMzB;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;CA0BzB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * wiki_find_pages tool - Search for pages by name or content
3
+ */
4
+ import { z } from 'zod';
5
+ export const findPagesSchema = z.object({
6
+ query: z.string().describe('Search query to find pages'),
7
+ group: z.string().optional().describe('Limit search to a specific group'),
8
+ nameOnly: z
9
+ .boolean()
10
+ .optional()
11
+ .describe('If true, only search page names, not content'),
12
+ limit: z
13
+ .number()
14
+ .optional()
15
+ .describe('Maximum number of results to return (default: 50)'),
16
+ });
17
+ export async function findPages(client, input) {
18
+ return client.searchPages(input.query, {
19
+ group: input.group,
20
+ nameOnly: input.nameOnly,
21
+ limit: input.limit,
22
+ });
23
+ }
24
+ export const findPagesTool = {
25
+ name: 'wiki_find_pages',
26
+ description: 'Search for wiki pages by name or content. Returns matching pages with snippets showing where the query was found.',
27
+ inputSchema: {
28
+ type: 'object',
29
+ properties: {
30
+ query: {
31
+ type: 'string',
32
+ description: 'Search query to find pages',
33
+ },
34
+ group: {
35
+ type: 'string',
36
+ description: 'Limit search to a specific group (optional)',
37
+ },
38
+ nameOnly: {
39
+ type: 'boolean',
40
+ description: 'If true, only search page names, not content (optional)',
41
+ },
42
+ limit: {
43
+ type: 'number',
44
+ description: 'Maximum number of results to return (default: 50)',
45
+ },
46
+ },
47
+ required: ['query'],
48
+ },
49
+ };
50
+ //# sourceMappingURL=findPages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"findPages.js","sourceRoot":"","sources":["../../src/tools/findPages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;IACzE,QAAQ,EAAE,CAAC;SACR,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,mDAAmD,CAAC;CACjE,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAkB,EAClB,KAAqB;IAErB,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE;QACrC,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,mHAAmH;IACrH,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,4BAA4B;aAC1C;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,6CAA6C;aAC3D;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,yDAAyD;aACvE;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,mDAAmD;aACjE;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;CACF,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * wiki_list_pages tool - List pages in a group
3
+ */
4
+ import { z } from 'zod';
5
+ import { WikiClient, PageListItem } from '../api/wikiClient.js';
6
+ export declare const listPagesSchema: z.ZodObject<{
7
+ group: z.ZodOptional<z.ZodString>;
8
+ limit: z.ZodOptional<z.ZodNumber>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ group?: string | undefined;
11
+ limit?: number | undefined;
12
+ }, {
13
+ group?: string | undefined;
14
+ limit?: number | undefined;
15
+ }>;
16
+ export type ListPagesInput = z.infer<typeof listPagesSchema>;
17
+ export declare function listPages(client: WikiClient, input: ListPagesInput): Promise<PageListItem[]>;
18
+ export declare const listPagesTool: {
19
+ name: string;
20
+ description: string;
21
+ inputSchema: {
22
+ type: "object";
23
+ properties: {
24
+ group: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ limit: {
29
+ type: string;
30
+ description: string;
31
+ };
32
+ };
33
+ required: never[];
34
+ };
35
+ };
36
+ //# sourceMappingURL=listPages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listPages.d.ts","sourceRoot":"","sources":["../../src/tools/listPages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEhE,eAAO,MAAM,eAAe;;;;;;;;;EAM1B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE7D,wBAAsB,SAAS,CAC7B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzB;AAED,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;CAkBzB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * wiki_list_pages tool - List pages in a group
3
+ */
4
+ import { z } from 'zod';
5
+ export const listPagesSchema = z.object({
6
+ group: z.string().optional().describe('Group to list pages from'),
7
+ limit: z
8
+ .number()
9
+ .optional()
10
+ .describe('Maximum number of pages to return (default: 100)'),
11
+ });
12
+ export async function listPages(client, input) {
13
+ return client.listPages(input.group, input.limit);
14
+ }
15
+ export const listPagesTool = {
16
+ name: 'wiki_list_pages',
17
+ description: 'List wiki pages, optionally filtered by group. Returns page names, titles, and metadata sorted by most recently modified.',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: {
21
+ group: {
22
+ type: 'string',
23
+ description: 'Group to list pages from (optional, lists all if omitted)',
24
+ },
25
+ limit: {
26
+ type: 'number',
27
+ description: 'Maximum number of pages to return (default: 100)',
28
+ },
29
+ },
30
+ required: [],
31
+ },
32
+ };
33
+ //# sourceMappingURL=listPages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listPages.js","sourceRoot":"","sources":["../../src/tools/listPages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IACjE,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,kDAAkD,CAAC;CAChE,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAkB,EAClB,KAAqB;IAErB,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,2HAA2H;IAC7H,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2DAA2D;aACzE;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kDAAkD;aAChE;SACF;QACD,QAAQ,EAAE,EAAE;KACb;CACF,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * wiki_read_page tool - Read a wiki page's content
3
+ */
4
+ import { z } from 'zod';
5
+ import { WikiClient, WikiPage } from '../api/wikiClient.js';
6
+ export declare const readPageSchema: z.ZodObject<{
7
+ pagename: z.ZodString;
8
+ format: z.ZodOptional<z.ZodEnum<["raw", "markdown", "html"]>>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ pagename: string;
11
+ format?: "raw" | "markdown" | "html" | undefined;
12
+ }, {
13
+ pagename: string;
14
+ format?: "raw" | "markdown" | "html" | undefined;
15
+ }>;
16
+ export type ReadPageInput = z.infer<typeof readPageSchema>;
17
+ export declare function readPage(client: WikiClient, input: ReadPageInput): Promise<WikiPage>;
18
+ export declare const readPageTool: {
19
+ name: string;
20
+ description: string;
21
+ inputSchema: {
22
+ type: "object";
23
+ properties: {
24
+ pagename: {
25
+ type: string;
26
+ description: string;
27
+ };
28
+ format: {
29
+ type: string;
30
+ enum: string[];
31
+ description: string;
32
+ };
33
+ };
34
+ required: string[];
35
+ };
36
+ };
37
+ //# sourceMappingURL=readPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readPage.d.ts","sourceRoot":"","sources":["../../src/tools/readPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5D,eAAO,MAAM,cAAc;;;;;;;;;EAQzB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,QAAQ,CAAC,CAInB;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAoBxB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * wiki_read_page tool - Read a wiki page's content
3
+ */
4
+ import { z } from 'zod';
5
+ export const readPageSchema = z.object({
6
+ pagename: z
7
+ .string()
8
+ .describe('Page name in Group.Name or Group/Name format'),
9
+ format: z
10
+ .enum(['raw', 'markdown', 'html'])
11
+ .optional()
12
+ .describe('Output format: raw (PmWiki markup), markdown, or html'),
13
+ });
14
+ export async function readPage(client, input) {
15
+ // Normalize pagename (convert / to .)
16
+ const pagename = input.pagename.replace('/', '.');
17
+ return client.readPage(pagename, input.format || 'raw');
18
+ }
19
+ export const readPageTool = {
20
+ name: 'wiki_read_page',
21
+ description: "Read a wiki page's content. Returns the page text along with metadata like title, author, and last modified time.",
22
+ inputSchema: {
23
+ type: 'object',
24
+ properties: {
25
+ pagename: {
26
+ type: 'string',
27
+ description: 'Page name in Group.Name or Group/Name format',
28
+ },
29
+ format: {
30
+ type: 'string',
31
+ enum: ['raw', 'markdown', 'html'],
32
+ description: 'Output format: raw (PmWiki markup), markdown, or html (default: raw)',
33
+ },
34
+ },
35
+ required: ['pagename'],
36
+ },
37
+ };
38
+ //# sourceMappingURL=readPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readPage.js","sourceRoot":"","sources":["../../src/tools/readPage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;SACjC,QAAQ,EAAE;SACV,QAAQ,CAAC,uDAAuD,CAAC;CACrE,CAAC,CAAC;AAIH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAkB,EAClB,KAAoB;IAEpB,sCAAsC;IACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EACT,mHAAmH;IACrH,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC;gBACjC,WAAW,EACT,sEAAsE;aACzE;SACF;QACD,QAAQ,EAAE,CAAC,UAAU,CAAC;KACvB;CACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "pmwiki-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for PmWiki - enables AI agents to read, create, and edit wiki pages",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "pmwiki-mcp": "dist/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc",
11
+ "start": "node dist/index.js",
12
+ "dev": "ts-node src/index.ts",
13
+ "prepublishOnly": "npm run build"
14
+ },
15
+ "keywords": [
16
+ "mcp",
17
+ "pmwiki",
18
+ "wiki",
19
+ "claude",
20
+ "ai",
21
+ "model-context-protocol"
22
+ ],
23
+ "author": "Mike Lee",
24
+ "license": "MIT",
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "type": "module",
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.0.0",
31
+ "zod": "^3.23.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^20.0.0",
35
+ "typescript": "^5.0.0"
36
+ },
37
+ "files": [
38
+ "dist/**/*",
39
+ "README.md"
40
+ ],
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/milee98/pmwiki"
44
+ }
45
+ }