@ontosdk/mcp 1.3.0 → 1.3.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/README.md CHANGED
@@ -4,13 +4,18 @@ The official Onto Model Context Protocol server. Add clean web content reading a
4
4
 
5
5
  ## What this does
6
6
 
7
- Onto's MCP server exposes three tools to any AI agent:
7
+ Onto's MCP server exposes these tools to any AI agent:
8
8
 
9
9
  - **`read_url`** — Read any URL and get back clean, agent-ready Markdown (typically 10× smaller than raw HTML)
10
10
  - **`score_url`** — Get the AIO (AI-readability) score for any URL with a breakdown of what helps and what hurts AI consumption
11
11
  - **`read_and_score`** — Both at once: clean content plus quality assessment so the agent knows how much to trust the source
12
+ - **`batch`** — Read, score, or extract many URLs (an explicit list or a whole site) in one call
13
+ - **`map_site`** — Discover a site's URLs via its sitemap, without reading them
14
+ - **`extract_data`** — Return the structured data a page already declares (JSON-LD, OpenGraph, meta)
12
15
 
13
- This is the official MCP wrapper for the [Onto Read API](https://api.buildonto.dev).
16
+ Every tool response ends with a one-line **⚡ Onto report** — reduction, tokens saved, and AIO score — so the value is visible on every call.
17
+
18
+ This is the official MCP wrapper for the [Onto Read API](https://api.buildonto.dev). It's a thin, deterministic layer: Onto cleans and scores with a rule-based engine (no LLM in the loop), so your agent's own model never has to parse raw HTML.
14
19
 
15
20
  ## Why use this?
16
21
 
@@ -44,7 +49,7 @@ Add to your Claude Code MCP config:
44
49
  }
45
50
  ```
46
51
 
47
- Restart Claude Code. The `read_url`, `score_url`, and `read_and_score` tools will appear in the available tools list.
52
+ Restart Claude Code. The Onto tools (`read_url`, `score_url`, `read_and_score`, `batch`, `map_site`, `extract_data`) will appear in the available tools list.
48
53
 
49
54
  ### 3. Install in Cursor
50
55
 
@@ -103,6 +108,40 @@ Returns clean Markdown plus the AIO score in one call. Recommended default for a
103
108
 
104
109
  **Input:** same as `read_url`.
105
110
 
111
+ ### `batch`
112
+
113
+ Process many URLs in **one call** — billed as a single request, so you don't spend a credit per URL. Give an explicit list or a base URL whose pages are auto-discovered.
114
+
115
+ **Input:**
116
+
117
+ | Field | Type | Required | Description |
118
+ |---|---|---|---|
119
+ | `urls` | string[] | one of | Explicit list of URLs (max 50). Use this **or** `site`. |
120
+ | `site` | string | one of | Base URL whose pages are auto-discovered via sitemap. Use this **or** `urls`. |
121
+ | `mode` | `"read"` \| `"read-and-score"` \| `"extract"` | no | What to do per URL (default `"read-and-score"`) |
122
+ | `limit` | number | no | Site mode only: max pages to discover (default 25, max 50) |
123
+
124
+ ### `map_site`
125
+
126
+ Discover a site's URLs (sitemap → on-page links) without reading them. Cheap — use it to plan which pages to read or batch next.
127
+
128
+ **Input:**
129
+
130
+ | Field | Type | Required | Description |
131
+ |---|---|---|---|
132
+ | `url` | string | yes | Base URL of the site to map |
133
+ | `limit` | number | no | Max URLs to return (default 100, max 1000) |
134
+
135
+ ### `extract_data`
136
+
137
+ Return the structured data a page already declares — JSON-LD, OpenGraph, and meta tags — plus the AIO score. Deterministic; no fields are inferred by a model.
138
+
139
+ **Input:**
140
+
141
+ | Field | Type | Required | Description |
142
+ |---|---|---|---|
143
+ | `url` | string | yes | URL to extract structured data from |
144
+
106
145
  ## Pricing
107
146
 
108
147
  | Tier | Monthly requests | Price |
package/dist/index.d.ts CHANGED
@@ -240,6 +240,6 @@ interface CallOptions {
240
240
  }
241
241
  declare function callOntoApi<T>(endpoint: string, options: CallOptions): Promise<T>;
242
242
 
243
- declare const version = "1.3.0";
243
+ declare const version = "1.3.1";
244
244
 
245
245
  export { type BatchInput, type BatchResponse, type BatchResult, type ExtractInput, type ExtractResponse, type MapInput, type MapResponse, OntoApiError, type ReadAndScoreInput, type ReadAndScoreResponse, type ReadResponse, type ReadUrlInput, type Recommendation, type ScoreResponse, type ScoreUrlInput, batchInputSchema, batchRead, callOntoApi, extractData, extractInputSchema, mapInputSchema, mapSite, readAndScore, readAndScoreInputSchema, readUrl, readUrlInputSchema, scoreUrl, scoreUrlInputSchema, version };
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { z } from "zod";
3
3
 
4
4
  // src/lib/version.ts
5
- var version = "1.3.0";
5
+ var version = "1.3.1";
6
6
 
7
7
  // src/lib/api-client.ts
8
8
  var DEFAULT_BASE = "https://api.buildonto.dev";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tools/read.ts","../src/lib/version.ts","../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/report.ts","../src/tools/score.ts","../src/tools/read-and-score.ts","../src/tools/batch.ts","../src/tools/map.ts","../src/tools/extract.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadResponse } from '../lib/types.js';\n\nexport const readUrlInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadUrlInput = z.infer<typeof readUrlInputSchema>;\n\nexport async function readUrl(input: ReadUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadResponse>('/v1/read', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const metaLines = [\n `- URL: ${result.url}`,\n `- Title: ${result.metadata.title || '(none)'}`,\n `- Original size: ${result.stats.raw_html_size_kb} KB`,\n `- Cleaned size: ${result.stats.markdown_size_kb} KB`,\n `- Reduction: ${result.stats.reduction_percent}%`,\n `- Extraction time: ${result.stats.extraction_time_ms} ms`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n ].join('\\n');\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n {\n type: 'text' as const,\n text: `\\n\\n---\\n\\n**Source metadata (from Onto):**\\n${metaLines}\\n\\n${ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n })}`,\n },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","export const version = '1.3.0';\n","/* Thin HTTP wrapper around the Onto Read API. Reads ONTO_API_KEY at call time\n * (not module-load) so server.ts can fail with a clean error message first. */\n\nimport { version as PACKAGE_VERSION } from './version.js';\nimport type { ApiErrorBody } from './types.js';\n\nconst DEFAULT_BASE = 'https://api.buildonto.dev';\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport class OntoApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OntoApiError';\n }\n}\n\ninterface CallOptions {\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport async function callOntoApi<T>(endpoint: string, options: CallOptions): Promise<T> {\n const apiKey = process.env.ONTO_API_KEY;\n if (!apiKey) {\n throw new OntoApiError(\n 'ONTO_API_KEY environment variable is not set. Get a key at https://app.buildonto.dev/read/keys',\n 0,\n 'NO_API_KEY',\n );\n }\n\n const base = process.env.ONTO_API_BASE ?? DEFAULT_BASE;\n const url = `${base}${endpoint}`;\n\n const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeout])\n : timeout;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `@ontosdk/mcp/${PACKAGE_VERSION}`,\n },\n body: JSON.stringify(options.body),\n signal,\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new OntoApiError(\n `Onto API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s. The target site may be slow or unreachable.`,\n 0,\n 'TIMEOUT',\n );\n }\n throw new OntoApiError(\n `Failed to reach Onto API at ${base}: ${(err as Error).message}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n\n const rawBody = await response.text();\n\n if (!response.ok) {\n let parsed: Partial<ApiErrorBody> = {};\n try {\n parsed = JSON.parse(rawBody) as Partial<ApiErrorBody>;\n } catch {\n // Body wasn't JSON; fall through with status-code-only error\n }\n\n const message = humanizeError(response.status, parsed);\n throw new OntoApiError(message, response.status, parsed.error);\n }\n\n try {\n return JSON.parse(rawBody) as T;\n } catch (err) {\n throw new OntoApiError(\n `Onto API returned invalid JSON: ${(err as Error).message}`,\n response.status,\n 'INVALID_RESPONSE',\n );\n }\n}\n\nfunction humanizeError(status: number, body: Partial<ApiErrorBody>): string {\n if (status === 401) {\n return 'Invalid Onto API key. Verify your key at https://app.buildonto.dev/read/keys';\n }\n if (status === 402) {\n return (\n body.message ??\n 'Monthly plan quota exceeded and credit balance is empty. Top up credits at https://app.buildonto.dev/read/billing'\n );\n }\n if (status === 403) {\n if (body.error === 'ROBOTS_BLOCKED') {\n return body.message ?? 'The target site blocks AI crawlers via robots.txt.';\n }\n return body.message ?? 'Forbidden.';\n }\n if (status === 429) {\n return (\n body.message ??\n 'Onto API rate limit exceeded. Upgrade your tier at https://app.buildonto.dev/read/billing or wait for the monthly reset.'\n );\n }\n if (status >= 500) {\n return body.message ?? `Onto API server error (${status}). Try again in a moment.`;\n }\n return body.message ?? `Onto API returned ${status}.`;\n}\n","/* Format errors as MCP tool responses. We don't throw McpError for\n * tool-call failures — the AI host shows tool errors to the user as\n * unhelpful internal-error messages. Returning isError: true with a\n * text body lets the model see what went wrong and recover. */\n\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { OntoApiError } from './api-client.js';\n\nexport function formatToolError(error: unknown): CallToolResult {\n if (error instanceof OntoApiError) {\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n {\n type: 'text',\n text: `Onto MCP error: ${message}\\n\\nTroubleshooting:\\n- Verify ONTO_API_KEY is set and valid (https://app.buildonto.dev/read/keys)\\n- Check the target URL is publicly accessible\\n- Check your monthly quota at https://app.buildonto.dev/read/usage`,\n },\n ],\n isError: true,\n };\n}\n","/* The \"Onto report\" — a single branded summary line appended to the end of\n * every tool response. This is a deliberate growth surface: every agent call\n * leaves Onto's value (reduction, tokens saved, trust score) visible in the\n * host's context, and stamps the brand. Keep it to ONE line, always the same\n * shape so it becomes recognizable.\n *\n * Token estimate uses 4 bytes/token — the same heuristic the dashboard uses\n * for its \"tokens saved\" stat, so numbers stay consistent across surfaces.\n */\n\nconst BYTES_PER_TOKEN = 4;\n\nexport interface OntoReportInput {\n /** Raw HTML size in KB (before Onto cleaned it). */\n rawKb?: number;\n /** Clean Markdown size in KB (what the agent actually consumes). */\n cleanKb?: number;\n /** Percentage shrink from raw → clean. */\n reductionPercent?: number;\n /** AIO readability score 0–100, when available. */\n aioScore?: number;\n /** Hallucination-risk band, when available. */\n risk?: 'low' | 'medium' | 'high';\n}\n\n/** Estimated input tokens saved by serving Markdown instead of raw HTML. */\nexport function estimateTokensSaved(rawKb: number, cleanKb: number): number {\n const savedBytes = Math.max(0, (rawKb - cleanKb) * 1024);\n return Math.round(savedBytes / BYTES_PER_TOKEN);\n}\n\n/** Compact, human-friendly token count: 1234 → \"1.2K\", 199000 → \"199K\". */\nfunction compact(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 10_000) return `${Math.round(n / 1_000)}K`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return `${n}`;\n}\n\n/**\n * Build the single-line Onto report. Only the fields that are present get\n * rendered, so the same helper works for read_url (no score) and\n * read_and_score / score_url (with score).\n */\nexport function ontoReport(input: OntoReportInput): string {\n const parts: string[] = [];\n\n if (input.rawKb != null && input.cleanKb != null) {\n parts.push(`${input.rawKb}KB → ${input.cleanKb}KB`);\n if (input.reductionPercent != null) parts.push(`${input.reductionPercent}% smaller`);\n parts.push(`~${compact(estimateTokensSaved(input.rawKb, input.cleanKb))} tokens saved`);\n } else if (input.reductionPercent != null) {\n parts.push(`${input.reductionPercent}% smaller`);\n }\n\n if (input.aioScore != null) {\n parts.push(`AIO ${input.aioScore}/100${input.risk ? ` (${input.risk} risk)` : ''}`);\n }\n\n return `⚡ Onto · ${parts.join(' · ')} · buildonto.dev`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ScoreResponse, Recommendation } from '../lib/types.js';\n\nexport const scoreUrlInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ScoreUrlInput = z.infer<typeof scoreUrlInputSchema>;\n\nexport async function scoreUrl(input: ScoreUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ScoreResponse>('/v1/score', {\n body: { url: input.url },\n });\n\n return {\n content: [{ type: 'text' as const, text: formatScoreSummary(result) }],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nexport function formatScoreSummary(result: ScoreResponse): string {\n const lines: string[] = [\n `**AIO Score:** ${result.aio_score}/100 (${result.grade})`,\n `**Hallucination risk:** ${result.hallucination_risk}`,\n `**URL:** ${result.url}`,\n '',\n ];\n\n if (result.benefits.length > 0) {\n lines.push('**What works well:**');\n for (const item of result.benefits) lines.push(`- ${item}`);\n lines.push('');\n }\n\n if (result.penalties.length > 0) {\n lines.push('**What hurts AI readability:**');\n for (const item of result.penalties) lines.push(`- ${item}`);\n lines.push('');\n }\n\n const insightEntries = Object.entries(result.insights ?? {});\n if (insightEntries.length > 0) {\n lines.push('**Insights:**');\n for (const [key, value] of insightEntries) {\n lines.push(`- ${key}: ${value ? 'yes' : 'no'}`);\n }\n lines.push('');\n }\n\n if (result.recommendations.length > 0) {\n lines.push('**Recommendations:**');\n for (const rec of result.recommendations) {\n lines.push(describeRecommendation(rec));\n }\n lines.push('');\n }\n\n lines.push('**Stats:**');\n lines.push(`- Raw size: ${result.stats.raw_size}`);\n lines.push(`- Efficiency: ${result.stats.efficiency}`);\n lines.push(`- Extraction time: ${result.stats.extraction_time_ms} ms`);\n lines.push('');\n lines.push(ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }));\n\n return lines.join('\\n');\n}\n\nfunction describeRecommendation(rec: Recommendation): string {\n if (typeof rec === 'string') return `- ${rec}`;\n if (rec.title) {\n const head = rec.priority ? `**${rec.title}** _(priority: ${rec.priority})_` : `**${rec.title}**`;\n return rec.description ? `- ${head} — ${rec.description}` : `- ${head}`;\n }\n if (rec.description) return `- ${rec.description}`;\n return `- ${JSON.stringify(rec)}`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadAndScoreResponse } from '../lib/types.js';\n\nexport const readAndScoreInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadAndScoreInput = z.infer<typeof readAndScoreInputSchema>;\n\nexport async function readAndScore(input: ReadAndScoreInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadAndScoreResponse>('/v1/read-and-score', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const trustHint = trustLine(result.aio_score, result.hallucination_risk);\n const summaryLines = [\n `**Source quality assessment (from Onto):**`,\n `- AIO Score: ${result.aio_score}/100 (${result.grade})`,\n `- Hallucination risk: ${result.hallucination_risk}`,\n `- Reduction: ${result.stats.reduction_percent}% (${result.stats.raw_html_size_kb} KB → ${result.stats.markdown_size_kb} KB)`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n '',\n trustHint,\n '',\n ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n aioScore: result.aio_score,\n risk: result.hallucination_risk,\n }),\n ];\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n { type: 'text' as const, text: `\\n\\n---\\n\\n${summaryLines.join('\\n')}` },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nfunction trustLine(score: number, risk: 'low' | 'medium' | 'high'): string {\n if (risk === 'high' || score < 40) {\n return 'Trust signal: low — this source is poorly structured for AI consumption. Verify any facts before relying on them.';\n }\n if (risk === 'medium' || score < 70) {\n return 'Trust signal: medium — source is partially AI-readable. Cross-check critical claims.';\n }\n return 'Trust signal: high — source is well-structured for AI consumption.';\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { BatchResponse, BatchResult } from '../lib/types.js';\n\nexport const batchInputSchema = z\n .object({\n urls: z.array(z.string().url()).min(1).max(50).optional(),\n site: z.string().url().optional(),\n mode: z.enum(['read', 'read-and-score', 'extract']).optional(),\n limit: z.number().int().min(1).max(50).optional(),\n })\n .refine((v) => (v.urls && v.urls.length > 0) || v.site, {\n message: 'Provide either \"urls\" (array) or \"site\" (string).',\n });\n\nexport type BatchInput = z.infer<typeof batchInputSchema>;\n\nfunction renderResult(r: BatchResult): string {\n if (!r.ok) {\n return `### ${r.url}\\n_skipped — ${r.error?.code}: ${r.error?.message}_`;\n }\n const head = [`### ${r.title || r.url}`, r.url];\n if (r.aio_score != null) {\n head.push(`AIO ${r.aio_score}/100 (${r.grade}, ${r.hallucination_risk} risk)`);\n }\n if (r.reduction_percent != null) head.push(`${r.reduction_percent}% smaller`);\n const lines = [head.join(' · ')];\n\n if (r.structured) {\n lines.push('', `JSON-LD: ${r.counts?.json_ld ?? 0} · OG: ${r.counts?.open_graph ?? 0} · meta: ${r.counts?.meta ?? 0}`);\n if (r.structured.jsonLd.length > 0) {\n lines.push('```json', JSON.stringify(r.structured.jsonLd, null, 2), '```');\n }\n } else if (r.markdown) {\n lines.push('', r.markdown);\n }\n return lines.join('\\n');\n}\n\nexport async function batchRead(input: BatchInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<BatchResponse>('/v1/batch', {\n body: { urls: input.urls, site: input.site, mode: input.mode, limit: input.limit },\n });\n\n const header =\n result.source === 'site'\n ? `# Batch ${result.mode} — site discovery`\n : `# Batch ${result.mode} — ${result.requested} URL(s)`;\n\n const lines = [\n header,\n `${result.succeeded}/${result.requested} succeeded.`,\n '',\n ...result.results.map(renderResult).flatMap((block) => [block, '']),\n `⚡ Onto · ${result.succeeded}/${result.requested} URLs in one call · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { MapResponse } from '../lib/types.js';\n\nexport const mapInputSchema = z.object({\n url: z.string().url(),\n limit: z.number().int().min(1).max(1000).optional(),\n});\n\nexport type MapInput = z.infer<typeof mapInputSchema>;\n\nexport async function mapSite(input: MapInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<MapResponse>('/v1/map', {\n body: { url: input.url, limit: input.limit },\n });\n\n const lines: string[] = [\n `# Sitemap for ${result.url}`,\n `Discovered ${result.count} URL(s) via ${result.source}.`,\n '',\n ...result.urls.map((u) => `- ${u}`),\n '',\n `⚡ Onto · ${result.count} URLs mapped (${result.source}) · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ExtractResponse } from '../lib/types.js';\n\nexport const extractInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ExtractInput = z.infer<typeof extractInputSchema>;\n\nexport async function extractData(input: ExtractInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ExtractResponse>('/v1/extract', {\n body: { url: input.url },\n });\n\n const og = Object.entries(result.structured.openGraph);\n const meta = Object.entries(result.structured.meta);\n\n const lines: string[] = [\n `# Structured data for ${result.url}`,\n result.title ? `Title: ${result.title}` : '',\n `Found ${result.counts.json_ld} JSON-LD object(s), ${result.counts.open_graph} OpenGraph tag(s), ${result.counts.meta} meta tag(s).`,\n '',\n '## JSON-LD',\n result.structured.jsonLd.length > 0\n ? '```json\\n' + JSON.stringify(result.structured.jsonLd, null, 2) + '\\n```'\n : '(none declared)',\n '',\n '## OpenGraph',\n og.length > 0 ? og.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n '## Meta',\n meta.length > 0 ? meta.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }),\n ].filter((line) => line !== '');\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/tools/read.ts","../src/lib/version.ts","../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/report.ts","../src/tools/score.ts","../src/tools/read-and-score.ts","../src/tools/batch.ts","../src/tools/map.ts","../src/tools/extract.ts"],"sourcesContent":["import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadResponse } from '../lib/types.js';\n\nexport const readUrlInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadUrlInput = z.infer<typeof readUrlInputSchema>;\n\nexport async function readUrl(input: ReadUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadResponse>('/v1/read', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const metaLines = [\n `- URL: ${result.url}`,\n `- Title: ${result.metadata.title || '(none)'}`,\n `- Original size: ${result.stats.raw_html_size_kb} KB`,\n `- Cleaned size: ${result.stats.markdown_size_kb} KB`,\n `- Reduction: ${result.stats.reduction_percent}%`,\n `- Extraction time: ${result.stats.extraction_time_ms} ms`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n ].join('\\n');\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n {\n type: 'text' as const,\n text: `\\n\\n---\\n\\n**Source metadata (from Onto):**\\n${metaLines}\\n\\n${ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n })}`,\n },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","export const version = '1.3.1';\n","/* Thin HTTP wrapper around the Onto Read API. Reads ONTO_API_KEY at call time\n * (not module-load) so server.ts can fail with a clean error message first. */\n\nimport { version as PACKAGE_VERSION } from './version.js';\nimport type { ApiErrorBody } from './types.js';\n\nconst DEFAULT_BASE = 'https://api.buildonto.dev';\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport class OntoApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OntoApiError';\n }\n}\n\ninterface CallOptions {\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport async function callOntoApi<T>(endpoint: string, options: CallOptions): Promise<T> {\n const apiKey = process.env.ONTO_API_KEY;\n if (!apiKey) {\n throw new OntoApiError(\n 'ONTO_API_KEY environment variable is not set. Get a key at https://app.buildonto.dev/read/keys',\n 0,\n 'NO_API_KEY',\n );\n }\n\n const base = process.env.ONTO_API_BASE ?? DEFAULT_BASE;\n const url = `${base}${endpoint}`;\n\n const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeout])\n : timeout;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `@ontosdk/mcp/${PACKAGE_VERSION}`,\n },\n body: JSON.stringify(options.body),\n signal,\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new OntoApiError(\n `Onto API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s. The target site may be slow or unreachable.`,\n 0,\n 'TIMEOUT',\n );\n }\n throw new OntoApiError(\n `Failed to reach Onto API at ${base}: ${(err as Error).message}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n\n const rawBody = await response.text();\n\n if (!response.ok) {\n let parsed: Partial<ApiErrorBody> = {};\n try {\n parsed = JSON.parse(rawBody) as Partial<ApiErrorBody>;\n } catch {\n // Body wasn't JSON; fall through with status-code-only error\n }\n\n const message = humanizeError(response.status, parsed);\n throw new OntoApiError(message, response.status, parsed.error);\n }\n\n try {\n return JSON.parse(rawBody) as T;\n } catch (err) {\n throw new OntoApiError(\n `Onto API returned invalid JSON: ${(err as Error).message}`,\n response.status,\n 'INVALID_RESPONSE',\n );\n }\n}\n\nfunction humanizeError(status: number, body: Partial<ApiErrorBody>): string {\n if (status === 401) {\n return 'Invalid Onto API key. Verify your key at https://app.buildonto.dev/read/keys';\n }\n if (status === 402) {\n return (\n body.message ??\n 'Monthly plan quota exceeded and credit balance is empty. Top up credits at https://app.buildonto.dev/read/billing'\n );\n }\n if (status === 403) {\n if (body.error === 'ROBOTS_BLOCKED') {\n return body.message ?? 'The target site blocks AI crawlers via robots.txt.';\n }\n return body.message ?? 'Forbidden.';\n }\n if (status === 429) {\n return (\n body.message ??\n 'Onto API rate limit exceeded. Upgrade your tier at https://app.buildonto.dev/read/billing or wait for the monthly reset.'\n );\n }\n if (status >= 500) {\n return body.message ?? `Onto API server error (${status}). Try again in a moment.`;\n }\n return body.message ?? `Onto API returned ${status}.`;\n}\n","/* Format errors as MCP tool responses. We don't throw McpError for\n * tool-call failures — the AI host shows tool errors to the user as\n * unhelpful internal-error messages. Returning isError: true with a\n * text body lets the model see what went wrong and recover. */\n\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { OntoApiError } from './api-client.js';\n\nexport function formatToolError(error: unknown): CallToolResult {\n if (error instanceof OntoApiError) {\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n {\n type: 'text',\n text: `Onto MCP error: ${message}\\n\\nTroubleshooting:\\n- Verify ONTO_API_KEY is set and valid (https://app.buildonto.dev/read/keys)\\n- Check the target URL is publicly accessible\\n- Check your monthly quota at https://app.buildonto.dev/read/usage`,\n },\n ],\n isError: true,\n };\n}\n","/* The \"Onto report\" — a single branded summary line appended to the end of\n * every tool response. This is a deliberate growth surface: every agent call\n * leaves Onto's value (reduction, tokens saved, trust score) visible in the\n * host's context, and stamps the brand. Keep it to ONE line, always the same\n * shape so it becomes recognizable.\n *\n * Token estimate uses 4 bytes/token — the same heuristic the dashboard uses\n * for its \"tokens saved\" stat, so numbers stay consistent across surfaces.\n */\n\nconst BYTES_PER_TOKEN = 4;\n\nexport interface OntoReportInput {\n /** Raw HTML size in KB (before Onto cleaned it). */\n rawKb?: number;\n /** Clean Markdown size in KB (what the agent actually consumes). */\n cleanKb?: number;\n /** Percentage shrink from raw → clean. */\n reductionPercent?: number;\n /** AIO readability score 0–100, when available. */\n aioScore?: number;\n /** Hallucination-risk band, when available. */\n risk?: 'low' | 'medium' | 'high';\n}\n\n/** Estimated input tokens saved by serving Markdown instead of raw HTML. */\nexport function estimateTokensSaved(rawKb: number, cleanKb: number): number {\n const savedBytes = Math.max(0, (rawKb - cleanKb) * 1024);\n return Math.round(savedBytes / BYTES_PER_TOKEN);\n}\n\n/** Compact, human-friendly token count: 1234 → \"1.2K\", 199000 → \"199K\". */\nfunction compact(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 10_000) return `${Math.round(n / 1_000)}K`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return `${n}`;\n}\n\n/**\n * Build the single-line Onto report. Only the fields that are present get\n * rendered, so the same helper works for read_url (no score) and\n * read_and_score / score_url (with score).\n */\nexport function ontoReport(input: OntoReportInput): string {\n const parts: string[] = [];\n\n if (input.rawKb != null && input.cleanKb != null) {\n parts.push(`${input.rawKb}KB → ${input.cleanKb}KB`);\n if (input.reductionPercent != null) parts.push(`${input.reductionPercent}% smaller`);\n parts.push(`~${compact(estimateTokensSaved(input.rawKb, input.cleanKb))} tokens saved`);\n } else if (input.reductionPercent != null) {\n parts.push(`${input.reductionPercent}% smaller`);\n }\n\n if (input.aioScore != null) {\n parts.push(`AIO ${input.aioScore}/100${input.risk ? ` (${input.risk} risk)` : ''}`);\n }\n\n return `⚡ Onto · ${parts.join(' · ')} · buildonto.dev`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ScoreResponse, Recommendation } from '../lib/types.js';\n\nexport const scoreUrlInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ScoreUrlInput = z.infer<typeof scoreUrlInputSchema>;\n\nexport async function scoreUrl(input: ScoreUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ScoreResponse>('/v1/score', {\n body: { url: input.url },\n });\n\n return {\n content: [{ type: 'text' as const, text: formatScoreSummary(result) }],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nexport function formatScoreSummary(result: ScoreResponse): string {\n const lines: string[] = [\n `**AIO Score:** ${result.aio_score}/100 (${result.grade})`,\n `**Hallucination risk:** ${result.hallucination_risk}`,\n `**URL:** ${result.url}`,\n '',\n ];\n\n if (result.benefits.length > 0) {\n lines.push('**What works well:**');\n for (const item of result.benefits) lines.push(`- ${item}`);\n lines.push('');\n }\n\n if (result.penalties.length > 0) {\n lines.push('**What hurts AI readability:**');\n for (const item of result.penalties) lines.push(`- ${item}`);\n lines.push('');\n }\n\n const insightEntries = Object.entries(result.insights ?? {});\n if (insightEntries.length > 0) {\n lines.push('**Insights:**');\n for (const [key, value] of insightEntries) {\n lines.push(`- ${key}: ${value ? 'yes' : 'no'}`);\n }\n lines.push('');\n }\n\n if (result.recommendations.length > 0) {\n lines.push('**Recommendations:**');\n for (const rec of result.recommendations) {\n lines.push(describeRecommendation(rec));\n }\n lines.push('');\n }\n\n lines.push('**Stats:**');\n lines.push(`- Raw size: ${result.stats.raw_size}`);\n lines.push(`- Efficiency: ${result.stats.efficiency}`);\n lines.push(`- Extraction time: ${result.stats.extraction_time_ms} ms`);\n lines.push('');\n lines.push(ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }));\n\n return lines.join('\\n');\n}\n\nfunction describeRecommendation(rec: Recommendation): string {\n if (typeof rec === 'string') return `- ${rec}`;\n if (rec.title) {\n const head = rec.priority ? `**${rec.title}** _(priority: ${rec.priority})_` : `**${rec.title}**`;\n return rec.description ? `- ${head} — ${rec.description}` : `- ${head}`;\n }\n if (rec.description) return `- ${rec.description}`;\n return `- ${JSON.stringify(rec)}`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadAndScoreResponse } from '../lib/types.js';\n\nexport const readAndScoreInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadAndScoreInput = z.infer<typeof readAndScoreInputSchema>;\n\nexport async function readAndScore(input: ReadAndScoreInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadAndScoreResponse>('/v1/read-and-score', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const trustHint = trustLine(result.aio_score, result.hallucination_risk);\n const summaryLines = [\n `**Source quality assessment (from Onto):**`,\n `- AIO Score: ${result.aio_score}/100 (${result.grade})`,\n `- Hallucination risk: ${result.hallucination_risk}`,\n `- Reduction: ${result.stats.reduction_percent}% (${result.stats.raw_html_size_kb} KB → ${result.stats.markdown_size_kb} KB)`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n '',\n trustHint,\n '',\n ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n aioScore: result.aio_score,\n risk: result.hallucination_risk,\n }),\n ];\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n { type: 'text' as const, text: `\\n\\n---\\n\\n${summaryLines.join('\\n')}` },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nfunction trustLine(score: number, risk: 'low' | 'medium' | 'high'): string {\n if (risk === 'high' || score < 40) {\n return 'Trust signal: low — this source is poorly structured for AI consumption. Verify any facts before relying on them.';\n }\n if (risk === 'medium' || score < 70) {\n return 'Trust signal: medium — source is partially AI-readable. Cross-check critical claims.';\n }\n return 'Trust signal: high — source is well-structured for AI consumption.';\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { BatchResponse, BatchResult } from '../lib/types.js';\n\nexport const batchInputSchema = z\n .object({\n urls: z.array(z.string().url()).min(1).max(50).optional(),\n site: z.string().url().optional(),\n mode: z.enum(['read', 'read-and-score', 'extract']).optional(),\n limit: z.number().int().min(1).max(50).optional(),\n })\n .refine((v) => (v.urls && v.urls.length > 0) || v.site, {\n message: 'Provide either \"urls\" (array) or \"site\" (string).',\n });\n\nexport type BatchInput = z.infer<typeof batchInputSchema>;\n\nfunction renderResult(r: BatchResult): string {\n if (!r.ok) {\n return `### ${r.url}\\n_skipped — ${r.error?.code}: ${r.error?.message}_`;\n }\n const head = [`### ${r.title || r.url}`, r.url];\n if (r.aio_score != null) {\n head.push(`AIO ${r.aio_score}/100 (${r.grade}, ${r.hallucination_risk} risk)`);\n }\n if (r.reduction_percent != null) head.push(`${r.reduction_percent}% smaller`);\n const lines = [head.join(' · ')];\n\n if (r.structured) {\n lines.push('', `JSON-LD: ${r.counts?.json_ld ?? 0} · OG: ${r.counts?.open_graph ?? 0} · meta: ${r.counts?.meta ?? 0}`);\n if (r.structured.jsonLd.length > 0) {\n lines.push('```json', JSON.stringify(r.structured.jsonLd, null, 2), '```');\n }\n } else if (r.markdown) {\n lines.push('', r.markdown);\n }\n return lines.join('\\n');\n}\n\nexport async function batchRead(input: BatchInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<BatchResponse>('/v1/batch', {\n body: { urls: input.urls, site: input.site, mode: input.mode, limit: input.limit },\n });\n\n const header =\n result.source === 'site'\n ? `# Batch ${result.mode} — site discovery`\n : `# Batch ${result.mode} — ${result.requested} URL(s)`;\n\n const lines = [\n header,\n `${result.succeeded}/${result.requested} succeeded.`,\n '',\n ...result.results.map(renderResult).flatMap((block) => [block, '']),\n `⚡ Onto · ${result.succeeded}/${result.requested} URLs in one call · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { MapResponse } from '../lib/types.js';\n\nexport const mapInputSchema = z.object({\n url: z.string().url(),\n limit: z.number().int().min(1).max(1000).optional(),\n});\n\nexport type MapInput = z.infer<typeof mapInputSchema>;\n\nexport async function mapSite(input: MapInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<MapResponse>('/v1/map', {\n body: { url: input.url, limit: input.limit },\n });\n\n const lines: string[] = [\n `# Sitemap for ${result.url}`,\n `Discovered ${result.count} URL(s) via ${result.source}.`,\n '',\n ...result.urls.map((u) => `- ${u}`),\n '',\n `⚡ Onto · ${result.count} URLs mapped (${result.source}) · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ExtractResponse } from '../lib/types.js';\n\nexport const extractInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ExtractInput = z.infer<typeof extractInputSchema>;\n\nexport async function extractData(input: ExtractInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ExtractResponse>('/v1/extract', {\n body: { url: input.url },\n });\n\n const og = Object.entries(result.structured.openGraph);\n const meta = Object.entries(result.structured.meta);\n\n const lines: string[] = [\n `# Structured data for ${result.url}`,\n result.title ? `Title: ${result.title}` : '',\n `Found ${result.counts.json_ld} JSON-LD object(s), ${result.counts.open_graph} OpenGraph tag(s), ${result.counts.meta} meta tag(s).`,\n '',\n '## JSON-LD',\n result.structured.jsonLd.length > 0\n ? '```json\\n' + JSON.stringify(result.structured.jsonLd, null, 2) + '\\n```'\n : '(none declared)',\n '',\n '## OpenGraph',\n og.length > 0 ? og.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n '## Meta',\n meta.length > 0 ? meta.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }),\n ].filter((line) => line !== '');\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n"],"mappings":";AAAA,SAAS,SAAS;;;ACAX,IAAM,UAAU;;;ACMvB,IAAM,eAAe;AACrB,IAAM,qBAAqB;AAEpB,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YACE,SACgB,QACA,MAChB;AACA,UAAM,OAAO;AAHG;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;AAOA,eAAsB,YAAe,UAAkB,SAAkC;AACvF,QAAM,SAAS,QAAQ,IAAI;AAC3B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO,QAAQ,IAAI,iBAAiB;AAC1C,QAAM,MAAM,GAAG,IAAI,GAAG,QAAQ;AAE9B,QAAM,UAAU,YAAY,QAAQ,kBAAkB;AACtD,QAAM,SAAS,QAAQ,SACnB,YAAY,IAAI,CAAC,QAAQ,QAAQ,OAAO,CAAC,IACzC;AAEJ,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,MAAM,KAAK;AAAA,MAC1B,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,MAAM;AAAA,QAC/B,gBAAgB;AAAA,QAChB,cAAc,gBAAgB,OAAe;AAAA,MAC/C;AAAA,MACA,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,eAAe,gBAAgB,IAAI,SAAS,gBAAgB;AAC9D,YAAM,IAAI;AAAA,QACR,oCAAoC,qBAAqB,GAAI;AAAA,QAC7D;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,IAAI;AAAA,MACR,+BAA+B,IAAI,KAAM,IAAc,OAAO;AAAA,MAC9D;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,MAAI,CAAC,SAAS,IAAI;AAChB,QAAI,SAAgC,CAAC;AACrC,QAAI;AACF,eAAS,KAAK,MAAM,OAAO;AAAA,IAC7B,QAAQ;AAAA,IAER;AAEA,UAAM,UAAU,cAAc,SAAS,QAAQ,MAAM;AACrD,UAAM,IAAI,aAAa,SAAS,SAAS,QAAQ,OAAO,KAAK;AAAA,EAC/D;AAEA,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,mCAAoC,IAAc,OAAO;AAAA,MACzD,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,QAAgB,MAAqC;AAC1E,MAAI,WAAW,KAAK;AAClB,WAAO;AAAA,EACT;AACA,MAAI,WAAW,KAAK;AAClB,WACE,KAAK,WACL;AAAA,EAEJ;AACA,MAAI,WAAW,KAAK;AAClB,QAAI,KAAK,UAAU,kBAAkB;AACnC,aAAO,KAAK,WAAW;AAAA,IACzB;AACA,WAAO,KAAK,WAAW;AAAA,EACzB;AACA,MAAI,WAAW,KAAK;AAClB,WACE,KAAK,WACL;AAAA,EAEJ;AACA,MAAI,UAAU,KAAK;AACjB,WAAO,KAAK,WAAW,0BAA0B,MAAM;AAAA,EACzD;AACA,SAAO,KAAK,WAAW,qBAAqB,MAAM;AACpD;;;ACjHO,SAAS,gBAAgB,OAAgC;AAC9D,MAAI,iBAAiB,cAAc;AACjC,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,MAAM,QAAQ,CAAC;AAAA,MAC/C,SAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,QACE,MAAM;AAAA,QACN,MAAM,mBAAmB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAClC;AAAA,IACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;AChBA,IAAM,kBAAkB;AAgBjB,SAAS,oBAAoB,OAAe,SAAyB;AAC1E,QAAM,aAAa,KAAK,IAAI,IAAI,QAAQ,WAAW,IAAI;AACvD,SAAO,KAAK,MAAM,aAAa,eAAe;AAChD;AAGA,SAAS,QAAQ,GAAmB;AAClC,MAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACxD,MAAI,KAAK,IAAQ,QAAO,GAAG,KAAK,MAAM,IAAI,GAAK,CAAC;AAChD,MAAI,KAAK,IAAO,QAAO,IAAI,IAAI,KAAO,QAAQ,CAAC,CAAC;AAChD,SAAO,GAAG,CAAC;AACb;AAOO,SAAS,WAAW,OAAgC;AACzD,QAAM,QAAkB,CAAC;AAEzB,MAAI,MAAM,SAAS,QAAQ,MAAM,WAAW,MAAM;AAChD,UAAM,KAAK,GAAG,MAAM,KAAK,aAAQ,MAAM,OAAO,IAAI;AAClD,QAAI,MAAM,oBAAoB,KAAM,OAAM,KAAK,GAAG,MAAM,gBAAgB,WAAW;AACnF,UAAM,KAAK,IAAI,QAAQ,oBAAoB,MAAM,OAAO,MAAM,OAAO,CAAC,CAAC,eAAe;AAAA,EACxF,WAAW,MAAM,oBAAoB,MAAM;AACzC,UAAM,KAAK,GAAG,MAAM,gBAAgB,WAAW;AAAA,EACjD;AAEA,MAAI,MAAM,YAAY,MAAM;AAC1B,UAAM,KAAK,OAAO,MAAM,QAAQ,OAAO,MAAM,OAAO,KAAK,MAAM,IAAI,WAAW,EAAE,EAAE;AAAA,EACpF;AAEA,SAAO,oBAAY,MAAM,KAAK,QAAK,CAAC;AACtC;;;AJrDO,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,KAAK,EAAE,OAAO,EAAE,IAAI;AAAA,EACpB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAC7C,CAAC;AAID,eAAsB,QAAQ,OAA8C;AAC1E,MAAI;AACF,UAAM,SAAS,MAAM,YAA0B,YAAY;AAAA,MACzD,MAAM,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,IAC7C,CAAC;AAED,UAAM,YAAY;AAAA,MAChB,UAAU,OAAO,GAAG;AAAA,MACpB,YAAY,OAAO,SAAS,SAAS,QAAQ;AAAA,MAC7C,oBAAoB,OAAO,MAAM,gBAAgB;AAAA,MACjD,mBAAmB,OAAO,MAAM,gBAAgB;AAAA,MAChD,gBAAgB,OAAO,MAAM,iBAAiB;AAAA,MAC9C,sBAAsB,OAAO,MAAM,kBAAkB;AAAA,MACrD,YAAY,OAAO,MAAM,MAAM,QAAQ,MAAM;AAAA,IAC/C,EAAE,KAAK,IAAI;AAEX,WAAO;AAAA,MACL,SAAS;AAAA,QACP,EAAE,MAAM,QAAiB,MAAM,OAAO,SAAS;AAAA,QAC/C;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,EAAgD,SAAS;AAAA;AAAA,EAAO,WAAW;AAAA,YAC/E,OAAO,OAAO,MAAM;AAAA,YACpB,SAAS,OAAO,MAAM;AAAA,YACtB,kBAAkB,OAAO,MAAM;AAAA,UACjC,CAAC,CAAC;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;;;AK9CA,SAAS,KAAAA,UAAS;AAOX,IAAM,sBAAsBC,GAAE,OAAO;AAAA,EAC1C,KAAKA,GAAE,OAAO,EAAE,IAAI;AACtB,CAAC;AAID,eAAsB,SAAS,OAA+C;AAC5E,MAAI;AACF,UAAM,SAAS,MAAM,YAA2B,aAAa;AAAA,MAC3D,MAAM,EAAE,KAAK,MAAM,IAAI;AAAA,IACzB,CAAC;AAED,WAAO;AAAA,MACL,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,mBAAmB,MAAM,EAAE,CAAC;AAAA,IACvE;AAAA,EACF,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;AAEO,SAAS,mBAAmB,QAA+B;AAChE,QAAM,QAAkB;AAAA,IACtB,kBAAkB,OAAO,SAAS,SAAS,OAAO,KAAK;AAAA,IACvD,2BAA2B,OAAO,kBAAkB;AAAA,IACpD,YAAY,OAAO,GAAG;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,sBAAsB;AACjC,eAAW,QAAQ,OAAO,SAAU,OAAM,KAAK,KAAK,IAAI,EAAE;AAC1D,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,UAAM,KAAK,gCAAgC;AAC3C,eAAW,QAAQ,OAAO,UAAW,OAAM,KAAK,KAAK,IAAI,EAAE;AAC3D,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,iBAAiB,OAAO,QAAQ,OAAO,YAAY,CAAC,CAAC;AAC3D,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,KAAK,eAAe;AAC1B,eAAW,CAAC,KAAK,KAAK,KAAK,gBAAgB;AACzC,YAAM,KAAK,KAAK,GAAG,KAAK,QAAQ,QAAQ,IAAI,EAAE;AAAA,IAChD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,gBAAgB,SAAS,GAAG;AACrC,UAAM,KAAK,sBAAsB;AACjC,eAAW,OAAO,OAAO,iBAAiB;AACxC,YAAM,KAAK,uBAAuB,GAAG,CAAC;AAAA,IACxC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,eAAe,OAAO,MAAM,QAAQ,EAAE;AACjD,QAAM,KAAK,iBAAiB,OAAO,MAAM,UAAU,EAAE;AACrD,QAAM,KAAK,sBAAsB,OAAO,MAAM,kBAAkB,KAAK;AACrE,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,WAAW,EAAE,UAAU,OAAO,WAAW,MAAM,OAAO,mBAAmB,CAAC,CAAC;AAEtF,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,uBAAuB,KAA6B;AAC3D,MAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,GAAG;AAC5C,MAAI,IAAI,OAAO;AACb,UAAM,OAAO,IAAI,WAAW,KAAK,IAAI,KAAK,kBAAkB,IAAI,QAAQ,OAAO,KAAK,IAAI,KAAK;AAC7F,WAAO,IAAI,cAAc,KAAK,IAAI,WAAM,IAAI,WAAW,KAAK,KAAK,IAAI;AAAA,EACvE;AACA,MAAI,IAAI,YAAa,QAAO,KAAK,IAAI,WAAW;AAChD,SAAO,KAAK,KAAK,UAAU,GAAG,CAAC;AACjC;;;AClFA,SAAS,KAAAC,UAAS;AAOX,IAAM,0BAA0BC,GAAE,OAAO;AAAA,EAC9C,KAAKA,GAAE,OAAO,EAAE,IAAI;AAAA,EACpB,OAAOA,GAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,KAAK;AAC7C,CAAC;AAID,eAAsB,aAAa,OAAmD;AACpF,MAAI;AACF,UAAM,SAAS,MAAM,YAAkC,sBAAsB;AAAA,MAC3E,MAAM,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,IAC7C,CAAC;AAED,UAAM,YAAY,UAAU,OAAO,WAAW,OAAO,kBAAkB;AACvE,UAAM,eAAe;AAAA,MACnB;AAAA,MACA,gBAAgB,OAAO,SAAS,SAAS,OAAO,KAAK;AAAA,MACrD,yBAAyB,OAAO,kBAAkB;AAAA,MAClD,gBAAgB,OAAO,MAAM,iBAAiB,MAAM,OAAO,MAAM,gBAAgB,cAAS,OAAO,MAAM,gBAAgB;AAAA,MACvH,YAAY,OAAO,MAAM,MAAM,QAAQ,MAAM;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,QACT,OAAO,OAAO,MAAM;AAAA,QACpB,SAAS,OAAO,MAAM;AAAA,QACtB,kBAAkB,OAAO,MAAM;AAAA,QAC/B,UAAU,OAAO;AAAA,QACjB,MAAM,OAAO;AAAA,MACf,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,QACP,EAAE,MAAM,QAAiB,MAAM,OAAO,SAAS;AAAA,QAC/C,EAAE,MAAM,QAAiB,MAAM;AAAA;AAAA;AAAA;AAAA,EAAc,aAAa,KAAK,IAAI,CAAC,GAAG;AAAA,MACzE;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;AAEA,SAAS,UAAU,OAAe,MAAyC;AACzE,MAAI,SAAS,UAAU,QAAQ,IAAI;AACjC,WAAO;AAAA,EACT;AACA,MAAI,SAAS,YAAY,QAAQ,IAAI;AACnC,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;AC1DA,SAAS,KAAAC,UAAS;AAMX,IAAM,mBAAmBC,GAC7B,OAAO;AAAA,EACN,MAAMA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAAA,EACxD,MAAMA,GAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAChC,MAAMA,GAAE,KAAK,CAAC,QAAQ,kBAAkB,SAAS,CAAC,EAAE,SAAS;AAAA,EAC7D,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS;AAClD,CAAC,EACA,OAAO,CAAC,MAAO,EAAE,QAAQ,EAAE,KAAK,SAAS,KAAM,EAAE,MAAM;AAAA,EACtD,SAAS;AACX,CAAC;AAIH,SAAS,aAAa,GAAwB;AAC5C,MAAI,CAAC,EAAE,IAAI;AACT,WAAO,OAAO,EAAE,GAAG;AAAA,kBAAgB,EAAE,OAAO,IAAI,KAAK,EAAE,OAAO,OAAO;AAAA,EACvE;AACA,QAAM,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG;AAC9C,MAAI,EAAE,aAAa,MAAM;AACvB,SAAK,KAAK,OAAO,EAAE,SAAS,SAAS,EAAE,KAAK,KAAK,EAAE,kBAAkB,QAAQ;AAAA,EAC/E;AACA,MAAI,EAAE,qBAAqB,KAAM,MAAK,KAAK,GAAG,EAAE,iBAAiB,WAAW;AAC5E,QAAM,QAAQ,CAAC,KAAK,KAAK,QAAK,CAAC;AAE/B,MAAI,EAAE,YAAY;AAChB,UAAM,KAAK,IAAI,YAAY,EAAE,QAAQ,WAAW,CAAC,aAAU,EAAE,QAAQ,cAAc,CAAC,eAAY,EAAE,QAAQ,QAAQ,CAAC,EAAE;AACrH,QAAI,EAAE,WAAW,OAAO,SAAS,GAAG;AAClC,YAAM,KAAK,WAAW,KAAK,UAAU,EAAE,WAAW,QAAQ,MAAM,CAAC,GAAG,KAAK;AAAA,IAC3E;AAAA,EACF,WAAW,EAAE,UAAU;AACrB,UAAM,KAAK,IAAI,EAAE,QAAQ;AAAA,EAC3B;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,UAAU,OAA4C;AAC1E,MAAI;AACF,UAAM,SAAS,MAAM,YAA2B,aAAa;AAAA,MAC3D,MAAM,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM;AAAA,IACnF,CAAC;AAED,UAAM,SACJ,OAAO,WAAW,SACd,WAAW,OAAO,IAAI,2BACtB,WAAW,OAAO,IAAI,WAAM,OAAO,SAAS;AAElD,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA,GAAG,OAAO,SAAS,IAAI,OAAO,SAAS;AAAA,MACvC;AAAA,MACA,GAAG,OAAO,QAAQ,IAAI,YAAY,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;AAAA,MAClE,oBAAY,OAAO,SAAS,IAAI,OAAO,SAAS;AAAA,IAClD;AAEA,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,EACxE,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;;;AChEA,SAAS,KAAAC,UAAS;AAMX,IAAM,iBAAiBC,GAAE,OAAO;AAAA,EACrC,KAAKA,GAAE,OAAO,EAAE,IAAI;AAAA,EACpB,OAAOA,GAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS;AACpD,CAAC;AAID,eAAsB,QAAQ,OAA0C;AACtE,MAAI;AACF,UAAM,SAAS,MAAM,YAAyB,WAAW;AAAA,MACvD,MAAM,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,MAAM;AAAA,IAC7C,CAAC;AAED,UAAM,QAAkB;AAAA,MACtB,iBAAiB,OAAO,GAAG;AAAA,MAC3B,cAAc,OAAO,KAAK,eAAe,OAAO,MAAM;AAAA,MACtD;AAAA,MACA,GAAG,OAAO,KAAK,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAAA,MAClC;AAAA,MACA,oBAAY,OAAO,KAAK,iBAAiB,OAAO,MAAM;AAAA,IACxD;AAEA,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,EACxE,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;;;AChCA,SAAS,KAAAC,UAAS;AAOX,IAAM,qBAAqBC,GAAE,OAAO;AAAA,EACzC,KAAKA,GAAE,OAAO,EAAE,IAAI;AACtB,CAAC;AAID,eAAsB,YAAY,OAA8C;AAC9E,MAAI;AACF,UAAM,SAAS,MAAM,YAA6B,eAAe;AAAA,MAC/D,MAAM,EAAE,KAAK,MAAM,IAAI;AAAA,IACzB,CAAC;AAED,UAAM,KAAK,OAAO,QAAQ,OAAO,WAAW,SAAS;AACrD,UAAM,OAAO,OAAO,QAAQ,OAAO,WAAW,IAAI;AAElD,UAAM,QAAkB;AAAA,MACtB,yBAAyB,OAAO,GAAG;AAAA,MACnC,OAAO,QAAQ,UAAU,OAAO,KAAK,KAAK;AAAA,MAC1C,SAAS,OAAO,OAAO,OAAO,uBAAuB,OAAO,OAAO,UAAU,sBAAsB,OAAO,OAAO,IAAI;AAAA,MACrH;AAAA,MACA;AAAA,MACA,OAAO,WAAW,OAAO,SAAS,IAC9B,cAAc,KAAK,UAAU,OAAO,WAAW,QAAQ,MAAM,CAAC,IAAI,UAClE;AAAA,MACJ;AAAA,MACA;AAAA,MACA,GAAG,SAAS,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI;AAAA,MAChE;AAAA,MACA;AAAA,MACA,KAAK,SAAS,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI;AAAA,MACpE;AAAA,MACA,WAAW,EAAE,UAAU,OAAO,WAAW,MAAM,OAAO,mBAAmB,CAAC;AAAA,IAC5E,EAAE,OAAO,CAAC,SAAS,SAAS,EAAE;AAE9B,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,MAAM,KAAK,IAAI,EAAE,CAAC,EAAE;AAAA,EACxE,SAAS,OAAO;AACd,WAAO,gBAAgB,KAAK;AAAA,EAC9B;AACF;","names":["z","z","z","z","z","z","z","z","z","z"]}
package/dist/server.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  import { z } from "zod";
15
15
 
16
16
  // src/lib/version.ts
17
- var version = "1.3.0";
17
+ var version = "1.3.1";
18
18
 
19
19
  // src/lib/api-client.ts
20
20
  var DEFAULT_BASE = "https://api.buildonto.dev";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts","../src/tools/read.ts","../src/lib/version.ts","../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/report.ts","../src/tools/score.ts","../src/tools/read-and-score.ts","../src/tools/batch.ts","../src/tools/map.ts","../src/tools/extract.ts"],"sourcesContent":["/* Onto MCP Server — exposes the Onto Read API as Model Context Protocol tools.\n *\n * Tools: read_url, score_url, read_and_score.\n * Reads ONTO_API_KEY from env. Defaults base URL to https://api.buildonto.dev.\n *\n * Install in Claude Code:\n * \"mcpServers\": {\n * \"onto\": {\n * \"command\": \"npx\",\n * \"args\": [\"-y\", \"@ontosdk/mcp\"],\n * \"env\": { \"ONTO_API_KEY\": \"onto_sk_live_...\" }\n * }\n * }\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ErrorCode,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { readUrl, readUrlInputSchema } from './tools/read.js';\nimport { scoreUrl, scoreUrlInputSchema } from './tools/score.js';\nimport { readAndScore, readAndScoreInputSchema } from './tools/read-and-score.js';\nimport { batchRead, batchInputSchema } from './tools/batch.js';\nimport { mapSite, mapInputSchema } from './tools/map.js';\nimport { extractData, extractInputSchema } from './tools/extract.js';\nimport { version } from './lib/version.js';\n\nif (!process.env.ONTO_API_KEY) {\n console.error('[onto-mcp] ONTO_API_KEY environment variable is required.');\n console.error('[onto-mcp] Create a key at https://app.buildonto.dev/read/keys');\n process.exit(1);\n}\n\nconst server = new Server(\n { name: 'onto', version },\n { capabilities: { tools: {} } },\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'read_url',\n description:\n 'Read any URL and return clean, agent-ready Markdown. Strips HTML noise, preserves semantic content, and returns content optimized for AI consumption. Use this when you need to extract content from a website for an AI agent to process.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to read. Must be a publicly accessible HTTP or HTTPS URL.',\n },\n fresh: {\n type: 'boolean',\n description: 'If true, bypass cache and fetch fresh content. Default false.',\n default: false,\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'score_url',\n description:\n 'Get the AIO (AI-readability) score for any URL. Returns a 0-100 score plus a list of penalties, benefits, and recommendations describing why the source is or is not well-suited for AI consumption. Use this to evaluate source quality before relying on it.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to score.',\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'read_and_score',\n description:\n 'Read any URL and return both clean Markdown AND the AIO accuracy score in one call. The recommended default for most AI workflows — gives both content and quality assessment together, so the AI agent can decide how much to trust the content.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to read and score.',\n },\n fresh: {\n type: 'boolean',\n description: 'If true, bypass cache and fetch fresh content. Default false.',\n default: false,\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'batch',\n description:\n 'Process many URLs in ONE call (billed as one request) — so you do not spend a credit per URL. Give either \"urls\" (an explicit list, up to 50) or \"site\" (a base URL whose pages are auto-discovered via sitemap). \"mode\" picks what to do per URL: \"read\" (Markdown), \"read-and-score\" (Markdown + AIO trust score, default), or \"extract\" (JSON-LD + OpenGraph + meta + score). Use this for full-site reads or bulk URL processing.',\n inputSchema: {\n type: 'object',\n properties: {\n urls: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit list of URLs to process (up to 50). Use this OR \"site\".',\n },\n site: {\n type: 'string',\n description: 'Base URL of a site whose pages will be auto-discovered. Use this OR \"urls\".',\n },\n mode: {\n type: 'string',\n enum: ['read', 'read-and-score', 'extract'],\n description: 'What to do per URL. Default \"read-and-score\".',\n },\n limit: {\n type: 'number',\n description: 'Site mode only: max pages to discover (default 25, max 50).',\n },\n },\n },\n },\n {\n name: 'map_site',\n description:\n 'Discover a site\\'s URLs (from sitemap.xml, falling back to on-page links) without reading them. Fast and cheap — use it to plan which pages to read or crawl next.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The site URL to map.',\n },\n limit: {\n type: 'number',\n description: 'Max URLs to return (default 100, max 1000).',\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'extract_data',\n description:\n 'Extract the structured data a page already declares — JSON-LD (schema.org), OpenGraph cards, and meta tags — plus the AIO trust score. Deterministic, no AI: returns only data present in the page. Use for fast, reliable facts (prices, products, articles) when the site publishes structured data.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to extract structured data from.',\n },\n },\n required: ['url'],\n },\n },\n ],\n}));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'read_url': {\n const validated = readUrlInputSchema.parse(args ?? {});\n return await readUrl(validated);\n }\n case 'score_url': {\n const validated = scoreUrlInputSchema.parse(args ?? {});\n return await scoreUrl(validated);\n }\n case 'read_and_score': {\n const validated = readAndScoreInputSchema.parse(args ?? {});\n return await readAndScore(validated);\n }\n case 'batch': {\n const validated = batchInputSchema.parse(args ?? {});\n return await batchRead(validated);\n }\n case 'map_site': {\n const validated = mapInputSchema.parse(args ?? {});\n return await mapSite(validated);\n }\n case 'extract_data': {\n const validated = extractInputSchema.parse(args ?? {});\n return await extractData(validated);\n }\n default:\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);\n }\n } catch (error) {\n if (error instanceof McpError) throw error;\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: `Tool '${name}' failed: ${message}` }],\n isError: true,\n };\n }\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // stderr (not stdout) — stdout is reserved for MCP protocol frames\n console.error(`[onto-mcp] v${version} listening on stdio`);\n}\n\nmain().catch((err) => {\n console.error('[onto-mcp] fatal:', err);\n process.exit(1);\n});\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadResponse } from '../lib/types.js';\n\nexport const readUrlInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadUrlInput = z.infer<typeof readUrlInputSchema>;\n\nexport async function readUrl(input: ReadUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadResponse>('/v1/read', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const metaLines = [\n `- URL: ${result.url}`,\n `- Title: ${result.metadata.title || '(none)'}`,\n `- Original size: ${result.stats.raw_html_size_kb} KB`,\n `- Cleaned size: ${result.stats.markdown_size_kb} KB`,\n `- Reduction: ${result.stats.reduction_percent}%`,\n `- Extraction time: ${result.stats.extraction_time_ms} ms`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n ].join('\\n');\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n {\n type: 'text' as const,\n text: `\\n\\n---\\n\\n**Source metadata (from Onto):**\\n${metaLines}\\n\\n${ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n })}`,\n },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","export const version = '1.3.0';\n","/* Thin HTTP wrapper around the Onto Read API. Reads ONTO_API_KEY at call time\n * (not module-load) so server.ts can fail with a clean error message first. */\n\nimport { version as PACKAGE_VERSION } from './version.js';\nimport type { ApiErrorBody } from './types.js';\n\nconst DEFAULT_BASE = 'https://api.buildonto.dev';\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport class OntoApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OntoApiError';\n }\n}\n\ninterface CallOptions {\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport async function callOntoApi<T>(endpoint: string, options: CallOptions): Promise<T> {\n const apiKey = process.env.ONTO_API_KEY;\n if (!apiKey) {\n throw new OntoApiError(\n 'ONTO_API_KEY environment variable is not set. Get a key at https://app.buildonto.dev/read/keys',\n 0,\n 'NO_API_KEY',\n );\n }\n\n const base = process.env.ONTO_API_BASE ?? DEFAULT_BASE;\n const url = `${base}${endpoint}`;\n\n const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeout])\n : timeout;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `@ontosdk/mcp/${PACKAGE_VERSION}`,\n },\n body: JSON.stringify(options.body),\n signal,\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new OntoApiError(\n `Onto API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s. The target site may be slow or unreachable.`,\n 0,\n 'TIMEOUT',\n );\n }\n throw new OntoApiError(\n `Failed to reach Onto API at ${base}: ${(err as Error).message}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n\n const rawBody = await response.text();\n\n if (!response.ok) {\n let parsed: Partial<ApiErrorBody> = {};\n try {\n parsed = JSON.parse(rawBody) as Partial<ApiErrorBody>;\n } catch {\n // Body wasn't JSON; fall through with status-code-only error\n }\n\n const message = humanizeError(response.status, parsed);\n throw new OntoApiError(message, response.status, parsed.error);\n }\n\n try {\n return JSON.parse(rawBody) as T;\n } catch (err) {\n throw new OntoApiError(\n `Onto API returned invalid JSON: ${(err as Error).message}`,\n response.status,\n 'INVALID_RESPONSE',\n );\n }\n}\n\nfunction humanizeError(status: number, body: Partial<ApiErrorBody>): string {\n if (status === 401) {\n return 'Invalid Onto API key. Verify your key at https://app.buildonto.dev/read/keys';\n }\n if (status === 402) {\n return (\n body.message ??\n 'Monthly plan quota exceeded and credit balance is empty. Top up credits at https://app.buildonto.dev/read/billing'\n );\n }\n if (status === 403) {\n if (body.error === 'ROBOTS_BLOCKED') {\n return body.message ?? 'The target site blocks AI crawlers via robots.txt.';\n }\n return body.message ?? 'Forbidden.';\n }\n if (status === 429) {\n return (\n body.message ??\n 'Onto API rate limit exceeded. Upgrade your tier at https://app.buildonto.dev/read/billing or wait for the monthly reset.'\n );\n }\n if (status >= 500) {\n return body.message ?? `Onto API server error (${status}). Try again in a moment.`;\n }\n return body.message ?? `Onto API returned ${status}.`;\n}\n","/* Format errors as MCP tool responses. We don't throw McpError for\n * tool-call failures — the AI host shows tool errors to the user as\n * unhelpful internal-error messages. Returning isError: true with a\n * text body lets the model see what went wrong and recover. */\n\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { OntoApiError } from './api-client.js';\n\nexport function formatToolError(error: unknown): CallToolResult {\n if (error instanceof OntoApiError) {\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n {\n type: 'text',\n text: `Onto MCP error: ${message}\\n\\nTroubleshooting:\\n- Verify ONTO_API_KEY is set and valid (https://app.buildonto.dev/read/keys)\\n- Check the target URL is publicly accessible\\n- Check your monthly quota at https://app.buildonto.dev/read/usage`,\n },\n ],\n isError: true,\n };\n}\n","/* The \"Onto report\" — a single branded summary line appended to the end of\n * every tool response. This is a deliberate growth surface: every agent call\n * leaves Onto's value (reduction, tokens saved, trust score) visible in the\n * host's context, and stamps the brand. Keep it to ONE line, always the same\n * shape so it becomes recognizable.\n *\n * Token estimate uses 4 bytes/token — the same heuristic the dashboard uses\n * for its \"tokens saved\" stat, so numbers stay consistent across surfaces.\n */\n\nconst BYTES_PER_TOKEN = 4;\n\nexport interface OntoReportInput {\n /** Raw HTML size in KB (before Onto cleaned it). */\n rawKb?: number;\n /** Clean Markdown size in KB (what the agent actually consumes). */\n cleanKb?: number;\n /** Percentage shrink from raw → clean. */\n reductionPercent?: number;\n /** AIO readability score 0–100, when available. */\n aioScore?: number;\n /** Hallucination-risk band, when available. */\n risk?: 'low' | 'medium' | 'high';\n}\n\n/** Estimated input tokens saved by serving Markdown instead of raw HTML. */\nexport function estimateTokensSaved(rawKb: number, cleanKb: number): number {\n const savedBytes = Math.max(0, (rawKb - cleanKb) * 1024);\n return Math.round(savedBytes / BYTES_PER_TOKEN);\n}\n\n/** Compact, human-friendly token count: 1234 → \"1.2K\", 199000 → \"199K\". */\nfunction compact(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 10_000) return `${Math.round(n / 1_000)}K`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return `${n}`;\n}\n\n/**\n * Build the single-line Onto report. Only the fields that are present get\n * rendered, so the same helper works for read_url (no score) and\n * read_and_score / score_url (with score).\n */\nexport function ontoReport(input: OntoReportInput): string {\n const parts: string[] = [];\n\n if (input.rawKb != null && input.cleanKb != null) {\n parts.push(`${input.rawKb}KB → ${input.cleanKb}KB`);\n if (input.reductionPercent != null) parts.push(`${input.reductionPercent}% smaller`);\n parts.push(`~${compact(estimateTokensSaved(input.rawKb, input.cleanKb))} tokens saved`);\n } else if (input.reductionPercent != null) {\n parts.push(`${input.reductionPercent}% smaller`);\n }\n\n if (input.aioScore != null) {\n parts.push(`AIO ${input.aioScore}/100${input.risk ? ` (${input.risk} risk)` : ''}`);\n }\n\n return `⚡ Onto · ${parts.join(' · ')} · buildonto.dev`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ScoreResponse, Recommendation } from '../lib/types.js';\n\nexport const scoreUrlInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ScoreUrlInput = z.infer<typeof scoreUrlInputSchema>;\n\nexport async function scoreUrl(input: ScoreUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ScoreResponse>('/v1/score', {\n body: { url: input.url },\n });\n\n return {\n content: [{ type: 'text' as const, text: formatScoreSummary(result) }],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nexport function formatScoreSummary(result: ScoreResponse): string {\n const lines: string[] = [\n `**AIO Score:** ${result.aio_score}/100 (${result.grade})`,\n `**Hallucination risk:** ${result.hallucination_risk}`,\n `**URL:** ${result.url}`,\n '',\n ];\n\n if (result.benefits.length > 0) {\n lines.push('**What works well:**');\n for (const item of result.benefits) lines.push(`- ${item}`);\n lines.push('');\n }\n\n if (result.penalties.length > 0) {\n lines.push('**What hurts AI readability:**');\n for (const item of result.penalties) lines.push(`- ${item}`);\n lines.push('');\n }\n\n const insightEntries = Object.entries(result.insights ?? {});\n if (insightEntries.length > 0) {\n lines.push('**Insights:**');\n for (const [key, value] of insightEntries) {\n lines.push(`- ${key}: ${value ? 'yes' : 'no'}`);\n }\n lines.push('');\n }\n\n if (result.recommendations.length > 0) {\n lines.push('**Recommendations:**');\n for (const rec of result.recommendations) {\n lines.push(describeRecommendation(rec));\n }\n lines.push('');\n }\n\n lines.push('**Stats:**');\n lines.push(`- Raw size: ${result.stats.raw_size}`);\n lines.push(`- Efficiency: ${result.stats.efficiency}`);\n lines.push(`- Extraction time: ${result.stats.extraction_time_ms} ms`);\n lines.push('');\n lines.push(ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }));\n\n return lines.join('\\n');\n}\n\nfunction describeRecommendation(rec: Recommendation): string {\n if (typeof rec === 'string') return `- ${rec}`;\n if (rec.title) {\n const head = rec.priority ? `**${rec.title}** _(priority: ${rec.priority})_` : `**${rec.title}**`;\n return rec.description ? `- ${head} — ${rec.description}` : `- ${head}`;\n }\n if (rec.description) return `- ${rec.description}`;\n return `- ${JSON.stringify(rec)}`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadAndScoreResponse } from '../lib/types.js';\n\nexport const readAndScoreInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadAndScoreInput = z.infer<typeof readAndScoreInputSchema>;\n\nexport async function readAndScore(input: ReadAndScoreInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadAndScoreResponse>('/v1/read-and-score', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const trustHint = trustLine(result.aio_score, result.hallucination_risk);\n const summaryLines = [\n `**Source quality assessment (from Onto):**`,\n `- AIO Score: ${result.aio_score}/100 (${result.grade})`,\n `- Hallucination risk: ${result.hallucination_risk}`,\n `- Reduction: ${result.stats.reduction_percent}% (${result.stats.raw_html_size_kb} KB → ${result.stats.markdown_size_kb} KB)`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n '',\n trustHint,\n '',\n ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n aioScore: result.aio_score,\n risk: result.hallucination_risk,\n }),\n ];\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n { type: 'text' as const, text: `\\n\\n---\\n\\n${summaryLines.join('\\n')}` },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nfunction trustLine(score: number, risk: 'low' | 'medium' | 'high'): string {\n if (risk === 'high' || score < 40) {\n return 'Trust signal: low — this source is poorly structured for AI consumption. Verify any facts before relying on them.';\n }\n if (risk === 'medium' || score < 70) {\n return 'Trust signal: medium — source is partially AI-readable. Cross-check critical claims.';\n }\n return 'Trust signal: high — source is well-structured for AI consumption.';\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { BatchResponse, BatchResult } from '../lib/types.js';\n\nexport const batchInputSchema = z\n .object({\n urls: z.array(z.string().url()).min(1).max(50).optional(),\n site: z.string().url().optional(),\n mode: z.enum(['read', 'read-and-score', 'extract']).optional(),\n limit: z.number().int().min(1).max(50).optional(),\n })\n .refine((v) => (v.urls && v.urls.length > 0) || v.site, {\n message: 'Provide either \"urls\" (array) or \"site\" (string).',\n });\n\nexport type BatchInput = z.infer<typeof batchInputSchema>;\n\nfunction renderResult(r: BatchResult): string {\n if (!r.ok) {\n return `### ${r.url}\\n_skipped — ${r.error?.code}: ${r.error?.message}_`;\n }\n const head = [`### ${r.title || r.url}`, r.url];\n if (r.aio_score != null) {\n head.push(`AIO ${r.aio_score}/100 (${r.grade}, ${r.hallucination_risk} risk)`);\n }\n if (r.reduction_percent != null) head.push(`${r.reduction_percent}% smaller`);\n const lines = [head.join(' · ')];\n\n if (r.structured) {\n lines.push('', `JSON-LD: ${r.counts?.json_ld ?? 0} · OG: ${r.counts?.open_graph ?? 0} · meta: ${r.counts?.meta ?? 0}`);\n if (r.structured.jsonLd.length > 0) {\n lines.push('```json', JSON.stringify(r.structured.jsonLd, null, 2), '```');\n }\n } else if (r.markdown) {\n lines.push('', r.markdown);\n }\n return lines.join('\\n');\n}\n\nexport async function batchRead(input: BatchInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<BatchResponse>('/v1/batch', {\n body: { urls: input.urls, site: input.site, mode: input.mode, limit: input.limit },\n });\n\n const header =\n result.source === 'site'\n ? `# Batch ${result.mode} — site discovery`\n : `# Batch ${result.mode} — ${result.requested} URL(s)`;\n\n const lines = [\n header,\n `${result.succeeded}/${result.requested} succeeded.`,\n '',\n ...result.results.map(renderResult).flatMap((block) => [block, '']),\n `⚡ Onto · ${result.succeeded}/${result.requested} URLs in one call · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { MapResponse } from '../lib/types.js';\n\nexport const mapInputSchema = z.object({\n url: z.string().url(),\n limit: z.number().int().min(1).max(1000).optional(),\n});\n\nexport type MapInput = z.infer<typeof mapInputSchema>;\n\nexport async function mapSite(input: MapInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<MapResponse>('/v1/map', {\n body: { url: input.url, limit: input.limit },\n });\n\n const lines: string[] = [\n `# Sitemap for ${result.url}`,\n `Discovered ${result.count} URL(s) via ${result.source}.`,\n '',\n ...result.urls.map((u) => `- ${u}`),\n '',\n `⚡ Onto · ${result.count} URLs mapped (${result.source}) · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ExtractResponse } from '../lib/types.js';\n\nexport const extractInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ExtractInput = z.infer<typeof extractInputSchema>;\n\nexport async function extractData(input: ExtractInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ExtractResponse>('/v1/extract', {\n body: { url: input.url },\n });\n\n const og = Object.entries(result.structured.openGraph);\n const meta = Object.entries(result.structured.meta);\n\n const lines: string[] = [\n `# Structured data for ${result.url}`,\n result.title ? `Title: ${result.title}` : '',\n `Found ${result.counts.json_ld} JSON-LD object(s), ${result.counts.open_graph} OpenGraph tag(s), ${result.counts.meta} meta tag(s).`,\n '',\n '## JSON-LD',\n result.structured.jsonLd.length > 0\n ? '```json\\n' + JSON.stringify(result.structured.jsonLd, null, 2) + '\\n```'\n : '(none declared)',\n '',\n '## OpenGraph',\n og.length > 0 ? og.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n '## Meta',\n meta.length > 0 ? meta.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }),\n ].filter((line) => line !== '');\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/tools/read.ts","../src/lib/version.ts","../src/lib/api-client.ts","../src/lib/errors.ts","../src/lib/report.ts","../src/tools/score.ts","../src/tools/read-and-score.ts","../src/tools/batch.ts","../src/tools/map.ts","../src/tools/extract.ts"],"sourcesContent":["/* Onto MCP Server — exposes the Onto Read API as Model Context Protocol tools.\n *\n * Tools: read_url, score_url, read_and_score.\n * Reads ONTO_API_KEY from env. Defaults base URL to https://api.buildonto.dev.\n *\n * Install in Claude Code:\n * \"mcpServers\": {\n * \"onto\": {\n * \"command\": \"npx\",\n * \"args\": [\"-y\", \"@ontosdk/mcp\"],\n * \"env\": { \"ONTO_API_KEY\": \"onto_sk_live_...\" }\n * }\n * }\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ErrorCode,\n McpError,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { readUrl, readUrlInputSchema } from './tools/read.js';\nimport { scoreUrl, scoreUrlInputSchema } from './tools/score.js';\nimport { readAndScore, readAndScoreInputSchema } from './tools/read-and-score.js';\nimport { batchRead, batchInputSchema } from './tools/batch.js';\nimport { mapSite, mapInputSchema } from './tools/map.js';\nimport { extractData, extractInputSchema } from './tools/extract.js';\nimport { version } from './lib/version.js';\n\nif (!process.env.ONTO_API_KEY) {\n console.error('[onto-mcp] ONTO_API_KEY environment variable is required.');\n console.error('[onto-mcp] Create a key at https://app.buildonto.dev/read/keys');\n process.exit(1);\n}\n\nconst server = new Server(\n { name: 'onto', version },\n { capabilities: { tools: {} } },\n);\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'read_url',\n description:\n 'Read any URL and return clean, agent-ready Markdown. Strips HTML noise, preserves semantic content, and returns content optimized for AI consumption. Use this when you need to extract content from a website for an AI agent to process.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to read. Must be a publicly accessible HTTP or HTTPS URL.',\n },\n fresh: {\n type: 'boolean',\n description: 'If true, bypass cache and fetch fresh content. Default false.',\n default: false,\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'score_url',\n description:\n 'Get the AIO (AI-readability) score for any URL. Returns a 0-100 score plus a list of penalties, benefits, and recommendations describing why the source is or is not well-suited for AI consumption. Use this to evaluate source quality before relying on it.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to score.',\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'read_and_score',\n description:\n 'Read any URL and return both clean Markdown AND the AIO accuracy score in one call. The recommended default for most AI workflows — gives both content and quality assessment together, so the AI agent can decide how much to trust the content.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to read and score.',\n },\n fresh: {\n type: 'boolean',\n description: 'If true, bypass cache and fetch fresh content. Default false.',\n default: false,\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'batch',\n description:\n 'Process many URLs in ONE call (billed as one request) — so you do not spend a credit per URL. Give either \"urls\" (an explicit list, up to 50) or \"site\" (a base URL whose pages are auto-discovered via sitemap). \"mode\" picks what to do per URL: \"read\" (Markdown), \"read-and-score\" (Markdown + AIO trust score, default), or \"extract\" (JSON-LD + OpenGraph + meta + score). Use this for full-site reads or bulk URL processing.',\n inputSchema: {\n type: 'object',\n properties: {\n urls: {\n type: 'array',\n items: { type: 'string' },\n description: 'Explicit list of URLs to process (up to 50). Use this OR \"site\".',\n },\n site: {\n type: 'string',\n description: 'Base URL of a site whose pages will be auto-discovered. Use this OR \"urls\".',\n },\n mode: {\n type: 'string',\n enum: ['read', 'read-and-score', 'extract'],\n description: 'What to do per URL. Default \"read-and-score\".',\n },\n limit: {\n type: 'number',\n description: 'Site mode only: max pages to discover (default 25, max 50).',\n },\n },\n },\n },\n {\n name: 'map_site',\n description:\n 'Discover a site\\'s URLs (from sitemap.xml, falling back to on-page links) without reading them. Fast and cheap — use it to plan which pages to read or crawl next.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The site URL to map.',\n },\n limit: {\n type: 'number',\n description: 'Max URLs to return (default 100, max 1000).',\n },\n },\n required: ['url'],\n },\n },\n {\n name: 'extract_data',\n description:\n 'Extract the structured data a page already declares — JSON-LD (schema.org), OpenGraph cards, and meta tags — plus the AIO trust score. Deterministic, no AI: returns only data present in the page. Use for fast, reliable facts (prices, products, articles) when the site publishes structured data.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The URL to extract structured data from.',\n },\n },\n required: ['url'],\n },\n },\n ],\n}));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'read_url': {\n const validated = readUrlInputSchema.parse(args ?? {});\n return await readUrl(validated);\n }\n case 'score_url': {\n const validated = scoreUrlInputSchema.parse(args ?? {});\n return await scoreUrl(validated);\n }\n case 'read_and_score': {\n const validated = readAndScoreInputSchema.parse(args ?? {});\n return await readAndScore(validated);\n }\n case 'batch': {\n const validated = batchInputSchema.parse(args ?? {});\n return await batchRead(validated);\n }\n case 'map_site': {\n const validated = mapInputSchema.parse(args ?? {});\n return await mapSite(validated);\n }\n case 'extract_data': {\n const validated = extractInputSchema.parse(args ?? {});\n return await extractData(validated);\n }\n default:\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);\n }\n } catch (error) {\n if (error instanceof McpError) throw error;\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: 'text' as const, text: `Tool '${name}' failed: ${message}` }],\n isError: true,\n };\n }\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n // stderr (not stdout) — stdout is reserved for MCP protocol frames\n console.error(`[onto-mcp] v${version} listening on stdio`);\n}\n\nmain().catch((err) => {\n console.error('[onto-mcp] fatal:', err);\n process.exit(1);\n});\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadResponse } from '../lib/types.js';\n\nexport const readUrlInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadUrlInput = z.infer<typeof readUrlInputSchema>;\n\nexport async function readUrl(input: ReadUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadResponse>('/v1/read', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const metaLines = [\n `- URL: ${result.url}`,\n `- Title: ${result.metadata.title || '(none)'}`,\n `- Original size: ${result.stats.raw_html_size_kb} KB`,\n `- Cleaned size: ${result.stats.markdown_size_kb} KB`,\n `- Reduction: ${result.stats.reduction_percent}%`,\n `- Extraction time: ${result.stats.extraction_time_ms} ms`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n ].join('\\n');\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n {\n type: 'text' as const,\n text: `\\n\\n---\\n\\n**Source metadata (from Onto):**\\n${metaLines}\\n\\n${ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n })}`,\n },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","export const version = '1.3.1';\n","/* Thin HTTP wrapper around the Onto Read API. Reads ONTO_API_KEY at call time\n * (not module-load) so server.ts can fail with a clean error message first. */\n\nimport { version as PACKAGE_VERSION } from './version.js';\nimport type { ApiErrorBody } from './types.js';\n\nconst DEFAULT_BASE = 'https://api.buildonto.dev';\nconst REQUEST_TIMEOUT_MS = 15_000;\n\nexport class OntoApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'OntoApiError';\n }\n}\n\ninterface CallOptions {\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport async function callOntoApi<T>(endpoint: string, options: CallOptions): Promise<T> {\n const apiKey = process.env.ONTO_API_KEY;\n if (!apiKey) {\n throw new OntoApiError(\n 'ONTO_API_KEY environment variable is not set. Get a key at https://app.buildonto.dev/read/keys',\n 0,\n 'NO_API_KEY',\n );\n }\n\n const base = process.env.ONTO_API_BASE ?? DEFAULT_BASE;\n const url = `${base}${endpoint}`;\n\n const timeout = AbortSignal.timeout(REQUEST_TIMEOUT_MS);\n const signal = options.signal\n ? AbortSignal.any([options.signal, timeout])\n : timeout;\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n 'User-Agent': `@ontosdk/mcp/${PACKAGE_VERSION}`,\n },\n body: JSON.stringify(options.body),\n signal,\n });\n } catch (err) {\n if (err instanceof DOMException && err.name === 'TimeoutError') {\n throw new OntoApiError(\n `Onto API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s. The target site may be slow or unreachable.`,\n 0,\n 'TIMEOUT',\n );\n }\n throw new OntoApiError(\n `Failed to reach Onto API at ${base}: ${(err as Error).message}`,\n 0,\n 'NETWORK_ERROR',\n );\n }\n\n const rawBody = await response.text();\n\n if (!response.ok) {\n let parsed: Partial<ApiErrorBody> = {};\n try {\n parsed = JSON.parse(rawBody) as Partial<ApiErrorBody>;\n } catch {\n // Body wasn't JSON; fall through with status-code-only error\n }\n\n const message = humanizeError(response.status, parsed);\n throw new OntoApiError(message, response.status, parsed.error);\n }\n\n try {\n return JSON.parse(rawBody) as T;\n } catch (err) {\n throw new OntoApiError(\n `Onto API returned invalid JSON: ${(err as Error).message}`,\n response.status,\n 'INVALID_RESPONSE',\n );\n }\n}\n\nfunction humanizeError(status: number, body: Partial<ApiErrorBody>): string {\n if (status === 401) {\n return 'Invalid Onto API key. Verify your key at https://app.buildonto.dev/read/keys';\n }\n if (status === 402) {\n return (\n body.message ??\n 'Monthly plan quota exceeded and credit balance is empty. Top up credits at https://app.buildonto.dev/read/billing'\n );\n }\n if (status === 403) {\n if (body.error === 'ROBOTS_BLOCKED') {\n return body.message ?? 'The target site blocks AI crawlers via robots.txt.';\n }\n return body.message ?? 'Forbidden.';\n }\n if (status === 429) {\n return (\n body.message ??\n 'Onto API rate limit exceeded. Upgrade your tier at https://app.buildonto.dev/read/billing or wait for the monthly reset.'\n );\n }\n if (status >= 500) {\n return body.message ?? `Onto API server error (${status}). Try again in a moment.`;\n }\n return body.message ?? `Onto API returned ${status}.`;\n}\n","/* Format errors as MCP tool responses. We don't throw McpError for\n * tool-call failures — the AI host shows tool errors to the user as\n * unhelpful internal-error messages. Returning isError: true with a\n * text body lets the model see what went wrong and recover. */\n\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { OntoApiError } from './api-client.js';\n\nexport function formatToolError(error: unknown): CallToolResult {\n if (error instanceof OntoApiError) {\n return {\n content: [{ type: 'text', text: error.message }],\n isError: true,\n };\n }\n\n const message = error instanceof Error ? error.message : String(error);\n return {\n content: [\n {\n type: 'text',\n text: `Onto MCP error: ${message}\\n\\nTroubleshooting:\\n- Verify ONTO_API_KEY is set and valid (https://app.buildonto.dev/read/keys)\\n- Check the target URL is publicly accessible\\n- Check your monthly quota at https://app.buildonto.dev/read/usage`,\n },\n ],\n isError: true,\n };\n}\n","/* The \"Onto report\" — a single branded summary line appended to the end of\n * every tool response. This is a deliberate growth surface: every agent call\n * leaves Onto's value (reduction, tokens saved, trust score) visible in the\n * host's context, and stamps the brand. Keep it to ONE line, always the same\n * shape so it becomes recognizable.\n *\n * Token estimate uses 4 bytes/token — the same heuristic the dashboard uses\n * for its \"tokens saved\" stat, so numbers stay consistent across surfaces.\n */\n\nconst BYTES_PER_TOKEN = 4;\n\nexport interface OntoReportInput {\n /** Raw HTML size in KB (before Onto cleaned it). */\n rawKb?: number;\n /** Clean Markdown size in KB (what the agent actually consumes). */\n cleanKb?: number;\n /** Percentage shrink from raw → clean. */\n reductionPercent?: number;\n /** AIO readability score 0–100, when available. */\n aioScore?: number;\n /** Hallucination-risk band, when available. */\n risk?: 'low' | 'medium' | 'high';\n}\n\n/** Estimated input tokens saved by serving Markdown instead of raw HTML. */\nexport function estimateTokensSaved(rawKb: number, cleanKb: number): number {\n const savedBytes = Math.max(0, (rawKb - cleanKb) * 1024);\n return Math.round(savedBytes / BYTES_PER_TOKEN);\n}\n\n/** Compact, human-friendly token count: 1234 → \"1.2K\", 199000 → \"199K\". */\nfunction compact(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 10_000) return `${Math.round(n / 1_000)}K`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return `${n}`;\n}\n\n/**\n * Build the single-line Onto report. Only the fields that are present get\n * rendered, so the same helper works for read_url (no score) and\n * read_and_score / score_url (with score).\n */\nexport function ontoReport(input: OntoReportInput): string {\n const parts: string[] = [];\n\n if (input.rawKb != null && input.cleanKb != null) {\n parts.push(`${input.rawKb}KB → ${input.cleanKb}KB`);\n if (input.reductionPercent != null) parts.push(`${input.reductionPercent}% smaller`);\n parts.push(`~${compact(estimateTokensSaved(input.rawKb, input.cleanKb))} tokens saved`);\n } else if (input.reductionPercent != null) {\n parts.push(`${input.reductionPercent}% smaller`);\n }\n\n if (input.aioScore != null) {\n parts.push(`AIO ${input.aioScore}/100${input.risk ? ` (${input.risk} risk)` : ''}`);\n }\n\n return `⚡ Onto · ${parts.join(' · ')} · buildonto.dev`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ScoreResponse, Recommendation } from '../lib/types.js';\n\nexport const scoreUrlInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ScoreUrlInput = z.infer<typeof scoreUrlInputSchema>;\n\nexport async function scoreUrl(input: ScoreUrlInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ScoreResponse>('/v1/score', {\n body: { url: input.url },\n });\n\n return {\n content: [{ type: 'text' as const, text: formatScoreSummary(result) }],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nexport function formatScoreSummary(result: ScoreResponse): string {\n const lines: string[] = [\n `**AIO Score:** ${result.aio_score}/100 (${result.grade})`,\n `**Hallucination risk:** ${result.hallucination_risk}`,\n `**URL:** ${result.url}`,\n '',\n ];\n\n if (result.benefits.length > 0) {\n lines.push('**What works well:**');\n for (const item of result.benefits) lines.push(`- ${item}`);\n lines.push('');\n }\n\n if (result.penalties.length > 0) {\n lines.push('**What hurts AI readability:**');\n for (const item of result.penalties) lines.push(`- ${item}`);\n lines.push('');\n }\n\n const insightEntries = Object.entries(result.insights ?? {});\n if (insightEntries.length > 0) {\n lines.push('**Insights:**');\n for (const [key, value] of insightEntries) {\n lines.push(`- ${key}: ${value ? 'yes' : 'no'}`);\n }\n lines.push('');\n }\n\n if (result.recommendations.length > 0) {\n lines.push('**Recommendations:**');\n for (const rec of result.recommendations) {\n lines.push(describeRecommendation(rec));\n }\n lines.push('');\n }\n\n lines.push('**Stats:**');\n lines.push(`- Raw size: ${result.stats.raw_size}`);\n lines.push(`- Efficiency: ${result.stats.efficiency}`);\n lines.push(`- Extraction time: ${result.stats.extraction_time_ms} ms`);\n lines.push('');\n lines.push(ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }));\n\n return lines.join('\\n');\n}\n\nfunction describeRecommendation(rec: Recommendation): string {\n if (typeof rec === 'string') return `- ${rec}`;\n if (rec.title) {\n const head = rec.priority ? `**${rec.title}** _(priority: ${rec.priority})_` : `**${rec.title}**`;\n return rec.description ? `- ${head} — ${rec.description}` : `- ${head}`;\n }\n if (rec.description) return `- ${rec.description}`;\n return `- ${JSON.stringify(rec)}`;\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ReadAndScoreResponse } from '../lib/types.js';\n\nexport const readAndScoreInputSchema = z.object({\n url: z.string().url(),\n fresh: z.boolean().optional().default(false),\n});\n\nexport type ReadAndScoreInput = z.infer<typeof readAndScoreInputSchema>;\n\nexport async function readAndScore(input: ReadAndScoreInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ReadAndScoreResponse>('/v1/read-and-score', {\n body: { url: input.url, fresh: input.fresh },\n });\n\n const trustHint = trustLine(result.aio_score, result.hallucination_risk);\n const summaryLines = [\n `**Source quality assessment (from Onto):**`,\n `- AIO Score: ${result.aio_score}/100 (${result.grade})`,\n `- Hallucination risk: ${result.hallucination_risk}`,\n `- Reduction: ${result.stats.reduction_percent}% (${result.stats.raw_html_size_kb} KB → ${result.stats.markdown_size_kb} KB)`,\n `- Cache: ${result.cache.hit ? 'HIT' : 'MISS'}`,\n '',\n trustHint,\n '',\n ontoReport({\n rawKb: result.stats.raw_html_size_kb,\n cleanKb: result.stats.markdown_size_kb,\n reductionPercent: result.stats.reduction_percent,\n aioScore: result.aio_score,\n risk: result.hallucination_risk,\n }),\n ];\n\n return {\n content: [\n { type: 'text' as const, text: result.markdown },\n { type: 'text' as const, text: `\\n\\n---\\n\\n${summaryLines.join('\\n')}` },\n ],\n };\n } catch (error) {\n return formatToolError(error);\n }\n}\n\nfunction trustLine(score: number, risk: 'low' | 'medium' | 'high'): string {\n if (risk === 'high' || score < 40) {\n return 'Trust signal: low — this source is poorly structured for AI consumption. Verify any facts before relying on them.';\n }\n if (risk === 'medium' || score < 70) {\n return 'Trust signal: medium — source is partially AI-readable. Cross-check critical claims.';\n }\n return 'Trust signal: high — source is well-structured for AI consumption.';\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { BatchResponse, BatchResult } from '../lib/types.js';\n\nexport const batchInputSchema = z\n .object({\n urls: z.array(z.string().url()).min(1).max(50).optional(),\n site: z.string().url().optional(),\n mode: z.enum(['read', 'read-and-score', 'extract']).optional(),\n limit: z.number().int().min(1).max(50).optional(),\n })\n .refine((v) => (v.urls && v.urls.length > 0) || v.site, {\n message: 'Provide either \"urls\" (array) or \"site\" (string).',\n });\n\nexport type BatchInput = z.infer<typeof batchInputSchema>;\n\nfunction renderResult(r: BatchResult): string {\n if (!r.ok) {\n return `### ${r.url}\\n_skipped — ${r.error?.code}: ${r.error?.message}_`;\n }\n const head = [`### ${r.title || r.url}`, r.url];\n if (r.aio_score != null) {\n head.push(`AIO ${r.aio_score}/100 (${r.grade}, ${r.hallucination_risk} risk)`);\n }\n if (r.reduction_percent != null) head.push(`${r.reduction_percent}% smaller`);\n const lines = [head.join(' · ')];\n\n if (r.structured) {\n lines.push('', `JSON-LD: ${r.counts?.json_ld ?? 0} · OG: ${r.counts?.open_graph ?? 0} · meta: ${r.counts?.meta ?? 0}`);\n if (r.structured.jsonLd.length > 0) {\n lines.push('```json', JSON.stringify(r.structured.jsonLd, null, 2), '```');\n }\n } else if (r.markdown) {\n lines.push('', r.markdown);\n }\n return lines.join('\\n');\n}\n\nexport async function batchRead(input: BatchInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<BatchResponse>('/v1/batch', {\n body: { urls: input.urls, site: input.site, mode: input.mode, limit: input.limit },\n });\n\n const header =\n result.source === 'site'\n ? `# Batch ${result.mode} — site discovery`\n : `# Batch ${result.mode} — ${result.requested} URL(s)`;\n\n const lines = [\n header,\n `${result.succeeded}/${result.requested} succeeded.`,\n '',\n ...result.results.map(renderResult).flatMap((block) => [block, '']),\n `⚡ Onto · ${result.succeeded}/${result.requested} URLs in one call · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport type { MapResponse } from '../lib/types.js';\n\nexport const mapInputSchema = z.object({\n url: z.string().url(),\n limit: z.number().int().min(1).max(1000).optional(),\n});\n\nexport type MapInput = z.infer<typeof mapInputSchema>;\n\nexport async function mapSite(input: MapInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<MapResponse>('/v1/map', {\n body: { url: input.url, limit: input.limit },\n });\n\n const lines: string[] = [\n `# Sitemap for ${result.url}`,\n `Discovered ${result.count} URL(s) via ${result.source}.`,\n '',\n ...result.urls.map((u) => `- ${u}`),\n '',\n `⚡ Onto · ${result.count} URLs mapped (${result.source}) · buildonto.dev`,\n ];\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n","import { z } from 'zod';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { callOntoApi } from '../lib/api-client.js';\nimport { formatToolError } from '../lib/errors.js';\nimport { ontoReport } from '../lib/report.js';\nimport type { ExtractResponse } from '../lib/types.js';\n\nexport const extractInputSchema = z.object({\n url: z.string().url(),\n});\n\nexport type ExtractInput = z.infer<typeof extractInputSchema>;\n\nexport async function extractData(input: ExtractInput): Promise<CallToolResult> {\n try {\n const result = await callOntoApi<ExtractResponse>('/v1/extract', {\n body: { url: input.url },\n });\n\n const og = Object.entries(result.structured.openGraph);\n const meta = Object.entries(result.structured.meta);\n\n const lines: string[] = [\n `# Structured data for ${result.url}`,\n result.title ? `Title: ${result.title}` : '',\n `Found ${result.counts.json_ld} JSON-LD object(s), ${result.counts.open_graph} OpenGraph tag(s), ${result.counts.meta} meta tag(s).`,\n '',\n '## JSON-LD',\n result.structured.jsonLd.length > 0\n ? '```json\\n' + JSON.stringify(result.structured.jsonLd, null, 2) + '\\n```'\n : '(none declared)',\n '',\n '## OpenGraph',\n og.length > 0 ? og.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n '## Meta',\n meta.length > 0 ? meta.map(([k, v]) => `- ${k}: ${v}`).join('\\n') : '(none)',\n '',\n ontoReport({ aioScore: result.aio_score, risk: result.hallucination_risk }),\n ].filter((line) => line !== '');\n\n return { content: [{ type: 'text' as const, text: lines.join('\\n') }] };\n } catch (error) {\n return formatToolError(error);\n }\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontosdk/mcp",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "mcpName": "io.github.ravixalgorithm/onto",
5
5
  "description": "Official Onto MCP server — clean Markdown and AIO scoring for any URL, available as MCP tools for Claude Code, Cursor, and any MCP client.",
6
6
  "type": "module",