@chainlink/mcp-server
Version:
Prototype MCP Server for CLL
172 lines • 8.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.searchCcipDataSources = exports.getChainSpecificData = exports.extractChainNamesFromQuery = void 0;
const logger_1 = require("../../../utils/logger");
const strings_1 = require("../shared/strings");
const matching_1 = require("../shared/matching");
const load_1 = require("./load");
const cache_1 = require("./cache");
const search_1 = require("../shared/search");
const SUPPORTED_ENVIRONMENTS = ["mainnet", "testnet"];
const PRODUCT_CCIP = "ccip";
const extractChainNamesFromQuery = async (query) => {
// Use centralized keyword index for CCIP chains
return (0, matching_1.detectChainsFromQuery)(query, "ccip");
};
exports.extractChainNamesFromQuery = extractChainNamesFromQuery;
const getChainSpecificData = async (chainNames) => {
const result = { chains: {}, tokens: {}, lanes: {}, metadata: [] };
for (const env of SUPPORTED_ENVIRONMENTS) {
try {
let config = (0, cache_1.getCachedCcipConfig)(PRODUCT_CCIP, env);
if (config === undefined) {
config = await (0, load_1.loadCcipDataSources)(PRODUCT_CCIP, env);
}
if (config) {
const matchingChains = (0, matching_1.matchChainsFromQuery)(chainNames, config.chains, "ccip");
for (const chainKey of matchingChains) {
if (!result.chains[chainKey])
result.chains[chainKey] = {};
result.chains[chainKey][env] = config.chains[chainKey];
}
if (config.tokens) {
for (const [tokenSymbol, tokenChains] of Object.entries(config.tokens)) {
for (const chainKey of matchingChains) {
if (tokenChains[chainKey]) {
if (!result.tokens[tokenSymbol])
result.tokens[tokenSymbol] = {};
if (!result.tokens[tokenSymbol][chainKey])
result.tokens[tokenSymbol][chainKey] = {};
result.tokens[tokenSymbol][chainKey][env] = tokenChains[chainKey];
}
}
}
}
if (config.lanes) {
for (const chainKey of matchingChains) {
if (config.lanes[chainKey]) {
if (!result.lanes[chainKey])
result.lanes[chainKey] = {};
result.lanes[chainKey][env] = config.lanes[chainKey];
}
}
for (const [sourceChain, destinations] of Object.entries(config.lanes)) {
for (const chainKey of matchingChains) {
if (destinations[chainKey]) {
if (!result.lanes[sourceChain])
result.lanes[sourceChain] = {};
if (!result.lanes[sourceChain][env])
result.lanes[sourceChain][env] = {};
result.lanes[sourceChain][env][chainKey] = destinations[chainKey];
}
}
}
}
result.metadata.push({
environment: env,
matchingChains: matchingChains,
totalChains: Object.keys(config.chains).length,
totalTokens: config.tokens ? Object.keys(config.tokens).length : 0,
totalLanes: config.lanes ? Object.keys(config.lanes).length : 0,
});
}
}
catch (error) {
logger_1.Logger.log("warn", `Error processing chain-specific data for ${env} environment: ${error}`);
}
}
return result;
};
exports.getChainSpecificData = getChainSpecificData;
const searchCcipDataSources = async (query) => {
const chainNames = await (0, exports.extractChainNamesFromQuery)(query);
const isAddressOrToken = (0, strings_1.isAddressOrTokenQuery)(query);
const isRouter = (0, strings_1.isRouterQuery)(query);
if (chainNames.length > 0) {
const chainSpecificData = await (0, exports.getChainSpecificData)(chainNames);
const results = [];
for (const [chainKey, chainData] of Object.entries(chainSpecificData.chains)) {
for (const [env, data] of Object.entries(chainData)) {
let relevance = (0, search_1.calculateRelevance)(chainKey, query, chainKey) + 50;
if (isRouter)
relevance += 200; // prioritize chain entries for router queries
results.push({
environment: env,
dataType: "chains",
key: chainKey,
data: data,
relevance,
});
}
}
for (const [tokenSymbol, tokenData] of Object.entries(chainSpecificData.tokens)) {
for (const [chainKey, chainTokens] of Object.entries(tokenData)) {
for (const [env, data] of Object.entries(chainTokens)) {
let tokenRelevance = (0, search_1.calculateRelevance)(tokenSymbol, query);
const chainRelevance = (0, search_1.calculateRelevance)(chainKey, query, chainKey);
// Boost tokens for address-oriented queries
if (isAddressOrToken && !isRouter)
tokenRelevance += 150;
const tokenBoost = tokenRelevance > 0 ? 200 : 100;
const combinedRelevance = Math.max(tokenRelevance, chainRelevance) + tokenBoost;
results.push({
environment: env,
dataType: "tokens",
key: `${tokenSymbol}.${chainKey}`,
data: data,
relevance: combinedRelevance,
});
}
}
}
for (const [sourceChain, laneData] of Object.entries(chainSpecificData.lanes)) {
for (const [env, envData] of Object.entries(laneData)) {
for (const [destChain, data] of Object.entries(envData)) {
const sourceRelevance = (0, search_1.calculateRelevance)(sourceChain, query, sourceChain);
const destRelevance = (0, search_1.calculateRelevance)(destChain, query, destChain);
const laneRelevance = Math.max(sourceRelevance, destRelevance) + 75;
results.push({
environment: env,
dataType: "lanes",
key: `${sourceChain}->${destChain}`,
data: data,
relevance: laneRelevance,
});
}
}
}
if (results.length > 0) {
return results.sort((a, b) => (b.relevance || 0) - (a.relevance || 0));
}
}
const results = [];
for (const env of SUPPORTED_ENVIRONMENTS) {
try {
let config = (0, cache_1.getCachedCcipConfig)(PRODUCT_CCIP, env);
if (config === undefined)
config = await (0, load_1.loadCcipDataSources)(PRODUCT_CCIP, env);
if (config) {
const chainResults = (0, search_1.searchInCcipDataSources)(config.chains, query, undefined, env, "chains");
results.push(...chainResults);
let tokenResults = (0, search_1.searchInCcipDataSources)(config.tokens, query, undefined, env, "tokens");
if (isAddressOrToken) {
tokenResults = tokenResults.map((r) => ({
...r,
relevance: (r.relevance || 0) + 150,
}));
}
results.push(...tokenResults);
const laneResults = (0, search_1.searchInCcipDataSources)(config.lanes, query, undefined, env, "lanes");
results.push(...laneResults);
}
}
catch (error) {
logger_1.Logger.log("warn", `Failed to search ${PRODUCT_CCIP} configuration in ${env}: ${error}`);
}
}
return results
.sort((a, b) => (b.relevance || 0) - (a.relevance || 0))
.slice(0, 50);
};
exports.searchCcipDataSources = searchCcipDataSources;
//# sourceMappingURL=search.js.map