@refkit/mcp 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@ Point any MCP client at:
10
10
  npx -y @refkit/mcp
11
11
  ```
12
12
 
13
- It boots with the keyless sources (Met, Art Institute of Chicago, Wikimedia Commons, Openverse + audio, Project Gutenberg, PoetryDB) and auto-adds any BYOK source whose key is in the environment. Each key is read as a unified `REFKIT_<PROVIDER>_KEY` name first, falling back to the provider's legacy name (both are honored indefinitely):
13
+ It boots with the keyless sources (Met, Art Institute of Chicago, Wikimedia Commons, Openverse + audio, Project Gutenberg, PoetryDB, Nailbook — Japanese nail-art, discovery-class `license: 'unknown'`, best queried with Japanese tag words) and auto-adds any BYOK source whose key is in the environment. Each key is read as a unified `REFKIT_<PROVIDER>_KEY` name first, falling back to the provider's legacy name (both are honored indefinitely):
14
14
 
15
15
  ```bash
16
16
  REFKIT_UNSPLASH_KEY=… REFKIT_PEXELS_KEY=… REFKIT_PIXABAY_KEY=… REFKIT_FLICKR_KEY=… REFKIT_SMITHSONIAN_KEY=… REFKIT_BRAVE_KEY=… npx -y @refkit/mcp
@@ -19,6 +19,8 @@ REFKIT_UNSPLASH_KEY=… REFKIT_PEXELS_KEY=… REFKIT_PIXABAY_KEY=… REFKIT_FLIC
19
19
  UNSPLASH_KEY=… PEXELS_KEY=… PIXABAY_KEY=… FLICKR_KEY=… SI_KEY=… BRAVE_TOKEN=… npx -y @refkit/mcp
20
20
  ```
21
21
 
22
+ If your MCP client clamps tool-output strings, `REFKIT_MAX_CURSOR_SEEN` shrinks the load-more cursor: it caps how many already-returned keys `nextCursor` remembers (default 500 ≈ 2.7k chars; `REFKIT_MAX_CURSOR_SEEN=200` ≈ 1.1k). A lower cap only risks re-showing results from that many batches ago on very deep pagination.
23
+
22
24
  Example MCP client config:
23
25
 
24
26
  ```json
@@ -6,6 +6,7 @@ import { z } from "zod";
6
6
  import { LICENSE_IDS, INTENTS, evaluateUse, buildAttribution, ccVersionFor, lexicalReranker } from "@refkit/core";
7
7
  var MODALITIES = ["image", "video", "audio", "text"];
8
8
  var ORIENTATIONS = ["landscape", "portrait", "square"];
9
+ var BASE_MEDIA_KINDS = ["photo", "illustration", "vector", "film", "animation"];
9
10
  var SEARCH_CONTROL_KEYS = [
10
11
  "orientation",
11
12
  "color",
@@ -31,33 +32,35 @@ var filtersSchema = z.object({
31
32
  language: z.string().optional()
32
33
  });
33
34
  var searchControlKeySchema = z.enum(SEARCH_CONTROL_KEYS);
34
- var searchControlsSchema = z.object({
35
- orientation: z.enum(ORIENTATIONS).optional(),
36
- color: z.string().optional(),
37
- language: z.string().optional(),
38
- sort: z.enum(["relevance", "latest", "popular", "interesting"]).optional(),
39
- safety: z.enum(["strict", "moderate", "off"]).optional(),
40
- license: z.object({
41
- commercial: z.boolean().optional(),
42
- modification: z.boolean().optional(),
43
- allowUnknown: z.boolean().optional()
44
- }).optional(),
45
- media: z.object({
46
- kind: z.enum(["photo", "illustration", "vector", "film", "animation"]).optional(),
47
- size: z.enum(["small", "medium", "large"]).optional(),
48
- minWidth: z.number().int().nonnegative().optional(),
49
- minHeight: z.number().int().nonnegative().optional(),
50
- duration: z.enum(["short", "medium", "long"]).optional()
51
- }).optional(),
52
- creator: z.object({
53
- id: z.string().optional(),
54
- name: z.string().optional()
55
- }).optional(),
56
- text: z.object({
57
- copyright: z.enum(["public-domain", "copyrighted", "any"]).optional()
58
- }).optional(),
59
- page: z.number().int().positive().optional()
60
- });
35
+ function buildSearchControlsSchema(kindValues) {
36
+ return z.object({
37
+ orientation: z.enum(ORIENTATIONS).optional(),
38
+ color: z.string().optional(),
39
+ language: z.string().optional(),
40
+ sort: z.enum(["relevance", "latest", "popular", "interesting"]).optional(),
41
+ safety: z.enum(["strict", "moderate", "off"]).optional(),
42
+ license: z.object({
43
+ commercial: z.boolean().optional(),
44
+ modification: z.boolean().optional(),
45
+ allowUnknown: z.boolean().optional()
46
+ }).optional(),
47
+ media: z.object({
48
+ kind: z.enum(kindValues).optional(),
49
+ size: z.enum(["small", "medium", "large"]).optional(),
50
+ minWidth: z.number().int().nonnegative().optional(),
51
+ minHeight: z.number().int().nonnegative().optional(),
52
+ duration: z.enum(["short", "medium", "long"]).optional()
53
+ }).optional(),
54
+ creator: z.object({
55
+ id: z.string().optional(),
56
+ name: z.string().optional()
57
+ }).optional(),
58
+ text: z.object({
59
+ copyright: z.enum(["public-domain", "copyrighted", "any"]).optional()
60
+ }).optional(),
61
+ page: z.number().int().positive().optional()
62
+ });
63
+ }
61
64
  var providerOptionValueSchema = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]);
62
65
  var providerOptionsSchema = z.record(z.string(), z.record(z.string(), providerOptionValueSchema));
