Sign In

@supericons/mcp

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@supericons/mcp - npm Package Compare versions

Comparing version
0.4.32
to
0.4.33
+222
usage-event-delivery.js
function normalizePositiveInteger(value, fallback, { min = 1, max = Number.MAX_SAFE_INTEGER } = {}) {
const parsed = Number(value);
if (!Number.isFinite(parsed)) return fallback;
return Math.min(max, Math.max(min, Math.trunc(parsed)));
}
function failureCode(error) {
const value = String(error?.code || error?.name || 'unknown_error').trim().toLowerCase();
return value.replace(/[^a-z0-9_:-]+/g, '_').slice(0, 80) || 'unknown_error';
}
export async function deliverSupabaseUsageEvent({
endpoint,
serviceRoleKey,
payload,
fetchImpl = fetch,
timeoutMs = 2500,
} = {}) {
try {
const response = await fetchImpl(endpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
apikey: serviceRoleKey,
Authorization: `Bearer ${serviceRoleKey}`,
Prefer: 'return=minimal',
},
body: JSON.stringify(payload),
signal: AbortSignal.timeout(timeoutMs),
});
if (response.ok || response.status === 409) return;
const error = new Error(`usage_write_http_${response.status}`);
error.code = `http_${response.status}`;
error.retryable = response.status === 408
|| response.status === 425
|| response.status === 429
|| response.status >= 500;
throw error;
} catch (error) {
if (typeof error?.retryable !== 'boolean') error.retryable = true;
throw error;
}
}
export function createUsageEventDelivery({
deliver,
concurrency = 4,
maxItems = 500,
retryDelaysMs = [250, 1000],
logger = console,
setTimer = setTimeout,
clearTimer = clearTimeout,
now = Date.now,
} = {}) {
if (typeof deliver !== 'function') throw new TypeError('deliver must be a function');
const workerLimit = normalizePositiveInteger(concurrency, 4, { max: 32 });
const itemLimit = normalizePositiveInteger(maxItems, 500, { max: 10_000 });
const delays = Array.isArray(retryDelaysMs)
? retryDelaysMs.map((value) => normalizePositiveInteger(value, 250, { min: 0, max: 30_000 }))
: [250, 1000];
const queue = [];
const retryTimers = new Map();
const idleWaiters = new Set();
let inFlight = 0;
let outstanding = 0;
let scheduled = false;
const counters = {
enqueued: 0,
delivered: 0,
retried: 0,
dropped: 0,
failed: 0,
};
let lastDeliveryAt = null;
let lastFailureAt = null;
let lastFailureCode = null;
function isIdle() {
return outstanding === 0 && inFlight === 0 && queue.length === 0 && retryTimers.size === 0;
}
function notifyIdle() {
if (!isIdle()) return;
for (const resolve of idleWaiters) resolve(true);
idleWaiters.clear();
}
function recordFinalFailure(error) {
counters.failed += 1;
lastFailureAt = new Date(now()).toISOString();
lastFailureCode = failureCode(error);
logger.warn?.(`[Supericons MCP] usage delivery failed: ${lastFailureCode}`);
}
function schedulePump() {
if (scheduled) return;
scheduled = true;
queueMicrotask(() => {
scheduled = false;
pump();
});
}
function finishItem() {
outstanding = Math.max(0, outstanding - 1);
schedulePump();
notifyIdle();
}
function scheduleRetry(item, delayMs) {
counters.retried += 1;
const timer = setTimer(() => {
retryTimers.delete(timer);
queue.push(item);
schedulePump();
}, delayMs);
retryTimers.set(timer, item);
}
function runItem(item) {
inFlight += 1;
Promise.resolve()
.then(() => deliver(item.payload))
.then(() => {
counters.delivered += 1;
lastDeliveryAt = new Date(now()).toISOString();
finishItem();
})
.catch((error) => {
const retryDelay = delays[item.attempt];
if (error?.retryable === true && retryDelay !== undefined) {
scheduleRetry({ ...item, attempt: item.attempt + 1 }, retryDelay);
} else {
recordFinalFailure(error);
finishItem();
}
})
.finally(() => {
inFlight = Math.max(0, inFlight - 1);
schedulePump();
notifyIdle();
});
}
function pump() {
while (inFlight < workerLimit && queue.length > 0) {
runItem(queue.shift());
}
notifyIdle();
}
function enqueue(payload) {
if (outstanding >= itemLimit) {
counters.dropped += 1;
lastFailureAt = new Date(now()).toISOString();
lastFailureCode = 'queue_full';
logger.warn?.('[Supericons MCP] usage delivery queue full');
return false;
}
outstanding += 1;
counters.enqueued += 1;
queue.push({ payload, attempt: 0 });
schedulePump();
return true;
}
function getStatus() {
return {
status: counters.dropped > 0 || counters.failed > 0 ? 'degraded' : 'ready',
queue_depth: queue.length,
in_flight: inFlight,
pending_retries: retryTimers.size,
outstanding,
concurrency: workerLimit,
max_items: itemLimit,
max_attempts: delays.length + 1,
enqueued_total: counters.enqueued,
delivered_total: counters.delivered,
retried_total: counters.retried,
dropped_total: counters.dropped,
failed_total: counters.failed,
last_delivery_at: lastDeliveryAt,
last_failure_at: lastFailureAt,
last_failure_code: lastFailureCode,
};
}
function waitForIdle({ timeoutMs = 5000 } = {}) {
if (isIdle()) return Promise.resolve(true);
return new Promise((resolve) => {
let timer = null;
const done = (value) => {
if (timer) clearTimer(timer);
idleWaiters.delete(onIdle);
resolve(value);
};
const onIdle = () => done(true);
idleWaiters.add(onIdle);
timer = setTimer(() => done(false), normalizePositiveInteger(timeoutMs, 5000, { max: 60_000 }));
});
}
function drain({ timeoutMs = 5000, expediteRetries = true } = {}) {
if (expediteRetries && retryTimers.size > 0) {
for (const [timer, item] of retryTimers.entries()) {
clearTimer(timer);
retryTimers.delete(timer);
queue.push(item);
}
schedulePump();
}
return waitForIdle({ timeoutMs });
}
return {
enqueue,
getStatus,
waitForIdle,
drain,
};
}
+10
-0
# Changelog
## 0.4.33 - 2026-08-12
### Added
- Added five reviewed anime icons for Akatsuki, Dragon Ball, Konoha, One Piece, and Sharingan searches.
- Refreshed the Supericons catalog, registry records, and agent-facing taxonomy.
### Verified
- Preserved the existing MCP tool schema, hosted-primary routing, strict library behavior, and established search behavior.
- Aligned website, hosted catalog, Railway runtime, and local npm package inputs in one release bundle.
## 0.4.32 - 2026-08-11

