@refkit/mcp 0.2.0 → 0.3.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
@@ -40,12 +40,29 @@ await serveStdio(createRefkit({
40
40
 
41
41
  ## The `search_references` tool
42
42
 
43
- Input: `{ query, modalities?, limit?, intent?, gateFor? }`.
43
+ Input: `{ query, modalities?, controls?, filters?, providerOptions?, explain?, limit?, intent?, gateFor? }`.
44
44
 
45
+ - `controls` — provider-neutral search controls such as `{ orientation, color, language, sort, safety, license, media }`; providers translate supported controls and report ignored controls when `explain: true`.
45
46
  - `intent` — annotate each result with a **use-verdict** for that intended use (no filtering).
46
47
  - `gateFor` — return only results whose license allows that intent.
48
+ - `filters` — compatibility alias for `controls.orientation`, `controls.color`, and `controls.language`.
49
+ - `explain` — include provider status, applied and ignored unified controls, warnings, and gate/drop metadata.
50
+ - `providerOptions` — typed provider-specific whitelisted controls keyed by provider id, for example:
47
51
 
48
- Output: `{ references: [{ id, title?, modality, provider, canonicalUrl, license, thumbnail?, excerpt?, useVerdict?, attribution? }] }`. When `intent` (or `gateFor`) is set, each result carries `useVerdict { decision, reason, confidence }` and — if the license requires it — a ready-to-use `attribution` credit line.
52
+ ```json
53
+ {
54
+ "query": "forest path",
55
+ "modalities": ["image"],
56
+ "controls": { "orientation": "landscape", "color": "green", "safety": "strict" },
57
+ "providerOptions": {
58
+ "unsplash": { "collections": ["abc", "def"], "page": 2 },
59
+ "flickr": { "tags": ["forest", "path"], "tagMode": "all", "minTakenDate": "2020-01-01" },
60
+ "brave": { "country": "US", "searchLang": "en" }
61
+ }
62
+ }
63
+ ```
64
+
65
+ Output: `{ references: [{ id, title?, modality, provider, canonicalUrl, license, thumbnail?, excerpt?, useVerdict?, useExplanation?, attribution? }], meta? }`. When `intent` (or `gateFor`) is set, each result carries `useVerdict { decision, reason, confidence }`, a plain `useExplanation`, and — if the license requires it — a ready-to-use `attribution` credit line. When `explain: true`, `meta` includes per-provider `fulfilled` / `failed` / `skipped` status, applied/ignored control details, warnings, and gate/drop counts.
49
66
 
50
67
  > Results are references with a license id + source link — **not rights clearance, not legal advice**. `unknown` / `needs-review` results require the caller to verify the source's terms.
51
68
 
@@ -0,0 +1,188 @@
1
+ // src/index.ts
2
+ import { readFileSync } from "fs";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { z } from "zod";
6
+ var MODALITIES = ["image", "video", "audio", "text"];
7
+ var INTENTS = ["internal-moodboard", "commercial-product", "ai-generation-input", "redistribution"];
8
+ var ORIENTATIONS = ["landscape", "portrait", "square"];
9
+ var SEARCH_CONTROL_KEYS = [
10
+ "orientation",
11
+ "color",
12
+ "language",
13
+ "sort",
14
+ "safety",
15
+ "license.commercial",
16
+ "license.modification",
17
+ "license.allowUnknown",
18
+ "media.kind",
19
+ "media.size",
20
+ "media.minWidth",
21
+ "media.minHeight",
22
+ "media.duration",
23
+ "creator.id",
24
+ "creator.name",
25
+ "text.copyright",
26
+ "page"
27
+ ];
28
+ var filtersSchema = z.object({
29
+ color: z.string().optional(),
30
+ orientation: z.enum(ORIENTATIONS).optional(),
31
+ language: z.string().optional()
32
+ });
33
+ 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
+ });
61
+ var providerOptionValueSchema = z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]);
62
+ var providerOptionsSchema = z.record(z.string(), z.record(z.string(), providerOptionValueSchema));
63
+ var VERSION = (() => {
64
+ try {
65
+ return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
66
+ } catch {
67
+ return "0.0.0";
68
+ }
69
+ })();
70
+ function toAgentRef(r, assessment) {
71
+ const base = {
72
+ id: r.id,
73
+ title: r.title,
74
+ modality: r.modality,
75
+ provider: r.source.providerId,
76
+ canonicalUrl: r.canonicalUrl,
77
+ license: r.rights.license,
78
+ thumbnail: r.thumbnail?.url,
79
+ excerpt: r.text?.excerpt
80
+ };
81
+ if (!assessment) return base;
82
+ const { verdict, attribution } = assessment;
83
+ const reason = verdict.reasons.join("; ");
84
+ const useExplanation = `${verdict.decision}: ${reason || "license facts allow this use"}${attribution.required && attribution.text ? ` Attribution required: ${attribution.text}` : ""}`;
85
+ return {
86
+ ...base,
87
+ useVerdict: { decision: verdict.decision, reason: verdict.reasons.join("; "), confidence: verdict.confidence },
88
+ useExplanation,
89
+ ...attribution.required && attribution.text ? { attribution: attribution.text } : {}
90
+ };
91
+ }
92
+ var agentRefSchema = z.object({
93
+ id: z.string(),
94
+ title: z.string().optional(),
95
+ modality: z.string(),
96
+ provider: z.string(),
97
+ canonicalUrl: z.string(),
98
+ license: z.string(),
99
+ thumbnail: z.string().optional(),
100
+ excerpt: z.string().optional(),
101
+ useVerdict: z.object({ decision: z.string(), reason: z.string(), confidence: z.string() }).optional().describe("present when `intent` (or `gateFor`) is set: may this be used for that intent, and how confident"),
102
+ useExplanation: z.string().optional().describe("plain-language use verdict summary for agents"),
103
+ attribution: z.string().optional().describe("ready-to-use credit line; present when the license requires attribution")
104
+ });
105
+ var searchMetaSchema = z.object({
106
+ query: z.string(),
107
+ modalities: z.array(z.enum(MODALITIES)),
108
+ limit: z.number(),
109
+ poolFactor: z.number(),
110
+ fetchLimit: z.number(),
111
+ appliedFilters: filtersSchema.optional(),
112
+ controls: z.object({
113
+ requested: z.array(searchControlKeySchema),
114
+ appliedByProvider: z.record(z.string(), z.array(searchControlKeySchema)),
115
+ ignoredByProvider: z.record(z.string(), z.array(searchControlKeySchema))
116
+ }).optional(),
117
+ providerOptions: z.array(z.string()).optional(),
118
+ providers: z.array(z.object({
119
+ providerId: z.string(),
120
+ status: z.enum(["fulfilled", "failed", "skipped"]),
121
+ returned: z.number().optional(),
122
+ accepted: z.number().optional(),
123
+ rejected: z.number().optional(),
124
+ reason: z.enum(["unsupported-modality"]).optional(),
125
+ error: z.string().optional()
126
+ })),
127
+ gate: z.object({
128
+ intent: z.enum(INTENTS),
129
+ before: z.number(),
130
+ after: z.number(),
131
+ dropped: z.number()
132
+ }).optional(),
133
+ warnings: z.array(z.string())
134
+ });
135
+ function createRefkitMcpServer(refkit) {
136
+ const server = new McpServer({ name: "refkit", version: VERSION });
137
+ server.registerTool(
138
+ "search_references",
139
+ {
140
+ title: "Search creative references",
141
+ 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.",
142
+ inputSchema: {
143
+ query: z.string().describe('what to search for, e.g. "cyberpunk alley at night"'),
144
+ modalities: z.array(z.enum(MODALITIES)).optional().describe('default ["image"]'),
145
+ filters: filtersSchema.optional().describe("compatibility alias for controls.orientation, controls.color, and controls.language"),
146
+ controls: searchControlsSchema.optional().describe("provider-neutral search controls; providers translate supported controls and report ignored controls in explain metadata"),
147
+ providerOptions: providerOptionsSchema.optional().describe("provider-specific search controls keyed by provider id; each provider whitelists supported keys"),
148
+ explain: z.boolean().optional().describe("include provider status, applied and ignored controls, warnings, and gate/drop metadata"),
149
+ limit: z.number().int().positive().optional(),
150
+ intent: z.enum(INTENTS).optional().describe("annotate each result with a use-verdict for this intended use (no filtering)"),
151
+ gateFor: z.enum(INTENTS).optional().describe("only return results whose license allows this intended use")
152
+ },
153
+ outputSchema: { references: z.array(agentRefSchema), meta: searchMetaSchema.optional() }
154
+ },
155
+ async ({ query, modalities, filters, controls, providerOptions, explain, limit, intent, gateFor }) => {
156
+ const searchInput = {
157
+ query,
158
+ modalities: modalities ?? ["image"],
159
+ filters,
160
+ controls,
161
+ providerOptions,
162
+ limit,
163
+ gateFor
164
+ };
165
+ const result = explain ? await refkit.searchWithMeta(searchInput) : { references: await refkit.search(searchInput), meta: void 0 };
166
+ const refs = result.references;
167
+ const assessIntent = intent ?? gateFor;
168
+ const references = refs.map(
169
+ (r) => assessIntent ? toAgentRef(r, { verdict: refkit.evaluateUse(r, assessIntent), attribution: refkit.buildAttribution(r) }) : toAgentRef(r)
170
+ );
171
+ return {
172
+ content: [{ type: "text", text: `${references.length} reference(s) for "${query}".` }],
173
+ structuredContent: { references, ...result.meta ? { meta: result.meta } : {} }
174
+ };
175
+ }
176
+ );
177
+ return server;
178
+ }
179
+ async function serveStdio(refkit) {
180
+ const server = createRefkitMcpServer(refkit);
181
+ await server.connect(new StdioServerTransport());
182
+ }
183
+
184
+ export {
185
+ createRefkitMcpServer,
186
+ serveStdio
187
+ };
188
+ //# sourceMappingURL=chunk-B5SVJVI4.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 type { RefkitClient, Reference, Verdict, Attribution, SearchFilters, SearchControls, SearchControlKey, ProviderOptionsById, SearchMeta } from '@refkit/core'\n\nconst MODALITIES = ['image', 'video', 'audio', 'text'] as const\nconst INTENTS = ['internal-moodboard', 'commercial-product', 'ai-generation-input', 'redistribution'] 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 })),\n gate: z.object({\n intent: z.enum(INTENTS),\n before: z.number(),\n after: z.number(),\n dropped: z.number(),\n }).optional(),\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, and gate/drop metadata'),\n limit: z.number().int().positive().optional(),\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: { references: z.array(agentRefSchema), meta: searchMetaSchema.optional() },\n },\n async ({ query, modalities, filters, controls, providerOptions, explain, limit, 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 gateFor,\n }\n const result = explain ? await refkit.searchWithMeta(searchInput) : { references: await refkit.search(searchInput), meta: undefined }\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: { references, ...(result.meta ? { meta: result.meta } : {}) },\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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  serveStdio
4
- } from "./chunk-RHYDE2DW.js";
4
+ } from "./chunk-B5SVJVI4.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { realpathSync } from "fs";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRefkitMcpServer,
3
3
  serveStdio