63
66
  var VERSION = (() => {
@@ -72,6 +75,7 @@ function toAgentRef(r, assessment) {
72
75
  id: r.id,
73
76
  title: r.title,
74
77
  modality: r.modality,
78
+ kind: r.kind,
75
79
  provider: r.source.providerId,
76
80
  canonicalUrl: r.canonicalUrl,
77
81
  license: r.rights.license,
@@ -93,6 +97,7 @@ var agentRefSchema = z.object({
93
97
  id: z.string(),
94
98
  title: z.string().optional(),
95
99
  modality: z.string(),
100
+ kind: z.string().optional().describe("fine-grained resource kind, e.g. photo / texture / ebook"),
96
101
  provider: z.string(),
97
102
  canonicalUrl: z.string(),
98
103
  license: z.string(),
@@ -121,7 +126,7 @@ var searchMetaSchema = z.object({
121
126
  returned: z.number().optional(),
122
127
  accepted: z.number().optional(),
123
128
  rejected: z.number().optional(),
124
- reason: z.enum(["unsupported-modality"]).optional(),
129
+ reason: z.enum(["unsupported-modality", "unsupported-kind", "not-selected"]).optional(),
125
130
  error: z.string().optional(),
126
131
  latencyMs: z.number().optional(),
127
132
  cached: z.boolean().optional()
@@ -137,14 +142,27 @@ var searchMetaSchema = z.object({
137
142
  });
138
143
  function createRefkitMcpServer(refkit) {
139
144
  const server = new McpServer({ name: "refkit", version: VERSION });
145
+ const enabledSourceIds = refkit.providers.map((p) => p.id);
146
+ const registered = refkit.providers;
147
+ const modalityValues = [...new Set(registered.flatMap((p) => p.modalities))];
148
+ const kindValues = [.../* @__PURE__ */ new Set([...BASE_MEDIA_KINDS, ...registered.flatMap((p) => p.kinds ?? [])])];
149
+ const sourceList = registered.map((p) => {
150
+ const kinds = p.kinds?.length ? `\xB7${p.kinds.join(",")}` : "";
151
+ const desc = p.description ? `: ${p.description}` : "";
152
+ return `- ${p.id} (${p.modalities.join("/")}${kinds})${desc}`;
153
+ }).join("\n");
154
+ const searchControlsSchema = buildSearchControlsSchema(kindValues);
140
155
  server.registerTool(
141
156
  "search_references",
142
157
  {
143
158
  title: "Search creative references",
144
- description: "Search license-normalized reference material (image / video / audio / text) across the configured sources. Every result carries a license id + canonical source link. Pass `intent` to annotate each result with a use-verdict (may I use this, is attribution required) WITHOUT filtering; pass `gateFor` to instead return only results whose license allows that intent. Results are references, not rights clearance \u2014 not legal advice.",
159
+ description: "Search license-normalized reference material (image / video / audio / text) across the configured sources. Every result carries a license id + canonical source link. Pass `intent` to annotate each result with a use-verdict (may I use this, is attribution required) WITHOUT filtering; pass `gateFor` to instead return only results whose license allows that intent. Results are references, not rights clearance \u2014 not legal advice.\n\nConfigured sources:\n" + sourceList,
145
160
  inputSchema: {
146
161
  query: z.string().describe('what to search for, e.g. "cyberpunk alley at night"'),
147
- modalities: z.array(z.enum(MODALITIES)).optional().describe('default ["image"]'),
162
+ modalities: z.array(z.enum(modalityValues)).optional().describe('default ["image"]'),
163
+ sources: z.array(z.string()).optional().describe(
164
+ `restrict the search to specific sources by id (omit to search every configured source \u2014 see "Configured sources" in this tool description). Use to scope a search-engine operator (e.g. "site:example.com") to a web-discovery source without affecting other sources' queries.`
165
+ ),
148
166
  filters: filtersSchema.optional().describe("compatibility alias for controls.orientation, controls.color, and controls.language"),
149
167
  controls: searchControlsSchema.optional().describe("provider-neutral search controls; providers translate supported controls and report ignored controls in explain metadata"),
150
168
  providerOptions: providerOptionsSchema.optional().describe("provider-specific search controls keyed by provider id; each provider whitelists supported keys"),
@@ -161,10 +179,11 @@ function createRefkitMcpServer(refkit) {
161
179
  meta: searchMetaSchema.optional()
162
180
  }
163
181
  },
164
- async ({ query, modalities, filters, controls, providerOptions, explain, limit, cursor, rerank, intent, gateFor }) => {
182
+ async ({ query, modalities, filters, controls, providerOptions, explain, limit, cursor, rerank, intent, gateFor, sources }) => {
165
183
  const searchInput = {
166
184
  query,
167
185
  modalities: modalities ?? ["image"],
186
+ sources,
168
187
  filters,
169
188
  controls,
170
189
  providerOptions,
@@ -173,7 +192,20 @@ function createRefkitMcpServer(refkit) {
173
192
  ...rerank ? { rerank: lexicalReranker() } : {},
174
193
  gateFor
175
194
  };
176
- const result = await refkit.searchWithMeta(searchInput);
195
+ let result;
196
+ try {
197
+ result = await refkit.searchWithMeta(searchInput);
198
+ } catch (err) {
199
+ if (sources && sources.length > 0 && !(err instanceof AggregateError)) {
200
+ const available = enabledSourceIds.join(", ") || "(none)";
201
+ const detail = err instanceof Error ? err.message : String(err);
202
+ return {
203
+ isError: true,
204
+ content: [{ type: "text", text: `${detail} Enabled source ids: ${available}.` }]
205
+ };
206
+ }
207
+ throw err;
208
+ }
177
209
  const refs = result.references;
178
210
  const assessIntent = intent ?? gateFor;
179
211
  const references = refs.map(
@@ -274,4 +306,4 @@ export {
274
306
  createRefkitMcpServer,
275
307
  serveStdio
276
308
  };
277
- //# sourceMappingURL=chunk-DQHNPSDF.js.map
309
+ //# sourceMappingURL=chunk-WVJJN6XK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { LICENSE_IDS, INTENTS, evaluateUse, buildAttribution, ccVersionFor, lexicalReranker } from '@refkit/core'\nimport type { RefkitClient, Reference, Verdict, Attribution, SearchFilters, SearchControls, SearchControlKey, ProviderOptionsById, SearchMeta, RightsRecord, Modality } from '@refkit/core'\n\nconst MODALITIES = ['image', 'video', 'audio', 'text'] as const\nconst ORIENTATIONS = ['landscape', 'portrait', 'square'] as const\n// Legacy media.kind control values — kept in the dynamic enum because they stay\n// meaningful as upstream filter translations for providers that support the\n// media.kind control without declaring kinds.\nconst BASE_MEDIA_KINDS = ['photo', 'illustration', 'vector', 'film', 'animation'] as const\nconst SEARCH_CONTROL_KEYS = [\n 'orientation',\n 'color',\n 'language',\n 'sort',\n 'safety',\n 'license.commercial',\n 'license.modification',\n 'license.allowUnknown',\n 'media.kind',\n 'media.size',\n 'media.minWidth',\n 'media.minHeight',\n 'media.duration',\n 'creator.id',\n 'creator.name',\n 'text.copyright',\n 'page',\n] as const satisfies readonly SearchControlKey[]\n\nconst filtersSchema = z.object({\n color: z.string().optional(),\n orientation: z.enum(ORIENTATIONS).optional(),\n language: z.string().optional(),\n})\nconst searchControlKeySchema = z.enum(SEARCH_CONTROL_KEYS)\n\nfunction buildSearchControlsSchema(kindValues: [string, ...string[]]) {\n return z.object({\n orientation: z.enum(ORIENTATIONS).optional(),\n color: z.string().optional(),\n language: z.string().optional(),\n sort: z.enum(['relevance', 'latest', 'popular', 'interesting']).optional(),\n safety: z.enum(['strict', 'moderate', 'off']).optional(),\n license: z.object({\n commercial: z.boolean().optional(),\n modification: z.boolean().optional(),\n allowUnknown: z.boolean().optional(),\n }).optional(),\n media: z.object({\n kind: z.enum(kindValues).optional(),\n size: z.enum(['small', 'medium', 'large']).optional(),\n minWidth: z.number().int().nonnegative().optional(),\n minHeight: z.number().int().nonnegative().optional(),\n duration: z.enum(['short', 'medium', 'long']).optional(),\n }).optional(),\n creator: z.object({\n id: z.string().optional(),\n name: z.string().optional(),\n }).optional(),\n text: z.object({\n copyright: z.enum(['public-domain', 'copyrighted', 'any']).optional(),\n }).optional(),\n page: z.number().int().positive().optional(),\n })\n}\n\nconst providerOptionValueSchema = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())])\nconst providerOptionsSchema = z.record(z.string(), z.record(z.string(), providerOptionValueSchema))\n\n// Reported in the MCP initialize handshake. Read the real version (the dist sits\n// next to package.json, which npm always ships) instead of a hardcoded placeholder.\nconst VERSION: string = (() => {\n try {\n return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version\n } catch {\n return '0.0.0'\n }\n})()\n\n// Concise, agent-facing projection of a Reference (no raw provider dump). When an\n// intent is supplied the use-gate verdict + attribution ride along, so the agent\n// sees *whether it may use* each result — not just a bare license id it ignores.\nfunction toAgentRef(r: Reference, assessment?: { verdict: Verdict; attribution: Attribution }) {\n const base = {\n id: r.id,\n title: r.title,\n modality: r.modality,\n kind: r.kind,\n provider: r.source.providerId,\n canonicalUrl: r.canonicalUrl,\n license: r.rights.license,\n thumbnail: r.thumbnail?.url,\n excerpt: r.text?.excerpt,\n }\n if (!assessment) return base\n const { verdict, attribution } = assessment\n const reason = verdict.reasons.join('; ')\n const useExplanation = `${verdict.decision}: ${reason || 'license facts allow this use'}${attribution.required && attribution.text ? ` Attribution required: ${attribution.text}` : ''}`\n return {\n ...base,\n useVerdict: { decision: verdict.decision, reason: verdict.reasons.join('; '), confidence: verdict.confidence },\n useExplanation,\n ...(attribution.required && attribution.text ? { attribution: attribution.text } : {}),\n }\n}\n\nconst agentRefSchema = z.object({\n id: z.string(),\n title: z.string().optional(),\n modality: z.string(),\n kind: z.string().optional().describe('fine-grained resource kind, e.g. photo / texture / ebook'),\n provider: z.string(),\n canonicalUrl: z.string(),\n license: z.string(),\n thumbnail: z.string().optional(),\n excerpt: z.string().optional(),\n useVerdict: z\n .object({ decision: z.string(), reason: z.string(), confidence: z.string() })\n .optional()\n .describe('present when `intent` (or `gateFor`) is set: may this be used for that intent, and how confident'),\n useExplanation: z.string().optional().describe('plain-language use verdict summary for agents'),\n attribution: z.string().optional().describe('ready-to-use credit line; present when the license requires attribution'),\n})\n\nconst searchMetaSchema: z.ZodType<SearchMeta> = z.object({\n query: z.string(),\n modalities: z.array(z.enum(MODALITIES)),\n limit: z.number(),\n poolFactor: z.number(),\n fetchLimit: z.number(),\n appliedFilters: filtersSchema.optional(),\n controls: z.object({\n requested: z.array(searchControlKeySchema),\n appliedByProvider: z.record(z.string(), z.array(searchControlKeySchema)),\n ignoredByProvider: z.record(z.string(), z.array(searchControlKeySchema)),\n }).optional(),\n providerOptions: z.array(z.string()).optional(),\n providers: z.array(z.object({\n providerId: z.string(),\n status: z.enum(['fulfilled', 'failed', 'skipped']),\n returned: z.number().optional(),\n accepted: z.number().optional(),\n rejected: z.number().optional(),\n reason: z.enum(['unsupported-modality', 'unsupported-kind', 'not-selected']).optional(),\n error: z.string().optional(),\n latencyMs: z.number().optional(),\n cached: z.boolean().optional(),\n })),\n gate: z.object({\n intent: z.enum(INTENTS),\n before: z.number(),\n after: z.number(),\n dropped: z.number(),\n }).optional(),\n nextCursor: z.string().optional().describe('opaque load-more cursor; pass back as `cursor` to fetch the next page with cross-page dedup'),\n warnings: z.array(z.string()),\n})\n\n/** Wrap a configured RefkitClient as an MCP server exposing `search_references`. */\nexport function createRefkitMcpServer(refkit: RefkitClient): McpServer {\n const server = new McpServer({ name: 'refkit', version: VERSION })\n // Enumerated in the `sources` param description so an agent knows the valid ids\n // up front (and reused to enrich a source-miss error). Providers are fixed for\n // the server's lifetime, so this snapshot never drifts.\n const enabledSourceIds = refkit.providers.map(p => p.id)\n\n const registered = refkit.providers\n const modalityValues = [...new Set(registered.flatMap(p => p.modalities))] as [Modality, ...Modality[]]\n const kindValues = [...new Set<string>([...BASE_MEDIA_KINDS, ...registered.flatMap(p => p.kinds ?? [])])] as [string, ...string[]]\n const sourceList = registered.map(p => {\n const kinds = p.kinds?.length ? `·${p.kinds.join(',')}` : ''\n const desc = p.description ? `: ${p.description}` : ''\n return `- ${p.id} (${p.modalities.join('/')}${kinds})${desc}`\n }).join('\\n')\n const searchControlsSchema = buildSearchControlsSchema(kindValues)\n\n server.registerTool(\n 'search_references',\n {\n title: 'Search creative references',\n description:\n 'Search license-normalized reference material (image / video / audio / text) across the configured sources. ' +\n 'Every result carries a license id + canonical source link. Pass `intent` to annotate each result with a ' +\n 'use-verdict (may I use this, is attribution required) WITHOUT filtering; pass `gateFor` to instead return ' +\n 'only results whose license allows that intent. Results are references, not rights clearance — not legal advice.' +\n '\\n\\nConfigured sources:\\n' + sourceList,\n inputSchema: {\n query: z.string().describe('what to search for, e.g. \"cyberpunk alley at night\"'),\n modalities: z.array(z.enum(modalityValues)).optional().describe('default [\"image\"]'),\n sources: z.array(z.string()).optional().describe(\n 'restrict the search to specific sources by id (omit to search every configured source — see \"Configured sources\" in this tool description). '\n + 'Use to scope a search-engine operator (e.g. \"site:example.com\") to a web-discovery source without affecting other sources\\' queries.',\n ),\n filters: filtersSchema.optional().describe('compatibility alias for controls.orientation, controls.color, and controls.language'),\n controls: searchControlsSchema.optional().describe('provider-neutral search controls; providers translate supported controls and report ignored controls in explain metadata'),\n providerOptions: providerOptionsSchema.optional().describe('provider-specific search controls keyed by provider id; each provider whitelists supported keys'),\n explain: z.boolean().optional().describe('include provider status, applied and ignored controls, warnings, gate/drop metadata, and the load-more cursor'),\n limit: z.number().int().positive().optional(),\n cursor: z.string().optional().describe('opaque cursor from a previous result\\'s nextCursor — fetches the next batch, deduped against earlier batches'),\n rerank: z.boolean().optional().describe('re-rank results by query relevance (term coverage incl. CJK, resolution, source diversity) instead of raw cross-source rank fusion'),\n intent: z.enum(INTENTS).optional().describe('annotate each result with a use-verdict for this intended use (no filtering)'),\n gateFor: z.enum(INTENTS).optional().describe('only return results whose license allows this intended use'),\n },\n outputSchema: {\n references: z.array(agentRefSchema),\n nextCursor: z.string().optional().describe('pass back as `cursor` for the next batch; absent = exhausted'),\n meta: searchMetaSchema.optional(),\n },\n },\n async ({ query, modalities, filters, controls, providerOptions, explain, limit, cursor, rerank, intent, gateFor, sources }) => {\n const searchInput = {\n query,\n modalities: modalities ?? ['image'],\n sources,\n filters: filters as SearchFilters | undefined,\n controls: controls as SearchControls | undefined,\n providerOptions: providerOptions as ProviderOptionsById | undefined,\n limit,\n cursor,\n ...(rerank ? { rerank: lexicalReranker() } : {}),\n gateFor,\n }\n // Always searchWithMeta: the continuation token (meta.nextCursor) must not\n // depend on the explain diagnostics flag — only the meta DUMP is gated.\n let result\n try {\n result = await refkit.searchWithMeta(searchInput)\n } catch (err) {\n // A source-selection miss (no requested id resolves for the modality) is a\n // caller mistake, not an outage — turn core's throw into an agent-actionable\n // tool error listing the valid ids. AggregateError (every chosen provider\n // failed at fetch) is a genuine upstream fault, so let it propagate.\n if (sources && sources.length > 0 && !(err instanceof AggregateError)) {\n const available = enabledSourceIds.join(', ') || '(none)'\n const detail = err instanceof Error ? err.message : String(err)\n return {\n isError: true,\n content: [{ type: 'text', text: `${detail} Enabled source ids: ${available}.` }],\n }\n }\n throw err\n }\n const refs = result.references\n const assessIntent = intent ?? gateFor\n const references = refs.map(r =>\n assessIntent\n ? toAgentRef(r, { verdict: refkit.evaluateUse(r, assessIntent), attribution: refkit.buildAttribution(r) })\n : toAgentRef(r),\n )\n return {\n content: [{ type: 'text', text: `${references.length} reference(s) for \"${query}\".` }],\n structuredContent: {\n references,\n ...(result.meta.nextCursor ? { nextCursor: result.meta.nextCursor } : {}),\n ...(explain ? { meta: result.meta } : {}),\n },\n }\n },\n )\n\n const attributionOutputSchema = { required: z.boolean(), text: z.string().optional(), html: z.string().optional() }\n\n server.registerTool(\n 'evaluate_use',\n {\n title: 'Evaluate a license for an intended use',\n description:\n 'Stateless license/use-gate check: given a license id + intended use, returns a conservative-heuristic verdict ' +\n '(allowed / allowed-with-attribution / denied / needs-review) with reasons and confidence. ' +\n 'Not legal advice — a strict-deny heuristic over source-declared license facts.',\n inputSchema: {\n license: z.enum(LICENSE_IDS).describe('the reference\\'s license id'),\n licenseVersion: z.string().optional().describe('precise CC version, e.g. \"4.0\" — attribution only'),\n author: z.string().optional(),\n title: z.string().optional(),\n canonicalUrl: z.string().describe('canonical source link, for attribution and audit'),\n intent: z.enum(INTENTS).describe('the intended use to evaluate this license against'),\n editorialOnly: z.boolean().optional().describe('source marked editorial-only'),\n jurisdiction: z.string().optional().describe('source-declared jurisdiction of the PD/copyright status'),\n userJurisdiction: z.string().optional().describe('caller\\'s jurisdiction; mismatched jurisdictions default to needs-review'),\n },\n outputSchema: {\n decision: z.enum(['allowed', 'allowed-with-attribution', 'denied', 'needs-review']),\n reasons: z.array(z.string()),\n confidence: z.enum(['high', 'low']),\n disclaimer: z.string(),\n attribution: z.object(attributionOutputSchema).optional(),\n },\n },\n async ({ license, licenseVersion, author, title, canonicalUrl, intent, editorialOnly, jurisdiction, userJurisdiction }) => {\n const version = ccVersionFor(license, licenseVersion)\n const rights: RightsRecord = {\n license,\n licenseVersion: version,\n author,\n rehostPolicy: 'cache-allowed',\n jurisdiction,\n editorialOnly,\n raw: { sourceTerms: '', sourceUrl: canonicalUrl },\n }\n const verdict: Verdict = evaluateUse(rights, intent, { userJurisdiction })\n const attribution =\n verdict.decision === 'allowed-with-attribution'\n ? buildAttribution({ license, licenseVersion: version, author, title, canonicalUrl })\n : undefined\n const summary = `${verdict.decision}: ${verdict.reasons.join('; ') || 'license facts allow this use'}`\n return {\n content: [{ type: 'text', text: summary }],\n structuredContent: {\n decision: verdict.decision,\n reasons: verdict.reasons,\n confidence: verdict.confidence,\n disclaimer: verdict.disclaimer,\n ...(attribution ? { attribution } : {}),\n },\n }\n },\n )\n\n server.registerTool(\n 'build_attribution',\n {\n title: 'Build an attribution credit line',\n description:\n 'Mechanically derive an attribution credit line (plain text + HTML) from a license id + author + title + ' +\n 'canonicalUrl. `required` is false when the license needs no attribution (e.g. CC0, PD).',\n inputSchema: {\n license: z.enum(LICENSE_IDS),\n licenseVersion: z.string().optional().describe('precise CC version, e.g. \"4.0\" — appended to the license name'),\n author: z.string().optional(),\n title: z.string().optional(),\n canonicalUrl: z.string(),\n },\n outputSchema: attributionOutputSchema,\n },\n async ({ license, licenseVersion, author, title, canonicalUrl }) => {\n const version = ccVersionFor(license, licenseVersion)\n const attribution: Attribution = buildAttribution({ license, licenseVersion: version, author, title, canonicalUrl })\n return {\n content: [{ type: 'text', text: attribution.required ? (attribution.text ?? '') : 'No attribution required for this license.' }],\n structuredContent: { required: attribution.required, text: attribution.text, html: attribution.html },\n }\n },\n )\n\n return server\n}\n\n/** Run the refkit MCP server over stdio (host wires the RefkitClient + its providers/keys). */\nexport async function serveStdio(refkit: RefkitClient): Promise<void> {\n const server = createRefkitMcpServer(refkit)\n await server.connect(new StdioServerTransport())\n}\n"],"mappings":"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","names":[]}
package/dist/cli.d.ts CHANGED
@@ -16,5 +16,10 @@ declare const BYOK_SOURCES: ByokSource[];
16
16
  * (optionalDependencies, dynamically imported on demand). Exported so the
17
17
  * wiring is unit-testable. */
18
18
  declare function defaultProviders(env?: NodeJS.ProcessEnv): Promise<ReferenceProvider[]>;
19
+ /** Cursor size knob for size-clamped tool-output channels: REFKIT_MAX_CURSOR_SEEN
20
+ * caps how many already-returned keys the load-more cursor remembers (see
21
+ * RefkitOptions.maxCursorSeen in @refkit/core — default 500 ≈ 2.7k chars of
22
+ * nextCursor). Invalid values warn on stderr and fall back to that default. */
23
+ declare function maxCursorSeenFromEnv(env?: NodeJS.ProcessEnv): number | undefined;
19
24
 
20
- export { BYOK_SOURCES, defaultProviders };
25
+ export { BYOK_SOURCES, defaultProviders, maxCursorSeenFromEnv };
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  serveStdio
4
- } from "./chunk-DQHNPSDF.js";
4
+ } from "./chunk-WVJJN6XK.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { realpathSync } from "fs";
@@ -16,6 +16,7 @@ import { poetrydb } from "@refkit/provider-poetrydb";
16
16
  import { rijksmuseum } from "@refkit/provider-rijksmuseum";
17
17
  import { polyhaven, ambientcg } from "@refkit/provider-polyhaven";
18
18
  import { internetArchive } from "@refkit/provider-internet-archive";
19
+ import { nailbook } from "@refkit/provider-nailbook";
19
20
  var BYOK_SOURCES = [
20
21
  {
21
22
  pkg: "@refkit/provider-unsplash",
@@ -81,7 +82,8 @@ async function defaultProviders(env = process.env) {
81
82
  rijksmuseum(),
82
83
  polyhaven(),
83
84
  ambientcg(),
84
- internetArchive()
85
+ internetArchive(),
86
+ nailbook()
85
87
  ];
86
88
  const loaded = await Promise.all(BYOK_SOURCES.map(async (source) => {
87
89
  const key = source.key(env);
@@ -109,11 +111,26 @@ var isEntry = (() => {
109
111
  return false;
110
112
  }
111
113
  })();
114
+ function maxCursorSeenFromEnv(env = process.env) {
115
+ const raw = env.REFKIT_MAX_CURSOR_SEEN;
116
+ if (raw === void 0 || raw === "") return void 0;
117
+ const n = /^\d+$/.test(raw) ? Number(raw) : Number.NaN;
118
+ if (!Number.isSafeInteger(n) || n < 1) {
119
+ console.error(`[refkit-mcp] ignoring invalid REFKIT_MAX_CURSOR_SEEN=${JSON.stringify(raw)} \u2014 expected a positive integer.`);
120
+ return void 0;
121
+ }
122
+ return n;
123
+ }
112
124
  if (isEntry) {
113
- await serveStdio(createRefkit({ providers: await defaultProviders() }));
125
+ const maxCursorSeen = maxCursorSeenFromEnv();
126
+ await serveStdio(createRefkit({
127
+ providers: await defaultProviders(),
128
+ ...maxCursorSeen !== void 0 ? { maxCursorSeen } : {}
129
+ }));
114
130
  }
115
131
  export {
116
132
  BYOK_SOURCES,
117
- defaultProviders
133
+ defaultProviders,
134
+ maxCursorSeenFromEnv
118
135
  };
119
136
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n// Zero-config entry: `npx @refkit/mcp` boots a working MCP server with the keyless\n// providers, plus any BYOK provider whose key is in the environment. No host code.\nimport { realpathSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { createRefkit, type ReferenceProvider } from '@refkit/core'\nimport { openverse, openverseAudio } from '@refkit/provider-openverse'\nimport { wikimediaCommons } from '@refkit/provider-wikimedia-commons'\nimport { met } from '@refkit/provider-met'\nimport { artic } from '@refkit/provider-artic'\nimport { gutendex } from '@refkit/provider-gutendex'\nimport { poetrydb } from '@refkit/provider-poetrydb'\nimport { rijksmuseum } from '@refkit/provider-rijksmuseum'\nimport { polyhaven, ambientcg } from '@refkit/provider-polyhaven'\nimport { internetArchive } from '@refkit/provider-internet-archive'\nimport { serveStdio } from './index'\n\n/** One BYOK source: its unified + legacy env var names, and a lazy loader for its\n * (optional) provider package. Loaded only when a key is present, so installs\n * that omitted optionalDependencies still boot — the missing source is skipped\n * with a stderr warning instead of crashing the server. */\ninterface ByokSource {\n pkg: string\n key: (env: NodeJS.ProcessEnv) => string | undefined\n load: (key: string) => Promise<ReferenceProvider[]>\n}\n\n// Env var convention: each BYOK key is read as `REFKIT_<PROVIDER>_KEY` first (the\n// unified name), falling back to the provider's legacy env var name — both are\n// honored indefinitely, the unified name is just preferred going forward.\n// Exported so tests can assert this table stays in sync with the package's\n// optionalDependencies — an entry in one but not the other ships a source that\n// either can never load or never installs.\nexport const BYOK_SOURCES: ByokSource[] = [\n {\n pkg: '@refkit/provider-unsplash',\n key: (env) => env.REFKIT_UNSPLASH_KEY ?? env.UNSPLASH_KEY,\n load: async (accessKey) => [(await import('@refkit/provider-unsplash')).unsplash({ accessKey })],\n },\n {\n pkg: '@refkit/provider-pexels',\n key: (env) => env.REFKIT_PEXELS_KEY ?? env.PEXELS_KEY,\n load: async (apiKey) => {\n const m = await import('@refkit/provider-pexels')\n return [m.pexels({ apiKey }), m.pexelsVideo({ apiKey })]\n },\n },\n {\n pkg: '@refkit/provider-pixabay',\n key: (env) => env.REFKIT_PIXABAY_KEY ?? env.PIXABAY_KEY,\n load: async (key) => {\n const m = await import('@refkit/provider-pixabay')\n return [m.pixabay({ key }), m.pixabayVideo({ key })]\n },\n },\n {\n pkg: '@refkit/provider-flickr',\n key: (env) => env.REFKIT_FLICKR_KEY ?? env.FLICKR_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-flickr')).flickr({ apiKey })],\n },\n {\n pkg: '@refkit/provider-smithsonian',\n key: (env) => env.REFKIT_SMITHSONIAN_KEY ?? env.SI_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-smithsonian')).smithsonian({ apiKey })],\n },\n {\n pkg: '@refkit/provider-brave',\n key: (env) => env.REFKIT_BRAVE_KEY ?? env.BRAVE_TOKEN,\n load: async (token) => [(await import('@refkit/provider-brave')).brave({ token })],\n },\n {\n pkg: '@refkit/provider-freesound',\n key: (env) => env.REFKIT_FREESOUND_KEY ?? env.FREESOUND_TOKEN,\n load: async (apiKey) => [(await import('@refkit/provider-freesound')).freesound({ apiKey })],\n },\n {\n pkg: '@refkit/provider-jamendo',\n key: (env) => env.REFKIT_JAMENDO_CLIENT_ID ?? env.JAMENDO_CLIENT_ID,\n load: async (clientId) => [(await import('@refkit/provider-jamendo')).jamendo({ clientId })],\n },\n {\n pkg: '@refkit/provider-europeana',\n key: (env) => env.REFKIT_EUROPEANA_KEY ?? env.EUROPEANA_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-europeana')).europeana({ apiKey })],\n },\n]\n\n/** Providers a zero-config server boots with: all keyless sources (hard deps,\n * statically imported), plus any BYOK source whose key is present in `env`\n * (optionalDependencies, dynamically imported on demand). Exported so the\n * wiring is unit-testable. */\nexport async function defaultProviders(env: NodeJS.ProcessEnv = process.env): Promise<ReferenceProvider[]> {\n const providers: ReferenceProvider[] = [\n openverse(), openverseAudio(), wikimediaCommons(), met(), artic(), gutendex(), poetrydb(),\n rijksmuseum(), polyhaven(), ambientcg(), internetArchive(),\n ]\n // Independent module loads — run them concurrently (startup cost = max, not sum)\n // and keep BYOK_SOURCES order in the provider list.\n const loaded = await Promise.all(BYOK_SOURCES.map(async (source) => {\n const key = source.key(env)\n if (!key) return []\n try {\n return await source.load(key)\n } catch (err) {\n // stderr only — stdout is the MCP transport. Only a genuinely missing\n // module gets the \"not installed\" hint; anything else (factory throw,\n // broken transitive import) surfaces the REAL error so the operator\n // doesn't chase the wrong remediation.\n const code = (err as { code?: string } | null)?.code\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {\n console.error(`[refkit-mcp] key for ${source.pkg} is set but the package is not installed — skipping this source. Reinstall @refkit/mcp with optional dependencies (or add ${source.pkg}) to enable it.`)\n } else {\n console.error(`[refkit-mcp] failed to initialize ${source.pkg} — skipping this source.`, err)\n }\n return []\n }\n }))\n for (const group of loaded) providers.push(...group)\n return providers\n}\n\n// Boot only when run as the CLI entry — not when imported (e.g. by tests). realpath\n// so an npm bin symlink resolves to this file.\nconst isEntry = (() => {\n if (!process.argv[1]) return false\n try {\n return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)\n } catch {\n return false\n }\n})()\n\nif (isEntry) {\n await serveStdio(createRefkit({ providers: await defaultProviders() }))\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n// Zero-config entry: `npx @refkit/mcp` boots a working MCP server with the keyless\n// providers, plus any BYOK provider whose key is in the environment. No host code.\nimport { realpathSync } from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport { createRefkit, type ReferenceProvider } from '@refkit/core'\nimport { openverse, openverseAudio } from '@refkit/provider-openverse'\nimport { wikimediaCommons } from '@refkit/provider-wikimedia-commons'\nimport { met } from '@refkit/provider-met'\nimport { artic } from '@refkit/provider-artic'\nimport { gutendex } from '@refkit/provider-gutendex'\nimport { poetrydb } from '@refkit/provider-poetrydb'\nimport { rijksmuseum } from '@refkit/provider-rijksmuseum'\nimport { polyhaven, ambientcg } from '@refkit/provider-polyhaven'\nimport { internetArchive } from '@refkit/provider-internet-archive'\nimport { nailbook } from '@refkit/provider-nailbook'\nimport { serveStdio } from './index'\n\n/** One BYOK source: its unified + legacy env var names, and a lazy loader for its\n * (optional) provider package. Loaded only when a key is present, so installs\n * that omitted optionalDependencies still boot — the missing source is skipped\n * with a stderr warning instead of crashing the server. */\ninterface ByokSource {\n pkg: string\n key: (env: NodeJS.ProcessEnv) => string | undefined\n load: (key: string) => Promise<ReferenceProvider[]>\n}\n\n// Env var convention: each BYOK key is read as `REFKIT_<PROVIDER>_KEY` first (the\n// unified name), falling back to the provider's legacy env var name — both are\n// honored indefinitely, the unified name is just preferred going forward.\n// Exported so tests can assert this table stays in sync with the package's\n// optionalDependencies — an entry in one but not the other ships a source that\n// either can never load or never installs.\nexport const BYOK_SOURCES: ByokSource[] = [\n {\n pkg: '@refkit/provider-unsplash',\n key: (env) => env.REFKIT_UNSPLASH_KEY ?? env.UNSPLASH_KEY,\n load: async (accessKey) => [(await import('@refkit/provider-unsplash')).unsplash({ accessKey })],\n },\n {\n pkg: '@refkit/provider-pexels',\n key: (env) => env.REFKIT_PEXELS_KEY ?? env.PEXELS_KEY,\n load: async (apiKey) => {\n const m = await import('@refkit/provider-pexels')\n return [m.pexels({ apiKey }), m.pexelsVideo({ apiKey })]\n },\n },\n {\n pkg: '@refkit/provider-pixabay',\n key: (env) => env.REFKIT_PIXABAY_KEY ?? env.PIXABAY_KEY,\n load: async (key) => {\n const m = await import('@refkit/provider-pixabay')\n return [m.pixabay({ key }), m.pixabayVideo({ key })]\n },\n },\n {\n pkg: '@refkit/provider-flickr',\n key: (env) => env.REFKIT_FLICKR_KEY ?? env.FLICKR_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-flickr')).flickr({ apiKey })],\n },\n {\n pkg: '@refkit/provider-smithsonian',\n key: (env) => env.REFKIT_SMITHSONIAN_KEY ?? env.SI_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-smithsonian')).smithsonian({ apiKey })],\n },\n {\n pkg: '@refkit/provider-brave',\n key: (env) => env.REFKIT_BRAVE_KEY ?? env.BRAVE_TOKEN,\n load: async (token) => [(await import('@refkit/provider-brave')).brave({ token })],\n },\n {\n pkg: '@refkit/provider-freesound',\n key: (env) => env.REFKIT_FREESOUND_KEY ?? env.FREESOUND_TOKEN,\n load: async (apiKey) => [(await import('@refkit/provider-freesound')).freesound({ apiKey })],\n },\n {\n pkg: '@refkit/provider-jamendo',\n key: (env) => env.REFKIT_JAMENDO_CLIENT_ID ?? env.JAMENDO_CLIENT_ID,\n load: async (clientId) => [(await import('@refkit/provider-jamendo')).jamendo({ clientId })],\n },\n {\n pkg: '@refkit/provider-europeana',\n key: (env) => env.REFKIT_EUROPEANA_KEY ?? env.EUROPEANA_KEY,\n load: async (apiKey) => [(await import('@refkit/provider-europeana')).europeana({ apiKey })],\n },\n]\n\n/** Providers a zero-config server boots with: all keyless sources (hard deps,\n * statically imported), plus any BYOK source whose key is present in `env`\n * (optionalDependencies, dynamically imported on demand). Exported so the\n * wiring is unit-testable. */\nexport async function defaultProviders(env: NodeJS.ProcessEnv = process.env): Promise<ReferenceProvider[]> {\n const providers: ReferenceProvider[] = [\n openverse(), openverseAudio(), wikimediaCommons(), met(), artic(), gutendex(), poetrydb(),\n rijksmuseum(), polyhaven(), ambientcg(), internetArchive(), nailbook(),\n ]\n // Independent module loads — run them concurrently (startup cost = max, not sum)\n // and keep BYOK_SOURCES order in the provider list.\n const loaded = await Promise.all(BYOK_SOURCES.map(async (source) => {\n const key = source.key(env)\n if (!key) return []\n try {\n return await source.load(key)\n } catch (err) {\n // stderr only — stdout is the MCP transport. Only a genuinely missing\n // module gets the \"not installed\" hint; anything else (factory throw,\n // broken transitive import) surfaces the REAL error so the operator\n // doesn't chase the wrong remediation.\n const code = (err as { code?: string } | null)?.code\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') {\n console.error(`[refkit-mcp] key for ${source.pkg} is set but the package is not installed — skipping this source. Reinstall @refkit/mcp with optional dependencies (or add ${source.pkg}) to enable it.`)\n } else {\n console.error(`[refkit-mcp] failed to initialize ${source.pkg} — skipping this source.`, err)\n }\n return []\n }\n }))\n for (const group of loaded) providers.push(...group)\n return providers\n}\n\n// Boot only when run as the CLI entry — not when imported (e.g. by tests). realpath\n// so an npm bin symlink resolves to this file.\nconst isEntry = (() => {\n if (!process.argv[1]) return false\n try {\n return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)\n } catch {\n return false\n }\n})()\n\n/** Cursor size knob for size-clamped tool-output channels: REFKIT_MAX_CURSOR_SEEN\n * caps how many already-returned keys the load-more cursor remembers (see\n * RefkitOptions.maxCursorSeen in @refkit/core — default 500 ≈ 2.7k chars of\n * nextCursor). Invalid values warn on stderr and fall back to that default. */\nexport function maxCursorSeenFromEnv(env: NodeJS.ProcessEnv = process.env): number | undefined {\n const raw = env.REFKIT_MAX_CURSOR_SEEN\n if (raw === undefined || raw === '') return undefined\n // Strict decimal digits only — Number()'s hex/exponent/whitespace leniency\n // would silently accept values like '1e100' that defeat the cap entirely.\n const n = /^\\d+$/.test(raw) ? Number(raw) : Number.NaN\n if (!Number.isSafeInteger(n) || n < 1) {\n console.error(`[refkit-mcp] ignoring invalid REFKIT_MAX_CURSOR_SEEN=${JSON.stringify(raw)} — expected a positive integer.`)\n return undefined\n }\n return n\n}\n\nif (isEntry) {\n const maxCursorSeen = maxCursorSeenFromEnv()\n await serveStdio(createRefkit({\n providers: await defaultProviders(),\n ...(maxCursorSeen !== undefined ? { maxCursorSeen } : {}),\n }))\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRefkitMcpServer,
3
3
  serveStdio
4
- } from "./chunk-DQHNPSDF.js";
4
+ } from "./chunk-WVJJN6XK.js";
5
5
  export {
6
6
  createRefkitMcpServer,
7
7
  serveStdio
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refkit/mcp",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "MCP server for refkit — exposes license-normalized reference search as an agent tool.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -34,31 +34,32 @@
34
34
  "dependencies": {
35
35
  "@modelcontextprotocol/sdk": "^1.29.0",
36
36
  "zod": "^4.3.6",
37
- "@refkit/core": "0.7.0",
38
- "@refkit/provider-artic": "0.2.4",
39
- "@refkit/provider-gutendex": "0.2.4",
40
- "@refkit/provider-internet-archive": "0.3.2",
41
- "@refkit/provider-met": "0.2.4",
42
- "@refkit/provider-openverse": "0.3.2",
43
- "@refkit/provider-poetrydb": "0.2.4",
44
- "@refkit/provider-polyhaven": "0.2.3",
45
- "@refkit/provider-rijksmuseum": "0.2.3",
46
- "@refkit/provider-wikimedia-commons": "0.3.2"
37
+ "@refkit/core": "0.8.0",
38
+ "@refkit/provider-artic": "0.3.0",
39
+ "@refkit/provider-gutendex": "0.3.0",
40
+ "@refkit/provider-internet-archive": "0.4.0",
41
+ "@refkit/provider-met": "0.3.0",
42
+ "@refkit/provider-nailbook": "0.1.0",
43
+ "@refkit/provider-openverse": "0.4.0",
44
+ "@refkit/provider-poetrydb": "0.3.0",
45
+ "@refkit/provider-polyhaven": "0.3.0",
46
+ "@refkit/provider-rijksmuseum": "0.3.0",
47
+ "@refkit/provider-wikimedia-commons": "0.4.0"
47
48
  },
48
49
  "files": [
49
50
  "dist",
50
51
  "LICENSE"
51
52
  ],
52
53
  "optionalDependencies": {
53
- "@refkit/provider-brave": "0.2.4",
54
- "@refkit/provider-europeana": "0.3.2",
55
- "@refkit/provider-flickr": "0.3.2",
56
- "@refkit/provider-freesound": "0.3.2",
57
- "@refkit/provider-jamendo": "0.3.2",
58
- "@refkit/provider-pexels": "0.2.4",
59
- "@refkit/provider-pixabay": "0.2.4",
60
- "@refkit/provider-smithsonian": "0.2.4",
61
- "@refkit/provider-unsplash": "0.2.4"
54
+ "@refkit/provider-flickr": "0.4.0",
55
+ "@refkit/provider-brave": "0.3.0",
56
+ "@refkit/provider-freesound": "0.4.0",
57
+ "@refkit/provider-europeana": "0.4.0",
58
+ "@refkit/provider-jamendo": "0.4.0",
59
+ "@refkit/provider-pixabay": "0.3.0",
60
+ "@refkit/provider-smithsonian": "0.3.0",
61
+ "@refkit/provider-pexels": "0.3.0",
62
+ "@refkit/provider-unsplash": "0.3.0"
62
63
  },
63
64
  "scripts": {
64
65
  "typecheck": "tsc --noEmit",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { LICENSE_IDS, INTENTS, evaluateUse, buildAttribution, ccVersionFor, lexicalReranker } from '@refkit/core'\nimport type { RefkitClient, Reference, Verdict, Attribution, SearchFilters, SearchControls, SearchControlKey, ProviderOptionsById, SearchMeta, RightsRecord } from '@refkit/core'\n\nconst MODALITIES = ['image', 'video', 'audio', 'text'] as const\nconst ORIENTATIONS = ['landscape', 'portrait', 'square'] as const\nconst SEARCH_CONTROL_KEYS = [\n 'orientation',\n 'color',\n 'language',\n 'sort',\n 'safety',\n 'license.commercial',\n 'license.modification',\n 'license.allowUnknown',\n 'media.kind',\n 'media.size',\n 'media.minWidth',\n 'media.minHeight',\n 'media.duration',\n 'creator.id',\n 'creator.name',\n 'text.copyright',\n 'page',\n] as const satisfies readonly SearchControlKey[]\n\nconst filtersSchema = z.object({\n color: z.string().optional(),\n orientation: z.enum(ORIENTATIONS).optional(),\n language: z.string().optional(),\n})\nconst searchControlKeySchema = z.enum(SEARCH_CONTROL_KEYS)\n\nconst searchControlsSchema = z.object({\n orientation: z.enum(ORIENTATIONS).optional(),\n color: z.string().optional(),\n language: z.string().optional(),\n sort: z.enum(['relevance', 'latest', 'popular', 'interesting']).optional(),\n safety: z.enum(['strict', 'moderate', 'off']).optional(),\n license: z.object({\n commercial: z.boolean().optional(),\n modification: z.boolean().optional(),\n allowUnknown: z.boolean().optional(),\n }).optional(),\n media: z.object({\n kind: z.enum(['photo', 'illustration', 'vector', 'film', 'animation']).optional(),\n size: z.enum(['small', 'medium', 'large']).optional(),\n minWidth: z.number().int().nonnegative().optional(),\n minHeight: z.number().int().nonnegative().optional(),\n duration: z.enum(['short', 'medium', 'long']).optional(),\n }).optional(),\n creator: z.object({\n id: z.string().optional(),\n name: z.string().optional(),\n }).optional(),\n text: z.object({\n copyright: z.enum(['public-domain', 'copyrighted', 'any']).optional(),\n }).optional(),\n page: z.number().int().positive().optional(),\n})\n\nconst providerOptionValueSchema = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())])\nconst providerOptionsSchema = z.record(z.string(), z.record(z.string(), providerOptionValueSchema))\n\n// Reported in the MCP initialize handshake. Read the real version (the dist sits\n// next to package.json, which npm always ships) instead of a hardcoded placeholder.\nconst VERSION: string = (() => {\n try {\n return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version\n } catch {\n return '0.0.0'\n }\n})()\n\n// Concise, agent-facing projection of a Reference (no raw provider dump). When an\n// intent is supplied the use-gate verdict + attribution ride along, so the agent\n// sees *whether it may use* each result — not just a bare license id it ignores.\nfunction toAgentRef(r: Reference, assessment?: { verdict: Verdict; attribution: Attribution }) {\n const base = {\n id: r.id,\n title: r.title,\n modality: r.modality,\n provider: r.source.providerId,\n canonicalUrl: r.canonicalUrl,\n license: r.rights.license,\n thumbnail: r.thumbnail?.url,\n excerpt: r.text?.excerpt,\n }\n if (!assessment) return base\n const { verdict, attribution } = assessment\n const reason = verdict.reasons.join('; ')\n const useExplanation = `${verdict.decision}: ${reason || 'license facts allow this use'}${attribution.required && attribution.text ? ` Attribution required: ${attribution.text}` : ''}`\n return {\n ...base,\n useVerdict: { decision: verdict.decision, reason: verdict.reasons.join('; '), confidence: verdict.confidence },\n useExplanation,\n ...(attribution.required && attribution.text ? { attribution: attribution.text } : {}),\n }\n}\n\nconst agentRefSchema = z.object({\n id: z.string(),\n title: z.string().optional(),\n modality: z.string(),\n provider: z.string(),\n canonicalUrl: z.string(),\n license: z.string(),\n thumbnail: z.string().optional(),\n excerpt: z.string().optional(),\n useVerdict: z\n .object({ decision: z.string(), reason: z.string(), confidence: z.string() })\n .optional()\n .describe('present when `intent` (or `gateFor`) is set: may this be used for that intent, and how confident'),\n useExplanation: z.string().optional().describe('plain-language use verdict summary for agents'),\n attribution: z.string().optional().describe('ready-to-use credit line; present when the license requires attribution'),\n})\n\nconst searchMetaSchema: z.ZodType<SearchMeta> = z.object({\n query: z.string(),\n modalities: z.array(z.enum(MODALITIES)),\n limit: z.number(),\n poolFactor: z.number(),\n fetchLimit: z.number(),\n appliedFilters: filtersSchema.optional(),\n controls: z.object({\n requested: z.array(searchControlKeySchema),\n appliedByProvider: z.record(z.string(), z.array(searchControlKeySchema)),\n ignoredByProvider: z.record(z.string(), z.array(searchControlKeySchema)),\n }).optional(),\n providerOptions: z.array(z.string()).optional(),\n providers: z.array(z.object({\n providerId: z.string(),\n status: z.enum(['fulfilled', 'failed', 'skipped']),\n returned: z.number().optional(),\n accepted: z.number().optional(),\n rejected: z.number().optional(),\n reason: z.enum(['unsupported-modality']).optional(),\n error: z.string().optional(),\n latencyMs: z.number().optional(),\n cached: z.boolean().optional(),\n })),\n gate: z.object({\n intent: z.enum(INTENTS),\n before: z.number(),\n after: z.number(),\n dropped: z.number(),\n }).optional(),\n nextCursor: z.string().optional().describe('opaque load-more cursor; pass back as `cursor` to fetch the next page with cross-page dedup'),\n warnings: z.array(z.string()),\n})\n\n/** Wrap a configured RefkitClient as an MCP server exposing `search_references`. */\nexport function createRefkitMcpServer(refkit: RefkitClient): McpServer {\n const server = new McpServer({ name: 'refkit', version: VERSION })\n\n server.registerTool(\n 'search_references',\n {\n title: 'Search creative references',\n description:\n 'Search license-normalized reference material (image / video / audio / text) across the configured sources. ' +\n 'Every result carries a license id + canonical source link. Pass `intent` to annotate each result with a ' +\n 'use-verdict (may I use this, is attribution required) WITHOUT filtering; pass `gateFor` to instead return ' +\n 'only results whose license allows that intent. Results are references, not rights clearance — not legal advice.',\n inputSchema: {\n query: z.string().describe('what to search for, e.g. \"cyberpunk alley at night\"'),\n modalities: z.array(z.enum(MODALITIES)).optional().describe('default [\"image\"]'),\n filters: filtersSchema.optional().describe('compatibility alias for controls.orientation, controls.color, and controls.language'),\n controls: searchControlsSchema.optional().describe('provider-neutral search controls; providers translate supported controls and report ignored controls in explain metadata'),\n providerOptions: providerOptionsSchema.optional().describe('provider-specific search controls keyed by provider id; each provider whitelists supported keys'),\n explain: z.boolean().optional().describe('include provider status, applied and ignored controls, warnings, gate/drop metadata, and the load-more cursor'),\n limit: z.number().int().positive().optional(),\n cursor: z.string().optional().describe('opaque cursor from a previous result\\'s nextCursor — fetches the next batch, deduped against earlier batches'),\n rerank: z.boolean().optional().describe('re-rank results by query relevance (term coverage incl. CJK, resolution, source diversity) instead of raw cross-source rank fusion'),\n intent: z.enum(INTENTS).optional().describe('annotate each result with a use-verdict for this intended use (no filtering)'),\n gateFor: z.enum(INTENTS).optional().describe('only return results whose license allows this intended use'),\n },\n outputSchema: {\n references: z.array(agentRefSchema),\n nextCursor: z.string().optional().describe('pass back as `cursor` for the next batch; absent = exhausted'),\n meta: searchMetaSchema.optional(),\n },\n },\n async ({ query, modalities, filters, controls, providerOptions, explain, limit, cursor, rerank, intent, gateFor }) => {\n const searchInput = {\n query,\n modalities: modalities ?? ['image'],\n filters: filters as SearchFilters | undefined,\n controls: controls as SearchControls | undefined,\n providerOptions: providerOptions as ProviderOptionsById | undefined,\n limit,\n cursor,\n ...(rerank ? { rerank: lexicalReranker() } : {}),\n gateFor,\n }\n // Always searchWithMeta: the continuation token (meta.nextCursor) must not\n // depend on the explain diagnostics flag — only the meta DUMP is gated.\n const result = await refkit.searchWithMeta(searchInput)\n const refs = result.references\n const assessIntent = intent ?? gateFor\n const references = refs.map(r =>\n assessIntent\n ? toAgentRef(r, { verdict: refkit.evaluateUse(r, assessIntent), attribution: refkit.buildAttribution(r) })\n : toAgentRef(r),\n )\n return {\n content: [{ type: 'text', text: `${references.length} reference(s) for \"${query}\".` }],\n structuredContent: {\n references,\n ...(result.meta.nextCursor ? { nextCursor: result.meta.nextCursor } : {}),\n ...(explain ? { meta: result.meta } : {}),\n },\n }\n },\n )\n\n const attributionOutputSchema = { required: z.boolean(), text: z.string().optional(), html: z.string().optional() }\n\n server.registerTool(\n 'evaluate_use',\n {\n title: 'Evaluate a license for an intended use',\n description:\n 'Stateless license/use-gate check: given a license id + intended use, returns a conservative-heuristic verdict ' +\n '(allowed / allowed-with-attribution / denied / needs-review) with reasons and confidence. ' +\n 'Not legal advice — a strict-deny heuristic over source-declared license facts.',\n inputSchema: {\n license: z.enum(LICENSE_IDS).describe('the reference\\'s license id'),\n licenseVersion: z.string().optional().describe('precise CC version, e.g. \"4.0\" — attribution only'),\n author: z.string().optional(),\n title: z.string().optional(),\n canonicalUrl: z.string().describe('canonical source link, for attribution and audit'),\n intent: z.enum(INTENTS).describe('the intended use to evaluate this license against'),\n editorialOnly: z.boolean().optional().describe('source marked editorial-only'),\n jurisdiction: z.string().optional().describe('source-declared jurisdiction of the PD/copyright status'),\n userJurisdiction: z.string().optional().describe('caller\\'s jurisdiction; mismatched jurisdictions default to needs-review'),\n },\n outputSchema: {\n decision: z.enum(['allowed', 'allowed-with-attribution', 'denied', 'needs-review']),\n reasons: z.array(z.string()),\n confidence: z.enum(['high', 'low']),\n disclaimer: z.string(),\n attribution: z.object(attributionOutputSchema).optional(),\n },\n },\n async ({ license, licenseVersion, author, title, canonicalUrl, intent, editorialOnly, jurisdiction, userJurisdiction }) => {\n const version = ccVersionFor(license, licenseVersion)\n const rights: RightsRecord = {\n license,\n licenseVersion: version,\n author,\n rehostPolicy: 'cache-allowed',\n jurisdiction,\n editorialOnly,\n raw: { sourceTerms: '', sourceUrl: canonicalUrl },\n }\n const verdict: Verdict = evaluateUse(rights, intent, { userJurisdiction })\n const attribution =\n verdict.decision === 'allowed-with-attribution'\n ? buildAttribution({ license, licenseVersion: version, author, title, canonicalUrl })\n : undefined\n const summary = `${verdict.decision}: ${verdict.reasons.join('; ') || 'license facts allow this use'}`\n return {\n content: [{ type: 'text', text: summary }],\n structuredContent: {\n decision: verdict.decision,\n reasons: verdict.reasons,\n confidence: verdict.confidence,\n disclaimer: verdict.disclaimer,\n ...(attribution ? { attribution } : {}),\n },\n }\n },\n )\n\n server.registerTool(\n 'build_attribution',\n {\n title: 'Build an attribution credit line',\n description:\n 'Mechanically derive an attribution credit line (plain text + HTML) from a license id + author + title + ' +\n 'canonicalUrl. `required` is false when the license needs no attribution (e.g. CC0, PD).',\n inputSchema: {\n license: z.enum(LICENSE_IDS),\n licenseVersion: z.string().optional().describe('precise CC version, e.g. \"4.0\" — appended to the license name'),\n author: z.string().optional(),\n title: z.string().optional(),\n canonicalUrl: z.string(),\n },\n outputSchema: attributionOutputSchema,\n },\n async ({ license, licenseVersion, author, title, canonicalUrl }) => {\n const version = ccVersionFor(license, licenseVersion)\n const attribution: Attribution = buildAttribution({ license, licenseVersion: version, author, title, canonicalUrl })\n return {\n content: [{ type: 'text', text: attribution.required ? (attribution.text ?? '') : 'No attribution required for this license.' }],\n structuredContent: { required: attribution.required, text: attribution.text, html: attribution.html },\n }\n },\n )\n\n return server\n}\n\n/** Run the refkit MCP server over stdio (host wires the RefkitClient + its providers/keys). */\nexport async function serveStdio(refkit: RefkitClient): Promise<void> {\n const server = createRefkitMcpServer(refkit)\n await server.connect(new StdioServerTransport())\n}\n"],"mappings":";AAAA,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAClB,SAAS,aAAa,SAAS,aAAa,kBAAkB,cAAc,uBAAuB;AAGnG,IAAM,aAAa,CAAC,SAAS,SAAS,SAAS,MAAM;AACrD,IAAM,eAAe,CAAC,aAAa,YAAY,QAAQ;AACvD,IAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,gBAAgB,EAAE,OAAO;AAAA,EAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,aAAa,EAAE,KAAK,YAAY,EAAE,SAAS;AAAA,EAC3C,UAAU,EAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AACD,IAAM,yBAAyB,EAAE,KAAK,mBAAmB;AAEzD,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACpC,aAAa,EAAE,KAAK,YAAY,EAAE,SAAS;AAAA,EAC3C,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,EAC9B,MAAM,EAAE,KAAK,CAAC,aAAa,UAAU,WAAW,aAAa,CAAC,EAAE,SAAS;AAAA,EACzE,QAAQ,EAAE,KAAK,CAAC,UAAU,YAAY,KAAK,CAAC,EAAE,SAAS;AAAA,EACvD,SAAS,EAAE,OAAO;AAAA,IAChB,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA,IACjC,cAAc,EAAE,QAAQ,EAAE,SAAS;AAAA,IACnC,cAAc,EAAE,QAAQ,EAAE,SAAS;AAAA,EACrC,CAAC,EAAE,SAAS;AAAA,EACZ,OAAO,EAAE,OAAO;AAAA,IACd,MAAM,EAAE,KAAK,CAAC,SAAS,gBAAgB,UAAU,QAAQ,WAAW,CAAC,EAAE,SAAS;AAAA,IAChF,MAAM,EAAE,KAAK,CAAC,SAAS,UAAU,OAAO,CAAC,EAAE,SAAS;AAAA,IACpD,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,IAClD,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,IACnD,UAAU,EAAE,KAAK,CAAC,SAAS,UAAU,MAAM,CAAC,EAAE,SAAS;AAAA,EACzD,CAAC,EAAE,SAAS;AAAA,EACZ,SAAS,EAAE,OAAO;AAAA,IAChB,IAAI,EAAE,OAAO,EAAE,SAAS;AAAA,IACxB,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,CAAC,EAAE,SAAS;AAAA,EACZ,MAAM,EAAE,OAAO;AAAA,IACb,WAAW,EAAE,KAAK,CAAC,iBAAiB,eAAe,KAAK,CAAC,EAAE,SAAS;AAAA,EACtE,CAAC,EAAE,SAAS;AAAA,EACZ,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAC7C,CAAC;AAED,IAAM,4BAA4B,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,GAAG,EAAE,QAAQ,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACpG,IAAM,wBAAwB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,yBAAyB,CAAC;AAIlG,IAAM,WAAmB,MAAM;AAC7B,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,IAAI,IAAI,mBAAmB,YAAY,GAAG,GAAG,MAAM,CAAC,EAAE;AAAA,EACvF,QAAQ;AACN,WAAO;AAAA,EACT;AACF,GAAG;AAKH,SAAS,WAAW,GAAc,YAA6D;AAC7F,QAAM,OAAO;AAAA,IACX,IAAI,EAAE;AAAA,IACN,OAAO,EAAE;AAAA,IACT,UAAU,EAAE;AAAA,IACZ,UAAU,EAAE,OAAO;AAAA,IACnB,cAAc,EAAE;AAAA,IAChB,SAAS,EAAE,OAAO;AAAA,IAClB,WAAW,EAAE,WAAW;AAAA,IACxB,SAAS,EAAE,MAAM;AAAA,EACnB;AACA,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,EAAE,SAAS,YAAY,IAAI;AACjC,QAAM,SAAS,QAAQ,QAAQ,KAAK,IAAI;AACxC,QAAM,iBAAiB,GAAG,QAAQ,QAAQ,KAAK,UAAU,8BAA8B,GAAG,YAAY,YAAY,YAAY,OAAO,0BAA0B,YAAY,IAAI,KAAK,EAAE;AACtL,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,EAAE,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,KAAK,IAAI,GAAG,YAAY,QAAQ,WAAW;AAAA,IAC7G;AAAA,IACA,GAAI,YAAY,YAAY,YAAY,OAAO,EAAE,aAAa,YAAY,KAAK,IAAI,CAAC;AAAA,EACtF;AACF;AAEA,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,IAAI,EAAE,OAAO;AAAA,EACb,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,UAAU,EAAE,OAAO;AAAA,EACnB,UAAU,EAAE,OAAO;AAAA,EACnB,cAAc,EAAE,OAAO;AAAA,EACvB,SAAS,EAAE,OAAO;AAAA,EAClB,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,YAAY,EACT,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,GAAG,YAAY,EAAE,OAAO,EAAE,CAAC,EAC3E,SAAS,EACT,SAAS,kGAAkG;AAAA,EAC9G,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,EAC9F,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yEAAyE;AACvH,CAAC;AAED,IAAM,mBAA0C,EAAE,OAAO;AAAA,EACvD,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,MAAM,EAAE,KAAK,UAAU,CAAC;AAAA,EACtC,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,OAAO;AAAA,EACrB,YAAY,EAAE,OAAO;AAAA,EACrB,gBAAgB,cAAc,SAAS;AAAA,EACvC,UAAU,EAAE,OAAO;AAAA,IACjB,WAAW,EAAE,MAAM,sBAAsB;AAAA,IACzC,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAAA,IACvE,mBAAmB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAAA,EACzE,CAAC,EAAE,SAAS;AAAA,EACZ,iBAAiB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC9C,WAAW,EAAE,MAAM,EAAE,OAAO;AAAA,IAC1B,YAAY,EAAE,OAAO;AAAA,IACrB,QAAQ,EAAE,KAAK,CAAC,aAAa,UAAU,SAAS,CAAC;AAAA,IACjD,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,QAAQ,EAAE,KAAK,CAAC,sBAAsB,CAAC,EAAE,SAAS;AAAA,IAClD,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,QAAQ,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,CAAC,CAAC;AAAA,EACF,MAAM,EAAE,OAAO;AAAA,IACb,QAAQ,EAAE,KAAK,OAAO;AAAA,IACtB,QAAQ,EAAE,OAAO;AAAA,IACjB,OAAO,EAAE,OAAO;AAAA,IAChB,SAAS,EAAE,OAAO;AAAA,EACpB,CAAC,EAAE,SAAS;AAAA,EACZ,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6FAA6F;AAAA,EACxI,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAC9B,CAAC;AAGM,SAAS,sBAAsB,QAAiC;AACrE,QAAM,SAAS,IAAI,UAAU,EAAE,MAAM,UAAU,SAAS,QAAQ,CAAC;AAEjE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAIF,aAAa;AAAA,QACX,OAAO,EAAE,OAAO,EAAE,SAAS,qDAAqD;AAAA,QAChF,YAAY,EAAE,MAAM,EAAE,KAAK,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,QAC/E,SAAS,cAAc,SAAS,EAAE,SAAS,qFAAqF;AAAA,QAChI,UAAU,qBAAqB,SAAS,EAAE,SAAS,0HAA0H;AAAA,QAC7K,iBAAiB,sBAAsB,SAAS,EAAE,SAAS,iGAAiG;AAAA,QAC5J,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+GAA+G;AAAA,QACxJ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,QAC5C,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kHAA8G;AAAA,QACrJ,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,oIAAoI;AAAA,QAC5K,QAAQ,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,SAAS,8EAA8E;AAAA,QAC1H,SAAS,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,MAC3G;AAAA,MACA,cAAc;AAAA,QACZ,YAAY,EAAE,MAAM,cAAc;AAAA,QAClC,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,QACzG,MAAM,iBAAiB,SAAS;AAAA,MAClC;AAAA,IACF;AAAA,IACA,OAAO,EAAE,OAAO,YAAY,SAAS,UAAU,iBAAiB,SAAS,OAAO,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AACpH,YAAM,cAAc;AAAA,QAClB;AAAA,QACA,YAAY,cAAc,CAAC,OAAO;AAAA,QAClC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,SAAS,EAAE,QAAQ,gBAAgB,EAAE,IAAI,CAAC;AAAA,QAC9C;AAAA,MACF;AAGA,YAAM,SAAS,MAAM,OAAO,eAAe,WAAW;AACtD,YAAM,OAAO,OAAO;AACpB,YAAM,eAAe,UAAU;AAC/B,YAAM,aAAa,KAAK;AAAA,QAAI,OAC1B,eACI,WAAW,GAAG,EAAE,SAAS,OAAO,YAAY,GAAG,YAAY,GAAG,aAAa,OAAO,iBAAiB,CAAC,EAAE,CAAC,IACvG,WAAW,CAAC;AAAA,MAClB;AACA,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,WAAW,MAAM,sBAAsB,KAAK,KAAK,CAAC;AAAA,QACrF,mBAAmB;AAAA,UACjB;AAAA,UACA,GAAI,OAAO,KAAK,aAAa,EAAE,YAAY,OAAO,KAAK,WAAW,IAAI,CAAC;AAAA,UACvE,GAAI,UAAU,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,0BAA0B,EAAE,UAAU,EAAE,QAAQ,GAAG,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE;AAElH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAGF,aAAa;AAAA,QACX,SAAS,EAAE,KAAK,WAAW,EAAE,SAAS,4BAA6B;AAAA,QACnE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAAmD;AAAA,QAClG,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,QAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,QAC3B,cAAc,EAAE,OAAO,EAAE,SAAS,kDAAkD;AAAA,QACpF,QAAQ,EAAE,KAAK,OAAO,EAAE,SAAS,mDAAmD;AAAA,QACpF,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,QAC7E,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,QACtG,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yEAA0E;AAAA,MAC7H;AAAA,MACA,cAAc;AAAA,QACZ,UAAU,EAAE,KAAK,CAAC,WAAW,4BAA4B,UAAU,cAAc,CAAC;AAAA,QAClF,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,QAC3B,YAAY,EAAE,KAAK,CAAC,QAAQ,KAAK,CAAC;AAAA,QAClC,YAAY,EAAE,OAAO;AAAA,QACrB,aAAa,EAAE,OAAO,uBAAuB,EAAE,SAAS;AAAA,MAC1D;AAAA,IACF;AAAA,IACA,OAAO,EAAE,SAAS,gBAAgB,QAAQ,OAAO,cAAc,QAAQ,eAAe,cAAc,iBAAiB,MAAM;AACzH,YAAM,UAAU,aAAa,SAAS,cAAc;AACpD,YAAM,SAAuB;AAAA,QAC3B;AAAA,QACA,gBAAgB;AAAA,QAChB;AAAA,QACA,cAAc;AAAA,QACd;AAAA,QACA;AAAA,QACA,KAAK,EAAE,aAAa,IAAI,WAAW,aAAa;AAAA,MAClD;AACA,YAAM,UAAmB,YAAY,QAAQ,QAAQ,EAAE,iBAAiB,CAAC;AACzE,YAAM,cACJ,QAAQ,aAAa,6BACjB,iBAAiB,EAAE,SAAS,gBAAgB,SAAS,QAAQ,OAAO,aAAa,CAAC,IAClF;AACN,YAAM,UAAU,GAAG,QAAQ,QAAQ,KAAK,QAAQ,QAAQ,KAAK,IAAI,KAAK,8BAA8B;AACpG,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAAA,QACzC,mBAAmB;AAAA,UACjB,UAAU,QAAQ;AAAA,UAClB,SAAS,QAAQ;AAAA,UACjB,YAAY,QAAQ;AAAA,UACpB,YAAY,QAAQ;AAAA,UACpB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aACE;AAAA,MAEF,aAAa;AAAA,QACX,SAAS,EAAE,KAAK,WAAW;AAAA,QAC3B,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oEAA+D;AAAA,QAC9G,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,QAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,QAC3B,cAAc,EAAE,OAAO;AAAA,MACzB;AAAA,MACA,cAAc;AAAA,IAChB;AAAA,IACA,OAAO,EAAE,SAAS,gBAAgB,QAAQ,OAAO,aAAa,MAAM;AAClE,YAAM,UAAU,aAAa,SAAS,cAAc;AACpD,YAAM,cAA2B,iBAAiB,EAAE,SAAS,gBAAgB,SAAS,QAAQ,OAAO,aAAa,CAAC;AACnH,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,YAAY,WAAY,YAAY,QAAQ,KAAM,4CAA4C,CAAC;AAAA,QAC/H,mBAAmB,EAAE,UAAU,YAAY,UAAU,MAAM,YAAY,MAAM,MAAM,YAAY,KAAK;AAAA,MACtG;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGA,eAAsB,WAAW,QAAqC;AACpE,QAAM,SAAS,sBAAsB,MAAM;AAC3C,QAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;AACjD;","names":[]}