@page2ai/mcp 0.1.2 → 0.2.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,74 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@page2ai/mcp` are documented here.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and this
5
+ project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html); while the
6
+ major version is `0`, a minor bump may carry breaking changes.
7
+
8
+ ## 0.2.1 - 2026-08-02
9
+
10
+ ### Fixed
11
+ - Pages built with a card grid lost almost all of their content. `@page2ai/core` chose the
12
+ conversion root with the FIRST `<article>` in document order, and HTML5 allows that tag on any
13
+ self-contained component, so a decorative card outranked the page. `docs.astro.build` returned
14
+ 208 characters of body where it now returns 3,494; `blog.cloudflare.com` returned 927 where it
15
+ now returns 15,068. An `<article>` is now used only when it carries at least half its
16
+ container's content text. Requires `@page2ai/core` 0.1.2.
17
+ - The server reported the wrong version over the wire. `SERVER_VERSION` was a hardcoded constant
18
+ beside `package.json` and `manifest.json`, and it drifted on the first release after it was
19
+ written. It is now read from `package.json`, with a fallback so a missing file can never stop
20
+ the server from starting.
21
+
22
+ ## [0.2.0] - 2026-07-29
23
+
24
+ Adopts MCP protocol revision **2026-07-28**, published 2026-07-28, one day after the
25
+ v2 TypeScript SDK packages landed on npm.
26
+
27
+ ### Breaking
28
+
29
+ - **Node.js 20 or newer is required** (was 18). `@modelcontextprotocol/core` and
30
+ `@modelcontextprotocol/server` both declare `engines.node: ">=20"`.
31
+ - `zod` moved from `^3.24.0` to `^4.2.0`. The v2 SDK's floor is `zod >= 4.2.0`; an
32
+ older range installs cleanly and then fails at type-check or at the first
33
+ `tools/list`, depending on which zod entry point is imported.
34
+
35
+ ### Added
36
+
37
+ - Serves protocol revision `2026-07-28` alongside `2025-11-25`. A client that opens
38
+ with `server/discover` and a `io.modelcontextprotocol/protocolVersion` claim in
39
+ `_meta` gets the 2026 era; a client that opens with `initialize` gets the 2025 era,
40
+ byte for byte as before. `serveStdio` owns the decision and pins one server
41
+ instance per connection.
42
+ - `SIGINT` / `SIGTERM` handlers that close the connection through the
43
+ `StdioServerHandle` returned by `serveStdio`.
44
+
45
+ ### Changed
46
+
47
+ - Migrated from the monolithic `@modelcontextprotocol/sdk@^1.29.0` to
48
+ `@modelcontextprotocol/server@^2.0.0`. This removes 90 transitive packages:
49
+ 117 production dependencies down to 26. The v1 package pulled the HTTP and OAuth
50
+ server stack into every install, including stdio-only servers like this one.
51
+ - Server registration moved into a factory (`buildServer`) so the same tool
52
+ registrations serve both eras.
53
+
54
+ ### Fixed
55
+
56
+ - The version reported over the wire and on stderr was hardcoded to `0.1.0` while
57
+ the package published as `0.1.2`. It now tracks the package version. This was
58
+ visible to any client reading `serverInfo`.
59
+ - `server.json` declared `0.1.1` while npm carried `0.1.2`.
60
+
61
+ ### Notes
62
+
63
+ - Wiring a `Server` directly to a `StdioServerTransport` serves only the 2025 era,
64
+ no matter which SDK version is installed. Upgrading the dependency is not enough;
65
+ the entry point has to change.
66
+
67
+ ## [0.1.2] - 2026-07-27
68
+
69
+ - Packaging and metadata fixes.
70
+
71
+ ## [0.1.0] - 2026-07-24
72
+
73
+ - First release: stdio MCP server exposing a single `page_to_markdown` tool backed
74
+ by `@page2ai/core`. SSRF guard, 10 MB size cap, 15 s default timeout.
package/README.md CHANGED
@@ -104,9 +104,35 @@ Future versions will support options via tool arguments:
104
104
 
105
105
  `@page2ai/mcp` collects no data, sends no telemetry, and makes no external network calls beyond the URLs you explicitly provide. See [PRIVACY.md](./PRIVACY.md) for details.
106
106
 
107
+ ## Protocol revisions
108
+
109
+ Since 0.2.0 this server answers **both** MCP protocol revisions on the same stdio
110
+ connection:
111
+
112
+ | Revision | How a client opens the connection | Served |
113
+ |---|---|---|
114
+ | `2026-07-28` | `server/discover`, carrying `io.modelcontextprotocol/protocolVersion` in `_meta` | yes |
115
+ | `2025-11-25` and earlier | the `initialize` handshake | yes |
116
+
117
+ `serveStdio` picks the era from the opening message and pins one server instance for
118
+ the life of the connection, so clients on older SDKs are unaffected. Note that a
119
+ message carrying no version claim is treated by the specification as a 2025-era
120
+ opening; `server/discover` without that `_meta` field is therefore answered with
121
+ `-32601` rather than being upgraded.
122
+
123
+ Verify against a build with the raw JSON-RPC frames, without a client library:
124
+
125
+ ```bash
126
+ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}' | node dist/index.js
127
+ ```
128
+
107
129
  ## Known advisories
108
130
 
109
- `npm audit` will surface a moderate finding in `@hono/node-server` (a transitive dependency of `@modelcontextprotocol/sdk`). That vulnerability lives in the SDK's HTTP/OAuth server path; `@page2ai/mcp` uses only the stdio transport and never loads that code path, so it is not exploitable through this package. The audit line will clear once the SDK bumps its Hono constraint to `>=2.0.5`.
131
+ None. Moving to the v2 SDK removed 90 transitive packages (117 production
132
+ dependencies down to 26) and with them the `@hono/node-server` advisory that
133
+ 0.1.x carried through the monolithic `@modelcontextprotocol/sdk`; that package
134
+ pulled the HTTP and OAuth server stack even for a stdio-only server. `npm audit`
135
+ is clean as of 0.2.0.
110
136
 
111
137
  ## Development
112
138
 
@@ -125,14 +151,24 @@ npx @modelcontextprotocol/inspector node dist/index.js
125
151
 
126
152
  ## Support
127
153
 
128
- - GitHub issues: https://github.com/igorsaevets/page2ai-mcp/issues
129
- - Docs: https://igorsaevets.github.io/page2ai-docs/mcp/
154
+ Pick the channel by what you have, not by what is quickest to type:
155
+
156
+ | You have | Use |
157
+ |---|---|
158
+ | A bug, a page that extracts badly, a feature idea | [GitHub issues](https://github.com/igorsaevets/page2ai-mcp/issues) — public and searchable, so the fix helps the next person too |
159
+ | A security vulnerability | [Private vulnerability reporting](https://github.com/igorsaevets/page2ai-mcp/security/advisories/new), see [SECURITY.md](SECURITY.md). Do not open a public issue |
160
+ | A usage question | [Docs](https://igorsaevets.github.io/page2ai-docs/mcp/) first, then an issue |
130
161
 
131
162
  ## About the author
132
163
 
133
- Written and maintained by **Igor Saevets** — AI expert and founder of Page2AI. Full bio and social links: [igorsaevets.github.io/page2ai-docs/about/](https://igorsaevets.github.io/page2ai-docs/about/).
164
+ Written and maintained by **Igor Saevets** — AI expert and founder of Page2AI. Full bio:
165
+ [igorsaevets.github.io/page2ai-docs/about/](https://igorsaevets.github.io/page2ai-docs/about/).
166
+
167
+ These are identity and collaboration links, not the support queue. A bug reported in a DM is a bug
168
+ nobody else can find later, so anything you want fixed belongs in the table above.
134
169
 
135
170
  - LinkedIn: [linkedin.com/in/igorsaevets](https://www.linkedin.com/in/igorsaevets/)
171
+ - Facebook: [facebook.com/igorsaevets](https://www.facebook.com/igorsaevets/)
136
172
  - GitHub: [github.com/igorsaevets](https://github.com/igorsaevets)
137
173
  - ORCID: [0009-0006-8636-1377](https://orcid.org/0009-0006-8636-1377)
138
174
  - Email: igorsaevets@gmail.com
package/dist/index.js CHANGED
@@ -3,46 +3,85 @@
3
3
  // Runs as a stdio subprocess spawned by Claude Desktop, Cursor, Windsurf, Zed.
4
4
  // Registers a single tool `page_to_markdown` that converts URLs to Markdown
5
5
  // via @page2ai/core (SSRF-guarded, 10MB size cap, 15s timeout by default).
6
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
- import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
6
+ //
7
+ // Protocol: serves BOTH the 2025-11-25 and 2026-07-28 revisions. `serveStdio`
8
+ // owns the era decision per connection: the opening exchange selects it, one
9
+ // instance from the factory is pinned for the connection's lifetime. Clients on
10
+ // older SDKs still send `initialize` and are served exactly as before; clients
11
+ // that probe with `server/discover` get the 2026-07-28 era. Wiring a `Server`
12
+ // straight to a `StdioServerTransport` — as this file did through v0.1.2 —
13
+ // serves only the 2025 era no matter which SDK version is installed.
14
+ import { readFileSync } from 'node:fs';
15
+ import { fileURLToPath } from 'node:url';
16
+ import { serveStdio } from '@modelcontextprotocol/server/stdio';
17
+ import { Server } from '@modelcontextprotocol/server';
9
18
  import { handlePageToMarkdown, pageToMarkdownDefinition } from './tools/page-to-markdown.js';
10
19
  const SERVER_NAME = 'page2ai-mcp';
11
- const SERVER_VERSION = '0.1.0';
12
- const server = new Server({
13
- name: SERVER_NAME,
14
- version: SERVER_VERSION,
15
- }, {
16
- capabilities: {
17
- tools: {},
18
- },
19
- });
20
- server.setRequestHandler(ListToolsRequestSchema, async () => ({
21
- tools: [pageToMarkdownDefinition],
22
- }));
23
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
24
- const toolName = request.params.name;
25
- const toolArgs = request.params.arguments ?? {};
26
- if (toolName === 'page_to_markdown') {
27
- return handlePageToMarkdown(toolArgs);
20
+ // Read the version from package.json instead of restating it here.
21
+ //
22
+ // This used to be `const SERVER_VERSION = '0.2.0'`, a third source of truth beside
23
+ // package.json and manifest.json, kept in sync by remembering to. It drifted on the very next
24
+ // release: 0.2.1 shipped while the running server still introduced itself over the wire as
25
+ // 0.2.0, so a client asking what it was talking to got the wrong answer and nothing failed.
26
+ //
27
+ // Wrapped because a version string is not worth crashing a server over: if the layout ever
28
+ // changes and the file is not where dist/index.js expects it, an unknown version is a far
29
+ // better outcome than a server that will not start.
30
+ const SERVER_VERSION = (() => {
31
+ try {
32
+ const pkgPath = fileURLToPath(new URL('../package.json', import.meta.url));
33
+ return JSON.parse(readFileSync(pkgPath, 'utf8')).version || '0.0.0-unknown';
28
34
  }
29
- return {
30
- isError: true,
31
- content: [{ type: 'text', text: `Unknown tool: ${toolName}` }],
32
- };
33
- });
35
+ catch {
36
+ return '0.0.0-unknown';
37
+ }
38
+ })();
34
39
  // Log to stderr — stdio transport uses stdout for JSON-RPC frames, so anything
35
40
  // written to stderr is safe (Claude Desktop logs it to the debug console).
36
41
  const log = (msg) => {
37
42
  process.stderr.write(`[${SERVER_NAME}] ${msg}\n`);
38
43
  };
39
- const main = async () => {
40
- const transport = new StdioServerTransport();
41
- await server.connect(transport);
42
- log(`server ${SERVER_VERSION} ready on stdio (tools: page_to_markdown)`);
44
+ // Called once per connection by serveStdio, after the era is known. Registration
45
+ // is identical for both eras — the SDK adapts the wire format underneath.
46
+ const buildServer = () => {
47
+ const server = new Server({
48
+ name: SERVER_NAME,
49
+ version: SERVER_VERSION,
50
+ }, {
51
+ capabilities: {
52
+ tools: {},
53
+ },
54
+ });
55
+ server.setRequestHandler('tools/list', async () => ({
56
+ tools: [pageToMarkdownDefinition],
57
+ }));
58
+ server.setRequestHandler('tools/call', async (request) => {
59
+ const toolName = request.params.name;
60
+ const toolArgs = request.params.arguments ?? {};
61
+ if (toolName === 'page_to_markdown') {
62
+ return handlePageToMarkdown(toolArgs);
63
+ }
64
+ return {
65
+ isError: true,
66
+ content: [{ type: 'text', text: `Unknown tool: ${toolName}` }],
67
+ };
68
+ });
69
+ return server;
43
70
  };
44
- main().catch((err) => {
45
- log(`fatal: ${err instanceof Error ? err.stack || err.message : String(err)}`);
46
- process.exit(1);
71
+ const handle = serveStdio(buildServer, {
72
+ // 'serve' is the default and is stated here on purpose: rejecting the 2025
73
+ // era would break every client still on an older SDK, which is most of them.
74
+ legacy: 'serve',
75
+ onerror: (err) => log(`transport error: ${err.message}`),
47
76
  });
77
+ log(`server ${SERVER_VERSION} ready on stdio (tools: page_to_markdown)`);
78
+ const shutdown = (signal) => {
79
+ log(`${signal} received, closing`);
80
+ handle.close().then(() => process.exit(0), (err) => {
81
+ log(`close failed: ${err instanceof Error ? err.message : String(err)}`);
82
+ process.exit(1);
83
+ });
84
+ };
85
+ process.on('SIGINT', () => shutdown('SIGINT'));
86
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
48
87
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,yCAAyC;AACzC,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAE3E,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,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE7F,MAAM,WAAW,GAAG,aAAa,CAAC;AAClC,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;IACE,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,cAAc;CACxB,EACD;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;KACV;CACF,CACF,CAAC;AAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,EAAE,CAAC,wBAAwB,CAAC;CAClC,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;IAChD,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QACpC,OAAO,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IACD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,QAAQ,EAAE,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,2EAA2E;AAC3E,MAAM,GAAG,GAAG,CAAC,GAAW,EAAQ,EAAE;IAChC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,WAAW,KAAK,GAAG,IAAI,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACrC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,GAAG,CAAC,UAAU,cAAc,2CAA2C,CAAC,CAAC;AAC3E,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,GAAG,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,21 +1,11 @@
1
- import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
1
+ import type { CallToolResult } from '@modelcontextprotocol/server';
2
2
  import { z } from 'zod';
3
3
  export declare const pageToMarkdownInputSchema: z.ZodObject<{
4
4
  url: z.ZodString;
5
5
  include_images: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
6
6
  include_frontmatter: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
7
7
  timeout_ms: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
8
- }, "strip", z.ZodTypeAny, {
9
- url: string;
10
- include_images: boolean;
11
- include_frontmatter: boolean;
12
- timeout_ms: number;
13
- }, {
14
- url: string;
15
- include_images?: boolean | undefined;
16
- include_frontmatter?: boolean | undefined;
17
- timeout_ms?: number | undefined;
18
- }>;
8
+ }, z.core.$strip>;
19
9
  export type PageToMarkdownInput = z.infer<typeof pageToMarkdownInputSchema>;
20
10
  export type PageToMarkdownResult = CallToolResult;
21
11
  export declare const pageToMarkdownDefinition: {
@@ -1 +1 @@
1
- {"version":3,"file":"page-to-markdown.d.ts","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;EAapC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAElD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDpC,CAAC;AASF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,OAAO,KAChB,OAAO,CAAC,oBAAoB,CAiC9B,CAAC"}
1
+ {"version":3,"file":"page-to-markdown.d.ts","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,yBAAyB;;;;;iBAapC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAG5E,MAAM,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAElD,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDpC,CAAC;AASF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,OAAO,KAChB,OAAO,CAAC,oBAAoB,CAkC9B,CAAC"}
@@ -68,8 +68,9 @@ export const handlePageToMarkdown = async (rawInput) => {
68
68
  input = pageToMarkdownInputSchema.parse(rawInput);
69
69
  }
70
70
  catch (e) {
71
+ // zod 4 renamed ZodError.errors to .issues; v2 of the MCP SDK requires zod >= 4.2.
71
72
  const msg = e instanceof z.ZodError
72
- ? e.errors.map((err) => `${err.path.join('.')}: ${err.message}`).join('; ')
73
+ ? e.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ')
73
74
  : String(e);
74
75
  return errorResult(`Invalid input: ${msg}`);
75
76
  }
@@ -1 +1 @@
1
- {"version":3,"file":"page-to-markdown.js","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"page-to-markdown.js","sourceRoot":"","sources":["../../src/tools/page-to-markdown.ts"],"names":[],"mappings":"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"}
package/manifest.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "manifest_version": "0.3",
3
3
  "name": "page2ai-mcp",
4
4
  "display_name": "Page2AI — Web to Markdown",
5
- "version": "0.1.1",
5
+ "version": "0.2.1",
6
6
  "description": "Convert any web page or HTML string to clean Markdown for LLM context",
7
7
  "long_description": "Page2AI MCP converts web pages to Markdown optimized for AI context windows. Extracts main content using DOM-position-aware dedup, preserves code blocks with language hints, converts tables and lists, and strips navigation, ads, and cookie banners. Works offline against local HTML strings or online against URLs. Zero external API calls in v0.1 — pure Node + linkedom.\n\nCompanion to the Page2AI Chrome extension. Shares the same extraction core (@page2ai/core) with the browser extension available at https://github.com/igorsaevets/page2ai-extension.",
8
8
  "author": {
@@ -37,7 +37,9 @@
37
37
  "entry_point": "dist/index.js",
38
38
  "mcp_config": {
39
39
  "command": "node",
40
- "args": ["${__dirname}/dist/index.js"]
40
+ "args": [
41
+ "${__dirname}/dist/index.js"
42
+ ]
41
43
  }
42
44
  },
43
45
  "tools": [
@@ -48,7 +50,11 @@
48
50
  ],
49
51
  "compatibility": {
50
52
  "claude_desktop": ">=1.0.0",
51
- "platforms": ["darwin", "win32", "linux"],
53
+ "platforms": [
54
+ "darwin",
55
+ "win32",
56
+ "linux"
57
+ ],
52
58
  "runtimes": {
53
59
  "node": ">=18.0.0"
54
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page2ai/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "mcpName": "io.github.igorsaevets/page2ai-mcp",
5
5
  "description": "MCP server that converts any web page URL to clean Markdown for LLM context. Zero external API calls, SSRF-guarded, 100% local.",
6
6
  "type": "module",
@@ -12,13 +12,14 @@
12
12
  "files": [
13
13
  "dist",
14
14
  "README.md",
15
+ "CHANGELOG.md",
15
16
  "PRIVACY.md",
16
17
  "LICENSE",
17
18
  "manifest.json",
18
19
  "server.json"
19
20
  ],
20
21
  "engines": {
21
- "node": ">=18.0.0"
22
+ "node": ">=20.0.0"
22
23
  },
23
24
  "scripts": {
24
25
  "build": "tsc -p tsconfig.build.json && node -e \"import('node:fs').then(({chmodSync})=>chmodSync('dist/index.js',0o755))\"",
@@ -26,15 +27,16 @@
26
27
  "start": "node dist/index.js",
27
28
  "test": "vitest run",
28
29
  "typecheck": "tsc --noEmit",
29
- "prepublishOnly": "npm run build && npm run test"
30
+ "prepublishOnly": "npm run build && npm run test",
31
+ "probe": "node scripts/probe-protocol.mjs node dist/index.js"
30
32
  },
31
33
  "publishConfig": {
32
34
  "access": "public"
33
35
  },
34
36
  "dependencies": {
35
- "@modelcontextprotocol/sdk": "^1.29.0",
36
- "@page2ai/core": "^0.1.0",
37
- "zod": "^3.24.0"
37
+ "@modelcontextprotocol/server": "^2.0.0",
38
+ "@page2ai/core": "^0.1.2",
39
+ "zod": "^4.2.0"
38
40
  },
39
41
  "devDependencies": {
40
42
  "@types/node": "^22.10.0",
package/server.json CHANGED
@@ -8,13 +8,15 @@
8
8
  "source": "github"
9
9
  },
10
10
  "websiteUrl": "https://github.com/igorsaevets/page2ai-mcp#readme",
11
- "version": "0.1.1",
11
+ "version": "0.2.0",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "@page2ai/mcp",
16
- "version": "0.1.1",
17
- "transport": { "type": "stdio" }
16
+ "version": "0.2.0",
17
+ "transport": {
18
+ "type": "stdio"
19
+ }
18
20
  }
19
21
  ]
20
22
  }