4
- } from "./chunk-RHYDE2DW.js";
4
+ } from "./chunk-B5SVJVI4.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.2.0",
3
+ "version": "0.3.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",
@@ -27,19 +27,19 @@
27
27
  "dependencies": {
28
28
  "@modelcontextprotocol/sdk": "^1.29.0",
29
29
  "zod": "^4.3.6",
30
- "@refkit/core": "0.3.0",
31
- "@refkit/provider-artic": "0.1.2",
32
- "@refkit/provider-gutendex": "0.1.2",
33
- "@refkit/provider-brave": "0.1.2",
34
- "@refkit/provider-flickr": "0.1.2",
35
- "@refkit/provider-met": "0.1.2",
36
- "@refkit/provider-openverse": "0.1.2",
37
- "@refkit/provider-pexels": "0.1.2",
38
- "@refkit/provider-pixabay": "0.1.2",
39
- "@refkit/provider-poetrydb": "0.1.2",
40
- "@refkit/provider-smithsonian": "0.1.2",
41
- "@refkit/provider-wikimedia-commons": "0.1.2",
42
- "@refkit/provider-unsplash": "0.1.2"
30
+ "@refkit/core": "0.4.0",
31
+ "@refkit/provider-artic": "0.2.0",
32
+ "@refkit/provider-brave": "0.2.0",
33
+ "@refkit/provider-flickr": "0.2.0",
34
+ "@refkit/provider-gutendex": "0.2.0",
35
+ "@refkit/provider-met": "0.2.0",
36
+ "@refkit/provider-openverse": "0.2.0",
37
+ "@refkit/provider-pexels": "0.2.0",
38
+ "@refkit/provider-pixabay": "0.2.0",
39
+ "@refkit/provider-poetrydb": "0.2.0",
40
+ "@refkit/provider-smithsonian": "0.2.0",
41
+ "@refkit/provider-unsplash": "0.2.0",
42
+ "@refkit/provider-wikimedia-commons": "0.2.0"
43
43
  },
