@webhouse/cms-mcp-client 0.1.1

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.
@@ -0,0 +1,221 @@
1
+ import * as _webhouse_cms from '@webhouse/cms';
2
+ import { ContentService, CmsConfig } from '@webhouse/cms';
3
+ import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+
6
+ declare const PUBLIC_TOOLS: readonly [{
7
+ readonly name: "get_site_summary";
8
+ readonly description: string;
9
+ readonly inputSchema: {
10
+ readonly type: "object";
11
+ readonly properties: {};
12
+ readonly required: string[];
13
+ };
14
+ }, {
15
+ readonly name: "list_collection";
16
+ readonly description: string;
17
+ readonly inputSchema: {
18
+ readonly type: "object";
19
+ readonly properties: {
20
+ readonly collection: {
21
+ readonly type: "string";
22
+ readonly description: "Collection name, e.g. 'posts', 'products'";
23
+ };
24
+ readonly limit: {
25
+ readonly type: "number";
26
+ readonly description: "Max results. Default 20, max 100.";
27
+ };
28
+ readonly offset: {
29
+ readonly type: "number";
30
+ readonly description: "Pagination offset. Default 0.";
31
+ };
32
+ readonly sort: {
33
+ readonly type: "string";
34
+ readonly enum: readonly ["date_desc", "date_asc", "title_asc"];
35
+ readonly description: "Sort order. Default: date_desc.";
36
+ };
37
+ };
38
+ readonly required: string[];
39
+ };
40
+ }, {
41
+ readonly name: "search_content";
42
+ readonly description: string;
43
+ readonly inputSchema: {
44
+ readonly type: "object";
45
+ readonly properties: {
46
+ readonly query: {
47
+ readonly type: "string";
48
+ readonly description: "Search query.";
49
+ };
50
+ readonly collection: {
51
+ readonly type: "string";
52
+ readonly description: "Optional: limit search to this collection.";
53
+ };
54
+ readonly limit: {
55
+ readonly type: "number";
56
+ readonly description: "Max results. Default 10, max 50.";
57
+ };
58
+ };
59
+ readonly required: string[];
60
+ };
61
+ }, {
62
+ readonly name: "get_page";
63
+ readonly description: string;
64
+ readonly inputSchema: {
65
+ readonly type: "object";
66
+ readonly properties: {
67
+ readonly slug: {
68
+ readonly type: "string";
69
+ readonly description: "Document slug, e.g. 'getting-started'.";
70
+ };
71
+ readonly collection: {
72
+ readonly type: "string";
73
+ readonly description: "Optional: collection to scope the lookup.";
74
+ };
75
+ };
76
+ readonly required: string[];
77
+ };
78
+ }, {
79
+ readonly name: "get_schema";
80
+ readonly description: "Returns the field schema for a collection, describing all available fields and their types.";
81
+ readonly inputSchema: {
82
+ readonly type: "object";
83
+ readonly properties: {
84
+ readonly collection: {
85
+ readonly type: "string";
86
+ readonly description: "Collection name.";
87
+ };
88
+ };
89
+ readonly required: string[];
90
+ };
91
+ }, {
92
+ readonly name: "export_all";
93
+ readonly description: string;
94
+ readonly inputSchema: {
95
+ readonly type: "object";
96
+ readonly properties: {
97
+ readonly include_body: {
98
+ readonly type: "boolean";
99
+ readonly description: "Include full body (true) or metadata only (false). Default: true.";
100
+ };
101
+ };
102
+ readonly required: string[];
103
+ };
104
+ }];
105
+ type ToolName = (typeof PUBLIC_TOOLS)[number]["name"];
106
+
107
+ declare class ContentReader {
108
+ private content;
109
+ private config;
110
+ constructor(content: ContentService, config: CmsConfig);
111
+ getSiteSummary(): Promise<{
112
+ collections: {
113
+ name: string;
114
+ label: string;
115
+ count: number;
116
+ }[];
117
+ totalDocuments: number;
118
+ defaultLocale: string;
119
+ locales: string[];
120
+ }>;
121
+ listCollection(args: {
122
+ collection: string;
123
+ limit?: number;
124
+ offset?: number;
125
+ sort?: "date_desc" | "date_asc" | "title_asc";
126
+ }): Promise<{
127
+ collection: string;
128
+ total: number;
129
+ limit: number;
130
+ offset: number;
131
+ documents: {
132
+ slug: string;
133
+ collection: string;
134
+ title: string;
135
+ excerpt: string;
136
+ tags: string[];
137
+ date: string;
138
+ updatedAt: string;
139
+ }[];
140
+ }>;
141
+ search(args: {
142
+ query: string;
143
+ collection?: string;
144
+ limit?: number;
145
+ }): Promise<{
146
+ query: string;
147
+ total: number;
148
+ results: ({
149
+ slug: string;
150
+ collection: string;
151
+ title: string;
152
+ excerpt: string;
153
+ tags: string[];
154
+ date: string;
155
+ updatedAt: string;
156
+ } & {
157
+ score: number;
158
+ })[];
159
+ }>;
160
+ getPage(args: {
161
+ slug: string;
162
+ collection?: string;
163
+ }): Promise<string>;
164
+ getSchema(collection: string): Promise<{
165
+ error: string;
166
+ name?: never;
167
+ label?: never;
168
+ fields?: never;
169
+ } | {
170
+ name: string;
171
+ label: string;
172
+ fields: {
173
+ name: string;
174
+ type: _webhouse_cms.FieldType;
175
+ label: string | undefined;
176
+ required: boolean;
177
+ }[];
178
+ error?: never;
179
+ }>;
180
+ exportAll(args: {
181
+ include_body?: boolean;
182
+ }): Promise<Record<string, unknown[]>>;
183
+ }
184
+
185
+ /**
186
+ * MCP Transport that uses Web Streams API (compatible with Next.js App Router).
187
+ * - GET handler creates the transport, returns transport.stream as SSE Response
188
+ * - POST handler calls transport.handleClientMessage(body) to deliver messages
189
+ */
190
+ declare class NextSSETransport {
191
+ private controller;
192
+ private encoder;
193
+ readonly stream: ReadableStream<Uint8Array>;
194
+ readonly sessionId: string;
195
+ onclose?: () => void;
196
+ onerror?: (error: Error) => void;
197
+ onmessage?: (message: JSONRPCMessage) => void;
198
+ constructor(sessionId: string, endpointUrl?: string);
199
+ /** Called by MCP SDK on startup — nothing to do since stream is already open. */
200
+ start(): Promise<void>;
201
+ /** Called by MCP SDK to send a message to the client via SSE. */
202
+ send(message: JSONRPCMessage): Promise<void>;
203
+ /** Called when the server shuts down or the client disconnects. */
204
+ close(): Promise<void>;
205
+ /** Called by the POST route handler to deliver a client message into the MCP server. */
206
+ handleClientMessage(body: unknown): void;
207
+ }
208
+ declare function getTransportSession(id: string): NextSSETransport | undefined;
209
+ declare function registerTransportSession(t: NextSSETransport): void;
210
+
211
+ type RateLimitResult = {
212
+ allowed: true;
213
+ } | {
214
+ allowed: false;
215
+ reason: string;
216
+ };
217
+ declare function checkRateLimit(ip: string, tool?: string): RateLimitResult;
218
+
219
+ declare function createPublicMcpServer(content: ContentService, config: CmsConfig): Server;
220
+
221
+ export { ContentReader, NextSSETransport, PUBLIC_TOOLS, type ToolName, checkRateLimit, createPublicMcpServer, getTransportSession, registerTransportSession };
@@ -0,0 +1,221 @@
1
+ import * as _webhouse_cms from '@webhouse/cms';
2
+ import { ContentService, CmsConfig } from '@webhouse/cms';
3
+ import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
4
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
5
+
6
+ declare const PUBLIC_TOOLS: readonly [{
7
+ readonly name: "get_site_summary";
8
+ readonly description: string;
9
+ readonly inputSchema: {
10
+ readonly type: "object";
11
+ readonly properties: {};
12
+ readonly required: string[];
13
+ };
14
+ }, {
15
+ readonly name: "list_collection";
16
+ readonly description: string;
17
+ readonly inputSchema: {
18
+ readonly type: "object";
19
+ readonly properties: {
20
+ readonly collection: {
21
+ readonly type: "string";
22
+ readonly description: "Collection name, e.g. 'posts', 'products'";
23
+ };
24
+ readonly limit: {
25
+ readonly type: "number";
26
+ readonly description: "Max results. Default 20, max 100.";
27
+ };
28
+ readonly offset: {
29
+ readonly type: "number";
30
+ readonly description: "Pagination offset. Default 0.";
31
+ };
32
+ readonly sort: {
33
+ readonly type: "string";
34
+ readonly enum: readonly ["date_desc", "date_asc", "title_asc"];
35
+ readonly description: "Sort order. Default: date_desc.";
36
+ };
37
+ };
38
+ readonly required: string[];
39
+ };
40
+ }, {
41
+ readonly name: "search_content";
42
+ readonly description: string;
43
+ readonly inputSchema: {
44
+ readonly type: "object";
45
+ readonly properties: {
46
+ readonly query: {
47
+ readonly type: "string";
48
+ readonly description: "Search query.";
49
+ };
50
+ readonly collection: {
51
+ readonly type: "string";
52
+ readonly description: "Optional: limit search to this collection.";
53
+ };
54
+ readonly limit: {
55
+ readonly type: "number";
56
+ readonly description: "Max results. Default 10, max 50.";
57
+ };
58
+ };
59
+ readonly required: string[];
60
+ };
61
+ }, {
62
+ readonly name: "get_page";
63
+ readonly description: string;
64
+ readonly inputSchema: {
65
+ readonly type: "object";
66
+ readonly properties: {
67
+ readonly slug: {
68
+ readonly type: "string";
69
+ readonly description: "Document slug, e.g. 'getting-started'.";
70
+ };
71
+ readonly collection: {
72
+ readonly type: "string";
73
+ readonly description: "Optional: collection to scope the lookup.";
74
+ };
75
+ };
76
+ readonly required: string[];
77
+ };
78
+ }, {
79
+ readonly name: "get_schema";
80
+ readonly description: "Returns the field schema for a collection, describing all available fields and their types.";
81
+ readonly inputSchema: {
82
+ readonly type: "object";
83
+ readonly properties: {
84
+ readonly collection: {
85
+ readonly type: "string";
86
+ readonly description: "Collection name.";
87
+ };
88
+ };
89
+ readonly required: string[];
90
+ };
91
+ }, {
92
+ readonly name: "export_all";
93
+ readonly description: string;
94
+ readonly inputSchema: {
95
+ readonly type: "object";
96
+ readonly properties: {
97
+ readonly include_body: {
98
+ readonly type: "boolean";
99
+ readonly description: "Include full body (true) or metadata only (false). Default: true.";
100
+ };
101
+ };
102
+ readonly required: string[];
103
+ };
104
+ }];
105
+ type ToolName = (typeof PUBLIC_TOOLS)[number]["name"];
106
+
107
+ declare class ContentReader {
108
+ private content;
109
+ private config;
110
+ constructor(content: ContentService, config: CmsConfig);
111
+ getSiteSummary(): Promise<{
112
+ collections: {
113
+ name: string;
114
+ label: string;
115
+ count: number;
116
+ }[];
117
+ totalDocuments: number;
118
+ defaultLocale: string;
119
+ locales: string[];
120
+ }>;
121
+ listCollection(args: {
122
+ collection: string;
123
+ limit?: number;
124
+ offset?: number;
125
+ sort?: "date_desc" | "date_asc" | "title_asc";
126
+ }): Promise<{
127
+ collection: string;
128
+ total: number;
129
+ limit: number;
130
+ offset: number;
131
+ documents: {
132
+ slug: string;
133
+ collection: string;
134
+ title: string;
135
+ excerpt: string;
136
+ tags: string[];
137
+ date: string;
138
+ updatedAt: string;
139
+ }[];
140
+ }>;
141
+ search(args: {
142
+ query: string;
143
+ collection?: string;
144
+ limit?: number;
145
+ }): Promise<{
146
+ query: string;
147
+ total: number;
148
+ results: ({
149
+ slug: string;
150
+ collection: string;
151
+ title: string;
152
+ excerpt: string;
153
+ tags: string[];
154
+ date: string;
155
+ updatedAt: string;
156
+ } & {
157
+ score: number;
158
+ })[];
159
+ }>;
160
+ getPage(args: {
161
+ slug: string;
162
+ collection?: string;
163
+ }): Promise<string>;
164
+ getSchema(collection: string): Promise<{
165
+ error: string;
166
+ name?: never;
167
+ label?: never;
168
+ fields?: never;
169
+ } | {
170
+ name: string;
171
+ label: string;
172
+ fields: {
173
+ name: string;
174
+ type: _webhouse_cms.FieldType;
175
+ label: string | undefined;
176
+ required: boolean;
177
+ }[];
178
+ error?: never;
179
+ }>;
180
+ exportAll(args: {
181
+ include_body?: boolean;
182
+ }): Promise<Record<string, unknown[]>>;
183
+ }
184
+
185
+ /**
186
+ * MCP Transport that uses Web Streams API (compatible with Next.js App Router).
187
+ * - GET handler creates the transport, returns transport.stream as SSE Response
188
+ * - POST handler calls transport.handleClientMessage(body) to deliver messages
189
+ */
190
+ declare class NextSSETransport {
191
+ private controller;
192
+ private encoder;
193
+ readonly stream: ReadableStream<Uint8Array>;
194
+ readonly sessionId: string;
195
+ onclose?: () => void;
196
+ onerror?: (error: Error) => void;
197
+ onmessage?: (message: JSONRPCMessage) => void;
198
+ constructor(sessionId: string, endpointUrl?: string);
199
+ /** Called by MCP SDK on startup — nothing to do since stream is already open. */
200
+ start(): Promise<void>;
201
+ /** Called by MCP SDK to send a message to the client via SSE. */
202
+ send(message: JSONRPCMessage): Promise<void>;
203
+ /** Called when the server shuts down or the client disconnects. */
204
+ close(): Promise<void>;
205
+ /** Called by the POST route handler to deliver a client message into the MCP server. */
206
+ handleClientMessage(body: unknown): void;
207
+ }
208
+ declare function getTransportSession(id: string): NextSSETransport | undefined;
209
+ declare function registerTransportSession(t: NextSSETransport): void;
210
+
211
+ type RateLimitResult = {
212
+ allowed: true;
213
+ } | {
214
+ allowed: false;
215
+ reason: string;
216
+ };
217
+ declare function checkRateLimit(ip: string, tool?: string): RateLimitResult;
218
+
219
+ declare function createPublicMcpServer(content: ContentService, config: CmsConfig): Server;
220
+
221
+ export { ContentReader, NextSSETransport, PUBLIC_TOOLS, type ToolName, checkRateLimit, createPublicMcpServer, getTransportSession, registerTransportSession };