@microlink/mcp 2.4.1 → 2.5.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 CHANGED
@@ -161,9 +161,11 @@ Each tool is a thin wrapper over a [`microlink.io`](https://github.com/microlink
161
161
  ### Response shape
162
162
 
163
163
  - Each tool returns the library's **direct result** under `structuredContent.data` (and the same value as pretty-printed JSON text). For example `microlink_markdown` → `{ data: "# Title\n..." }`, `microlink_screenshot` → `{ data: { url, type, width, height, size } }`, `microlink_links` → `{ data: ["https://...", ...] }`.
164
+ - Every tool also declares an MCP `outputSchema` describing its `structuredContent.data`, mirroring the TypeScript types shipped by the library (`Asset`, `Metadata`, `Embed`, `FunctionResult`, ...), so MCP clients get machine-readable result contracts. Error results are exempt from output validation. Fields that can legitimately be absent are nullable (for example `logo` when no brand logo is detected, or `markdown` when the selector matches nothing).
165
+ - Tools are annotated `readOnlyHint: true` since they only fetch and transform public URLs. The exception is `microlink_function`, which executes user-supplied code and is not annotated read-only.
164
166
  - On failure the tool sets MCP `isError` and returns `{ error: { message, code?, status?, statusCode?, url?, more?, details? } }`, where `message` carries the specific cause reported by the API. Capability errors that retrying cannot fix (for example `EPROXYNEEDED` or `EINTEGRATION`) also include machine-readable `reason` (`upgrade_required`), `capability`, an `upgrade` object with the plan and pricing URL, and an agent-facing `hint` with the next step. A `429` includes `reason: "quota_exceeded"` and a free-quota `hint`.
165
167
 
166
- Parameters labeled `PRO` in the official Microlink docs require a paid plan.
168
+ Parameters that require a paid plan are labeled `PRO` in their own schema descriptions, mirroring the official Microlink docs.
167
169
  For compatibility with some MCP clients:
168
170
  - boolean parameters also accept the strings `"true"` and `"false"` and are normalized before validation.
169
171
  - parameters that accept objects also accept JSON stringified objects (for example, `screenshot: "{\"overlay\":{\"browser\":\"dark\"}}"`).
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@microlink/mcp",
3
3
  "description": "MCP server for Microlink API",
4
4
  "homepage": "https://github.com/microlinkhq/microlink",
5
- "version": "2.4.1",
5
+ "version": "2.5.0",
6
6
  "main": "./src/index.js",
7
7
  "exports": {
8
8
  ".": "./src/index.js"
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "@microlink/mql": "0.19.0",
47
47
  "@modelcontextprotocol/sdk": "1.30.0",
48
- "microlink.io": "0.10.3",
48
+ "microlink.io": "0.10.4",
49
49
  "zod": "~4.4.3"
50
50
  },
51
51
  "engines": {
@@ -59,12 +59,13 @@
59
59
  "scripts": {
60
60
  "postinstall": "node scripts/postinstall.js",
61
61
  "start": "node src/index.js",
62
- "test": "node --test test/*.test.js"
62
+ "test": "node --test test/*.test.js",
63
+ "test:live": "LIVE=1 node --test test/live.test.js"
63
64
  },
64
65
  "license": "MIT",
65
66
  "publishConfig": {
66
67
  "access": "public"
67
68
  },
68
69
  "type": "module",
69
- "gitHead": "f2d20e6f64995a7084ed097d5441d0f0f4950c76"
70
+ "gitHead": "69d1f76ff2dcbfb56cccd86a17da9c719e398301"
70
71
  }
package/src/index.js CHANGED
@@ -8,14 +8,25 @@ import { tools } from './tools/index.js'
8
8
  const require = createRequire(import.meta.url)
9
9
  const { version: pkgVersion } = require('../package.json')
10
10
 
11
+ const DEFAULT_INSTRUCTIONS = [
12
+ 'Turn any public URL into screenshots, PDFs, metadata, readable content (Markdown, HTML or plain text), media sources, technology stacks, Lighthouse audits, Google search results or custom-scraped fields.',
13
+ 'Always pass full URLs including the protocol.',
14
+ 'Without an API key, requests use the free endpoint (50 requests/day); pass apiKey or set MICROLINK_API_KEY for PRO.',
15
+ 'On failure, read the error message and the hint/reason fields and adjust the request instead of retrying blindly.'
16
+ ].join(' ')
17
+
11
18
  export function createMicrolinkServer ({
12
19
  name = 'microlink-mcp-server',
13
- version = pkgVersion
20
+ version = pkgVersion,
21
+ instructions = DEFAULT_INSTRUCTIONS
14
22
  } = {}) {
15
- const server = new McpServer({
16
- name,
17
- version
18
- })
23
+ const server = new McpServer(
24
+ {
25
+ name,
26
+ version
27
+ },
28
+ { instructions }
29
+ )
19
30
 
20
31
  tools(server)
21
32
 
@@ -7,7 +7,7 @@ export function extract (server) {
7
7
  'microlink_extract',
8
8
  [
9
9
  'Scrape custom fields from any public URL via Microlink using MQL data rules.',
10
- 'Pass `data` with the rules object (selector/selectorAll, attr, type, evaluate; nested rules and arrays supported); returns the extracted `data` object.',
10
+ 'Pass `data` with the rules object (selector/selectorAll, attr, type, evaluate; nested rules and arrays supported); returns the extracted `data` object. By default no page metadata is included; pass `meta: true` to also get the default metadata.',
11
11
  'Also supports combining capabilities (`screenshot`, `pdf`, `iframe`, `insights`) and browser controls in the same request.',
12
12
  'Mirrors the `microlink.extract(url, rules)` library method.'
13
13
  ].join(' '),
@@ -54,6 +54,30 @@ export const INTERACTIVE_ANNOTATIONS = {
54
54
  openWorldHint: true
55
55
  }
56
56
 
57
+ // Human-friendly titles shown by MCP clients for each tool.
58
+ const TITLES = {
59
+ metadata: 'Metadata',
60
+ logo: 'Logo',
61
+ markdown: 'Markdown',
62
+ html: 'HTML',
63
+ text: 'Plain text',
64
+ screenshot: 'Screenshot',
65
+ pdf: 'PDF',
66
+ embed: 'Embed',
67
+ video: 'Video',
68
+ audio: 'Audio',
69
+ links: 'Links',
70
+ images: 'Images',
71
+ videos: 'Videos',
72
+ audios: 'Audios',
73
+ emails: 'Emails',
74
+ technologies: 'Technologies',
75
+ lighthouse: 'Lighthouse',
76
+ search: 'Google search',
77
+ function: 'Function',
78
+ extract: 'Extract'
79
+ }
80
+
57
81
  // Common shape: a tool that maps to `client.<method>(url, options)`.
58
82
  export function urlMethod (method) {
59
83
  return (client, { url, ...options }) => client[method](url, options)
@@ -86,10 +110,11 @@ export function register (
86
110
  const key = name.replace(/^microlink_/, '')
87
111
  const dataSchema = outputSchemas[key]
88
112
  const outputSchema = dataSchema ? { data: dataSchema } : undefined
113
+ const title = TITLES[key]
89
114
 
90
115
  server.registerTool(
91
116
  name,
92
- { description, inputSchema, outputSchema, annotations },
117
+ { title, description, inputSchema, outputSchema, annotations },
93
118
  async (args, extra) => {
94
119
  const parsed = inputSchema.safeParse(args)
95
120