@refkit/mcp 0.2.0 → 0.4.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 +19 -2
- package/dist/chunk-B5SVJVI4.js +188 -0
- package/dist/chunk-B5SVJVI4.js.map +1 -0
- package/dist/cli.js +15 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +20 -14
- package/dist/chunk-RHYDE2DW.js +0 -85
- package/dist/chunk-RHYDE2DW.js.map +0 -1
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
|
-
|
|
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-
|
|
4
|
+
} from "./chunk-B5SVJVI4.js";
|
|
5
5
|
|
|
6
6
|
// src/cli.ts
|
|
7
7
|
import { realpathSync } from "fs";
|
|
@@ -19,6 +19,12 @@ import { pixabay, pixabayVideo } from "@refkit/provider-pixabay";
|
|
|
19
19
|
import { flickr } from "@refkit/provider-flickr";
|
|
20
20
|
import { smithsonian } from "@refkit/provider-smithsonian";
|
|
21
21
|
import { brave } from "@refkit/provider-brave";
|
|
22
|
+
import { rijksmuseum } from "@refkit/provider-rijksmuseum";
|
|
23
|
+
import { polyhaven, ambientcg } from "@refkit/provider-polyhaven";
|
|
24
|
+
import { freesound } from "@refkit/provider-freesound";
|
|
25
|
+
import { jamendo } from "@refkit/provider-jamendo";
|
|
26
|
+
import { europeana } from "@refkit/provider-europeana";
|
|
27
|
+
import { internetArchive } from "@refkit/provider-internet-archive";
|
|
22
28
|
function defaultProviders(env = process.env) {
|
|
23
29
|
const providers = [
|
|
24
30
|
openverse(),
|
|
@@ -27,7 +33,11 @@ function defaultProviders(env = process.env) {
|
|
|
27
33
|
met(),
|
|
28
34
|
artic(),
|
|
29
35
|
gutendex(),
|
|
30
|
-
poetrydb()
|
|
36
|
+
poetrydb(),
|
|
37
|
+
rijksmuseum(),
|
|
38
|
+
polyhaven(),
|
|
39
|
+
ambientcg(),
|
|
40
|
+
internetArchive()
|
|
31
41
|
];
|
|
32
42
|
if (env.UNSPLASH_KEY) providers.push(unsplash({ accessKey: env.UNSPLASH_KEY }));
|
|
33
43
|
if (env.PEXELS_KEY) providers.push(pexels({ apiKey: env.PEXELS_KEY }), pexelsVideo({ apiKey: env.PEXELS_KEY }));
|
|
@@ -35,6 +45,9 @@ function defaultProviders(env = process.env) {
|
|
|
35
45
|
if (env.FLICKR_KEY) providers.push(flickr({ apiKey: env.FLICKR_KEY }));
|
|
36
46
|
if (env.SI_KEY) providers.push(smithsonian({ apiKey: env.SI_KEY }));
|
|
37
47
|
if (env.BRAVE_TOKEN) providers.push(brave({ token: env.BRAVE_TOKEN }));
|
|
48
|
+
if (env.FREESOUND_TOKEN) providers.push(freesound({ apiKey: env.FREESOUND_TOKEN }));
|
|
49
|
+
if (env.JAMENDO_CLIENT_ID) providers.push(jamendo({ clientId: env.JAMENDO_CLIENT_ID }));
|
|
50
|
+
if (env.EUROPEANA_KEY) providers.push(europeana({ apiKey: env.EUROPEANA_KEY }));
|
|
38
51
|
return providers;
|
|
39
52
|
}
|
|
40
53
|
var isEntry = (() => {
|
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 { unsplash } from '@refkit/provider-unsplash'\nimport { pexels, pexelsVideo } from '@refkit/provider-pexels'\nimport { pixabay, pixabayVideo } from '@refkit/provider-pixabay'\nimport { flickr } from '@refkit/provider-flickr'\nimport { smithsonian } from '@refkit/provider-smithsonian'\nimport { brave } from '@refkit/provider-brave'\nimport { serveStdio } from './index'\n\n/** Providers a zero-config server boots with: all keyless sources, plus any BYOK\n * source whose key is present in `env`. Exported so the wiring is unit-testable. */\nexport function defaultProviders(env: NodeJS.ProcessEnv = process.env): ReferenceProvider[] {\n const providers: ReferenceProvider[] = [\n openverse(), openverseAudio(), wikimediaCommons(), met(), artic(), gutendex(), poetrydb(),\n ]\n if (env.UNSPLASH_KEY) providers.push(unsplash({ accessKey: env.UNSPLASH_KEY }))\n if (env.PEXELS_KEY) providers.push(pexels({ apiKey: env.PEXELS_KEY }), pexelsVideo({ apiKey: env.PEXELS_KEY }))\n if (env.PIXABAY_KEY) providers.push(pixabay({ key: env.PIXABAY_KEY }), pixabayVideo({ key: env.PIXABAY_KEY }))\n if (env.FLICKR_KEY) providers.push(flickr({ apiKey: env.FLICKR_KEY }))\n if (env.SI_KEY) providers.push(smithsonian({ apiKey: env.SI_KEY }))\n if (env.BRAVE_TOKEN) providers.push(brave({ token: env.BRAVE_TOKEN }))\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: defaultProviders() }))\n}\n"],"mappings":";;;;;;AAGA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,oBAA4C;AACrD,SAAS,WAAW,sBAAsB;AAC1C,SAAS,wBAAwB;AACjC,SAAS,WAAW;AACpB,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,QAAQ,mBAAmB;AACpC,SAAS,SAAS,oBAAoB;AACtC,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAC5B,SAAS,aAAa;
|
|
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 { unsplash } from '@refkit/provider-unsplash'\nimport { pexels, pexelsVideo } from '@refkit/provider-pexels'\nimport { pixabay, pixabayVideo } from '@refkit/provider-pixabay'\nimport { flickr } from '@refkit/provider-flickr'\nimport { smithsonian } from '@refkit/provider-smithsonian'\nimport { brave } from '@refkit/provider-brave'\nimport { rijksmuseum } from '@refkit/provider-rijksmuseum'\nimport { polyhaven, ambientcg } from '@refkit/provider-polyhaven'\nimport { freesound } from '@refkit/provider-freesound'\nimport { jamendo } from '@refkit/provider-jamendo'\nimport { europeana } from '@refkit/provider-europeana'\nimport { internetArchive } from '@refkit/provider-internet-archive'\nimport { serveStdio } from './index'\n\n/** Providers a zero-config server boots with: all keyless sources, plus any BYOK\n * source whose key is present in `env`. Exported so the wiring is unit-testable. */\nexport function defaultProviders(env: NodeJS.ProcessEnv = process.env): ReferenceProvider[] {\n const providers: ReferenceProvider[] = [\n openverse(), openverseAudio(), wikimediaCommons(), met(), artic(), gutendex(), poetrydb(),\n rijksmuseum(), polyhaven(), ambientcg(), internetArchive(),\n ]\n if (env.UNSPLASH_KEY) providers.push(unsplash({ accessKey: env.UNSPLASH_KEY }))\n if (env.PEXELS_KEY) providers.push(pexels({ apiKey: env.PEXELS_KEY }), pexelsVideo({ apiKey: env.PEXELS_KEY }))\n if (env.PIXABAY_KEY) providers.push(pixabay({ key: env.PIXABAY_KEY }), pixabayVideo({ key: env.PIXABAY_KEY }))\n if (env.FLICKR_KEY) providers.push(flickr({ apiKey: env.FLICKR_KEY }))\n if (env.SI_KEY) providers.push(smithsonian({ apiKey: env.SI_KEY }))\n if (env.BRAVE_TOKEN) providers.push(brave({ token: env.BRAVE_TOKEN }))\n if (env.FREESOUND_TOKEN) providers.push(freesound({ apiKey: env.FREESOUND_TOKEN }))\n if (env.JAMENDO_CLIENT_ID) providers.push(jamendo({ clientId: env.JAMENDO_CLIENT_ID }))\n if (env.EUROPEANA_KEY) providers.push(europeana({ apiKey: env.EUROPEANA_KEY }))\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: defaultProviders() }))\n}\n"],"mappings":";;;;;;AAGA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,oBAA4C;AACrD,SAAS,WAAW,sBAAsB;AAC1C,SAAS,wBAAwB;AACjC,SAAS,WAAW;AACpB,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,QAAQ,mBAAmB;AACpC,SAAS,SAAS,oBAAoB;AACtC,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,mBAAmB;AAC5B,SAAS,WAAW,iBAAiB;AACrC,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAKzB,SAAS,iBAAiB,MAAyB,QAAQ,KAA0B;AAC1F,QAAM,YAAiC;AAAA,IACrC,UAAU;AAAA,IAAG,eAAe;AAAA,IAAG,iBAAiB;AAAA,IAAG,IAAI;AAAA,IAAG,MAAM;AAAA,IAAG,SAAS;AAAA,IAAG,SAAS;AAAA,IACxF,YAAY;AAAA,IAAG,UAAU;AAAA,IAAG,UAAU;AAAA,IAAG,gBAAgB;AAAA,EAC3D;AACA,MAAI,IAAI,aAAc,WAAU,KAAK,SAAS,EAAE,WAAW,IAAI,aAAa,CAAC,CAAC;AAC9E,MAAI,IAAI,WAAY,WAAU,KAAK,OAAO,EAAE,QAAQ,IAAI,WAAW,CAAC,GAAG,YAAY,EAAE,QAAQ,IAAI,WAAW,CAAC,CAAC;AAC9G,MAAI,IAAI,YAAa,WAAU,KAAK,QAAQ,EAAE,KAAK,IAAI,YAAY,CAAC,GAAG,aAAa,EAAE,KAAK,IAAI,YAAY,CAAC,CAAC;AAC7G,MAAI,IAAI,WAAY,WAAU,KAAK,OAAO,EAAE,QAAQ,IAAI,WAAW,CAAC,CAAC;AACrE,MAAI,IAAI,OAAQ,WAAU,KAAK,YAAY,EAAE,QAAQ,IAAI,OAAO,CAAC,CAAC;AAClE,MAAI,IAAI,YAAa,WAAU,KAAK,MAAM,EAAE,OAAO,IAAI,YAAY,CAAC,CAAC;AACrE,MAAI,IAAI,gBAAiB,WAAU,KAAK,UAAU,EAAE,QAAQ,IAAI,gBAAgB,CAAC,CAAC;AAClF,MAAI,IAAI,kBAAmB,WAAU,KAAK,QAAQ,EAAE,UAAU,IAAI,kBAAkB,CAAC,CAAC;AACtF,MAAI,IAAI,cAAe,WAAU,KAAK,UAAU,EAAE,QAAQ,IAAI,cAAc,CAAC,CAAC;AAC9E,SAAO;AACT;AAIA,IAAM,WAAW,MAAM;AACrB,MAAI,CAAC,QAAQ,KAAK,CAAC,EAAG,QAAO;AAC7B,MAAI;AACF,WAAO,aAAa,QAAQ,KAAK,CAAC,CAAC,MAAM,cAAc,YAAY,GAAG;AAAA,EACxE,QAAQ;AACN,WAAO;AAAA,EACT;AACF,GAAG;AAEH,IAAI,SAAS;AACX,QAAM,WAAW,aAAa,EAAE,WAAW,iBAAiB,EAAE,CAAC,CAAC;AAClE;","names":[]}
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refkit/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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,25 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
29
29
|
"zod": "^4.3.6",
|
|
30
|
-
"@refkit/core": "0.
|
|
31
|
-
"@refkit/provider-artic": "0.1
|
|
32
|
-
"@refkit/provider-
|
|
33
|
-
"@refkit/provider-
|
|
34
|
-
"@refkit/provider-
|
|
35
|
-
"@refkit/provider-
|
|
36
|
-
"@refkit/provider-
|
|
37
|
-
"@refkit/provider-
|
|
38
|
-
"@refkit/provider-
|
|
39
|
-
"@refkit/provider-
|
|
40
|
-
"@refkit/provider-
|
|
41
|
-
"@refkit/provider-
|
|
42
|
-
"@refkit/provider-
|
|
30
|
+
"@refkit/core": "0.5.0",
|
|
31
|
+
"@refkit/provider-artic": "0.2.1",
|
|
32
|
+
"@refkit/provider-brave": "0.2.1",
|
|
33
|
+
"@refkit/provider-flickr": "0.2.1",
|
|
34
|
+
"@refkit/provider-europeana": "0.2.0",
|
|
35
|
+
"@refkit/provider-gutendex": "0.2.1",
|
|
36
|
+
"@refkit/provider-freesound": "0.2.0",
|
|
37
|
+
"@refkit/provider-internet-archive": "0.2.0",
|
|
38
|
+
"@refkit/provider-jamendo": "0.2.0",
|
|
39
|
+
"@refkit/provider-met": "0.2.1",
|
|
40
|
+
"@refkit/provider-pexels": "0.2.1",
|
|
41
|
+
"@refkit/provider-openverse": "0.2.1",
|
|
42
|
+
"@refkit/provider-pixabay": "0.2.1",
|
|
43
|
+
"@refkit/provider-polyhaven": "0.2.0",
|
|
44
|
+
"@refkit/provider-poetrydb": "0.2.1",
|
|
45
|
+
"@refkit/provider-rijksmuseum": "0.2.0",
|
|
46
|
+
"@refkit/provider-smithsonian": "0.2.1",
|
|
47
|
+
"@refkit/provider-unsplash": "0.2.1",
|
|
48
|
+
"@refkit/provider-wikimedia-commons": "0.2.1"
|
|
43
49
|
},
|
|
44
50
|
"files": [
|
|
45
51
|
"dist",
|
package/dist/chunk-RHYDE2DW.js
DELETED
|
@@ -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":";AAAA,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,4BAA4B;AACrC,SAAS,SAAS;AAGlB,IAAM,aAAa,CAAC,SAAS,SAAS,SAAS,MAAM;AACrD,IAAM,UAAU,CAAC,sBAAsB,sBAAsB,uBAAuB,gBAAgB;AAIpG,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,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,EAAE,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,KAAK,IAAI,GAAG,YAAY,QAAQ,WAAW;AAAA,IAC7G,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,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yEAAyE;AACvH,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,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS;AAAA,QAC5C,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,EAAE,YAAY,EAAE,MAAM,cAAc,EAAE;AAAA,IACtD;AAAA,IACA,OAAO,EAAE,OAAO,YAAY,OAAO,QAAQ,QAAQ,MAAM;AACvD,YAAM,OAAO,MAAM,OAAO,OAAO,EAAE,OAAO,YAAY,cAAc,CAAC,OAAO,GAAG,OAAO,QAAQ,CAAC;AAC/F,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,EAAE,WAAW;AAAA,MAClC;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":[]}
|