@@ -5,0 +15,0 @@

+11
-3

@@ -184,6 +184,8 @@ import { appendFileSync, existsSync, readFileSync } from 'node:fs';

async function postSearchRequest(url, headers, body, {
export async function postSearchRequest(url, headers, body, {
failureLabel,
failureCode,
resilience = hostedSearchResilience,
fetchImpl = fetch,
requestTimeoutMs = HOSTED_SEARCH_REQUEST_TIMEOUT_MS,
}) {

@@ -193,7 +195,7 @@ return resilience.execute(async () => {

try {
response = await fetch(url, {
response = await fetchImpl(url, {
method: 'POST',
headers,
body: JSON.stringify(body),
signal: AbortSignal.timeout(HOSTED_SEARCH_REQUEST_TIMEOUT_MS),
signal: AbortSignal.timeout(requestTimeoutMs),
});

@@ -206,2 +208,4 @@ } catch (cause) {

error.hosted_search_dependency_failure = true;
error.failure_stage = 'dependency_connect';
error.upstream_status = null;
throw error;

@@ -219,2 +223,4 @@ }

error.hosted_search_dependency_failure = true;
error.failure_stage = 'dependency_decode';
error.upstream_status = response.status;
throw error;

@@ -230,2 +236,4 @@ }

error.hosted_search_dependency_failure = response.status >= 500;
error.failure_stage = 'dependency_response';
error.upstream_status = response.status;
const retryAfter = Number(response.headers.get('retry-after'));

@@ -232,0 +240,0 @@ if (Number.isFinite(retryAfter) && retryAfter > 0) {

{
"name": "@supericons/mcp",
"version": "0.4.32",
"version": "0.4.33",
"mcpName": "io.github.curlymolelabs/supericons",

@@ -82,2 +82,3 @@ "description": "MCP server for Supericons: multilingual semantic SVG icon search and recommendations for AI coding agents.",

"usage-event-detail.js",
"usage-event-delivery.js",
"usage-dedupe.js",

@@ -84,0 +85,0 @@ "usage-attribution.js",

{
"generatedAt": "2026-08-11T09:33:58.443Z",
"freeIconCount": 21542,
"generatedAt": "2026-08-11T16:58:37.250Z",
"freeIconCount": 21547,
"freeLibraryCount": 11,

@@ -9,3 +9,3 @@ "premiumCollectionCount": 9,

"mcpFreeToolCount": 5,
"mcpPackageVersion": "0.4.32",
"mcpPackageVersion": "0.4.33",
"display": {

@@ -12,0 +12,0 @@ "freeIconsRounded": "20,000+",

@@ -187,3 +187,3 @@ const DEFAULT_LOCAL_FIRST_VALUE = 'on';

});
return prioritizeExactIconMatches(params.query, merged, {}, reranked, {
const prioritized = prioritizeExactIconMatches(params.query, merged, {}, reranked, {
library: params.library,

@@ -194,2 +194,3 @@ libraryMode: params.libraryMode,

});
return prioritized.slice(0, limit);
}

@@ -196,0 +197,0 @@

@@ -17,2 +17,18 @@ // Generated by scripts/build-search-ranking-policy.mjs

],
"brand_identity_wrapper_terms": [
"logo",
"logos",
"icon",
"icons",
"brand",
"brands",
"wordmark",
"mark",
"marks",
"symbol",
"symbols"
],
"brand_identity_noise_terms": [
"official"
],
"candidate_strength_policy": {

@@ -19,0 +35,0 @@ "expressive_fallback_tags": [

@@ -9,2 +9,3 @@ /**

import {
getBrandIdentityQueryVariants,
getBrandRankAdjustment,

@@ -364,26 +365,28 @@ getSearchInterpretationPlan,

function getExactBrandIdentityResults(query, icons, synonyms, options = {}) {
const identityWords = getMeaningfulQueryWords(tokenizeSemanticText(query));
const identityQuery = identityWords.join(' ');
if (!identityQuery) return [];
for (const identityQuery of getBrandIdentityQueryVariants(query)) {
if (!identityQuery) continue;
const identityResults = searchIconsForSingleQuery(identityQuery, icons, synonyms, {
...options,
limit: Math.max(Number(options.limit || 20) * 2, 20),
applyExpressiveFallback: false,
candidatePool: getIndexedCandidatePool(icons, identityQuery, synonyms),
});
const identityResults = searchIconsForSingleQuery(identityQuery, icons, synonyms, {
...options,
limit: Math.max(Number(options.limit || 20) * 2, 20),
applyExpressiveFallback: false,
candidatePool: getIndexedCandidatePool(icons, identityQuery, synonyms),
});
const exactResults = identityResults.filter((icon) => {
const directScore = getDirectSearchScore(
icon,
normalizeSemanticText(identityQuery),
tokenizeSemanticText(identityQuery),
);
const brandAdjustment = getBrandRankAdjustment(identityQuery, icon);
return (
directScore >= 300 &&
isLikelyBrandIdentityIcon(icon) &&
brandAdjustment.penalty === 0
);
});
if (exactResults.length > 0) return exactResults;
}
return identityResults.filter((icon) => {
const directScore = getDirectSearchScore(
icon,
normalizeSemanticText(identityQuery),
tokenizeSemanticText(identityQuery),
);
const brandAdjustment = getBrandRankAdjustment(query, icon);
return (
directScore >= 300 &&
isLikelyBrandIdentityIcon(icon) &&
brandAdjustment.penalty === 0
);
});
return [];
}

@@ -390,0 +393,0 @@

@@ -6,2 +6,4 @@ import { GENERATED_SEARCH_RANKING_POLICY } from './generated-search-ranking-policy.js';

const brandIntentTerms = new Set(policy.brand_intent_terms || []);
const brandIdentityWrapperTerms = new Set(policy.brand_identity_wrapper_terms || []);
const brandIdentityNoiseTerms = new Set(policy.brand_identity_noise_terms || []);
const expressiveFallbackTags = new Set(

@@ -176,3 +178,3 @@ (policy.candidate_strength_policy?.expressive_fallback_tags || []).map(normalizeSearchRankingText),

function getCandidateText(candidate = {}) {
function getCandidateText(candidate = {}, options = {}) {
return normalizeSearchRankingText(

@@ -186,3 +188,3 @@ [

candidate.meaning,
candidate.query_variant,
options.includeQueryVariant !== false ? candidate.query_variant : null,
...(candidate.semanticTags || []),

@@ -236,2 +238,14 @@ ...(candidate.synonyms || []),

export function getBrandIdentityQueryVariants(query) {
const tokens = tokenize(query);
const exactCandidateTokens = tokens.filter((token) => !brandIdentityWrapperTerms.has(token));
const fallbackCandidateTokens = exactCandidateTokens.filter(
(token) => !brandIdentityNoiseTerms.has(token),
);
return unique([
exactCandidateTokens.join(' '),
fallbackCandidateTokens.join(' '),
]);
}
function hasBrandIntent(query) {

@@ -427,3 +441,7 @@ return tokenize(query).some((token) => brandIntentTerms.has(token));

if (libraryMode === 'prefer' && requestedLibrary && scored.length > 1 && scored[0].policyScore <= 0) {
if (libraryMode === 'prefer' && requestedLibrary && scored.length > 1) {
const shouldPreserveExistingPreferenceFlow = scored[0].policyScore <= 0;
const leadingFamilyIds = new Set(
getCandidateInterpretationFamilyIds(query, scored[0].candidate, { includeQueryVariant: false }),
);
const preferredIndex = scored.findIndex((entry) => {

@@ -433,3 +451,9 @@ const library = String(

).toLowerCase();
return library === requestedLibrary;
if (library !== requestedLibrary || entry.policyScore < 0) return false;
if (entry.policyScore > 0 || shouldPreserveExistingPreferenceFlow) return true;
const candidateFamilyIds = getCandidateInterpretationFamilyIds(query, entry.candidate, {
includeQueryVariant: false,
});
return candidateFamilyIds.some((familyId) => leadingFamilyIds.has(familyId));
});

@@ -440,11 +464,13 @@ if (preferredIndex > 0) {

const alternativeIndex = scored.findIndex((entry, index) => {
if (index === 0) return false;
const library = String(
entry.candidate.lib || entry.candidate.library || entry.candidate.source_library || '',
).toLowerCase();
return library !== requestedLibrary;
});
if (alternativeIndex > 1) {
scored.splice(1, 0, ...scored.splice(alternativeIndex, 1));
if (shouldPreserveExistingPreferenceFlow) {
const alternativeIndex = scored.findIndex((entry, index) => {
if (index === 0) return false;
const library = String(
entry.candidate.lib || entry.candidate.library || entry.candidate.source_library || '',
).toLowerCase();
return library !== requestedLibrary;
});
if (alternativeIndex > 1) {
scored.splice(1, 0, ...scored.splice(alternativeIndex, 1));
}
}

@@ -456,3 +482,3 @@ }

export function getCandidateInterpretationFamilyIds(query, candidate = {}) {
export function getCandidateInterpretationFamilyIds(query, candidate = {}, options = {}) {
const plan = getSearchInterpretationPlan(query);

@@ -462,3 +488,4 @@ if (!plan) return [];

const queryVariant = normalizeSearchRankingText(candidate.query_variant);
const candidateText = getCandidateText(candidate);
const includeQueryVariant = options.includeQueryVariant !== false;
const candidateText = getCandidateText(candidate, { includeQueryVariant });
const iconRef = getCandidateIconRef(candidate);

@@ -471,3 +498,3 @@ const familyIds = [];

const candidateIconRefs = (family.candidate_icon_refs || []).map((value) => String(value).toLowerCase());
const matchedVariant = queryVariant && retrievalQueries.includes(queryVariant);
const matchedVariant = includeQueryVariant && queryVariant && retrievalQueries.includes(queryVariant);
const matchedCandidate = candidateTerms.some((term) => includesPhrase(candidateText, term));

@@ -474,0 +501,0 @@ const matchedIconRef = candidateIconRefs.includes(iconRef);

@@ -175,2 +175,8 @@ const BASE_FILTER_TAGS = Object.freeze(['agentic-ai-tools-pack', 'brand-logo']);

},
{
id: 'anime-manga',
label: 'Anime & Manga',
description: 'Iconic symbols from anime and manga: village emblems, crew flags, and pop culture marks.',
sidebarGlyph: 'auto_awesome',
},
]);

@@ -1297,2 +1303,27 @@

),
'si:anime-konoha-leaf': taxonomy(
'anime-manga',
['japanese-animation', 'media-entertainment', 'pop-culture'],
['naruto', 'konoha', 'ninja', 'shonen']
),
'si:anime-akatsuki-cloud': taxonomy(
'anime-manga',
['japanese-animation', 'media-entertainment', 'pop-culture'],
['naruto', 'akatsuki', 'villain', 'shonen']
),
'si:anime-sharingan': taxonomy(
'anime-manga',
['japanese-animation', 'media-entertainment', 'pop-culture'],
['naruto', 'sharingan', 'uchiha', 'shonen']
),
'si:anime-dragonball-fourstar': taxonomy(
'anime-manga',
['japanese-animation', 'media-entertainment', 'pop-culture'],
['dragon-ball', 'goku', 'collectible', 'shonen']
),
'si:anime-onepiece-jolly-roger': taxonomy(
'anime-manga',
['japanese-animation', 'media-entertainment', 'pop-culture'],
['one-piece', 'luffy', 'pirate', 'shonen']
),
});

@@ -1299,0 +1330,0 @@

@@ -10,3 +10,3 @@ {

},
"version": "0.4.32",
"version": "0.4.33",
"remotes": [

@@ -22,3 +22,3 @@ {

"identifier": "@supericons/mcp",
"version": "0.4.32",
"version": "0.4.33",
"transport": {

@@ -25,0 +25,0 @@ "type": "stdio"

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display