44
44
  "files": [
45
45
  "dist",
@@ -1,85 +0,0 @@
1
- // src/index.ts
2
- import { readFileSync } from "fs";
3
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import { z } from "zod";
6
- var MODALITIES = ["image", "video", "audio", "text"];
7
- var INTENTS = ["internal-moodboard", "commercial-product", "ai-generation-input", "redistribution"];
8
- var VERSION = (() => {
9
- try {
10
- return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
11
- } catch {
12
- return "0.0.0";
13
- }
14
- })();
15
- function toAgentRef(r, assessment) {
16
- const base = {
17
- id: r.id,
18
- title: r.title,
19
- modality: r.modality,
20
- provider: r.source.providerId,
21
- canonicalUrl: r.canonicalUrl,
22
- license: r.rights.license,
23
- thumbnail: r.thumbnail?.url,
24
- excerpt: r.text?.excerpt
25
- };
26
- if (!assessment) return base;
27
- const { verdict, attribution } = assessment;
28
- return {
29
- ...base,
30
- useVerdict: { decision: verdict.decision, reason: verdict.reasons.join("; "), confidence: verdict.confidence },
31
- ...attribution.required && attribution.text ? { attribution: attribution.text } : {}
32
- };
33
- }
34
- var agentRefSchema = z.object({
35
- id: z.string(),
36
- title: z.string().optional(),
37
- modality: z.string(),
38
- provider: z.string(),
39
- canonicalUrl: z.string(),
40
- license: z.string(),
41
- thumbnail: z.string().optional(),
42
- excerpt: z.string().optional(),
43
- useVerdict: z.object({ decision: z.string(), reason: z.string(), confidence: z.string() }).optional().describe("present when `intent` (or `gateFor`) is set: may this be used for that intent, and how confident"),
44
- attribution: z.string().optional().describe("ready-to-use credit line; present when the license requires attribution")
45
- });
46
- function createRefkitMcpServer(refkit) {
47
- const server = new McpServer({ name: "refkit", version: VERSION });
48
- server.registerTool(
49
- "search_references",
50
- {
51
- title: "Search creative references",
52
- 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.",
53
- inputSchema: {
54
- query: z.string().describe('what to search for, e.g. "cyberpunk alley at night"'),
55
- modalities: z.array(z.enum(MODALITIES)).optional().describe('default ["image"]'),
56
- limit: z.number().int().positive().optional(),
57
- intent: z.enum(INTENTS).optional().describe("annotate each result with a use-verdict for this intended use (no filtering)"),
58
- gateFor: z.enum(INTENTS).optional().describe("only return results whose license allows this intended use")
59
- },
60
- outputSchema: { references: z.array(agentRefSchema) }
61
- },
62
- async ({ query, modalities, limit, intent, gateFor }) => {
63
- const refs = await refkit.search({ query, modalities: modalities ?? ["image"], limit, gateFor });
64
- const assessIntent = intent ?? gateFor;
65
- const references = refs.map(
66
- (r) => assessIntent ? toAgentRef(r, { verdict: refkit.evaluateUse(r, assessIntent), attribution: refkit.buildAttribution(r) }) : toAgentRef(r)
67
- );
68
- return {
69
- content: [{ type: "text", text: `${references.length} reference(s) for "${query}".` }],
70
- structuredContent: { references }
71
- };
72
- }
73
- );
74
- return server;
75
- }
76
- async function serveStdio(refkit) {
77
- const server = createRefkitMcpServer(refkit);
78
- await server.connect(new StdioServerTransport());
79
- }
80
-
81
- export {
82
- createRefkitMcpServer,
83
- serveStdio
84
- };
85
- //# sourceMappingURL=chunk-RHYDE2DW.js.map
@@ -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 type { RefkitClient, Reference, Verdict, Attribution } from '@refkit/core'\n\nconst MODALITIES = ['image', 'video', 'audio', 'text'] as const\nconst INTENTS = ['internal-moodboard', 'commercial-product', 'ai-generation-input', 'redistribution'] as const\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 return {\n ...base,\n useVerdict: { decision: verdict.decision, reason: verdict.reasons.join('; '), confidence: verdict.confidence },\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 attribution: z.string().optional().describe('ready-to-use credit line; present when the license requires attribution'),\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 limit: z.number().int().positive().optional(),\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: { references: z.array(agentRefSchema) },\n },\n async ({ query, modalities, limit, intent, gateFor }) => {\n const refs = await refkit.search({ query, modalities: modalities ?? ['image'], limit, gateFor })\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: { references },\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":[]}