opengov-mcp-server
Version:
MCP server that enables a client, such as Claude Desktop, to access open government data through Socrata APIs
108 lines • 3.22 kB
JavaScript
import axios from 'axios';
/**
* Supported data portal platforms
*/
export var PortalPlatform;
(function (PortalPlatform) {
PortalPlatform["UNKNOWN"] = "unknown";
PortalPlatform["SOCRATA"] = "socrata";
PortalPlatform["ARCGIS"] = "arcgis";
PortalPlatform["CKAN"] = "ckan";
})(PortalPlatform || (PortalPlatform = {}));
/**
* Detects if the portal is using Socrata
*/
async function isSocrata(baseUrl) {
try {
const response = await axios.get(`${baseUrl}/api/catalog/v1`, {
params: { limit: 1 },
timeout: 5000
});
return response.status === 200 && response.data.results !== undefined;
}
catch {
try {
// Alternative Socrata detection
const altResponse = await axios.get(`${baseUrl}/api/views.json`, {
params: { limit: 1 },
timeout: 5000
});
return altResponse.status === 200 && Array.isArray(altResponse.data);
}
catch {
return false;
}
}
}
/**
* Detects if the portal is using ArcGIS Hub/Open Data
*/
async function isArcGIS(baseUrl) {
try {
// Check for ArcGIS Hub API
const response = await axios.get(`${baseUrl}/api/v3/datasets`, {
timeout: 5000
});
return response.status === 200;
}
catch {
try {
// Alternative detection for ArcGIS
const htmlResponse = await axios.get(baseUrl, {
timeout: 5000
});
return (htmlResponse.data.includes('arcgis') ||
htmlResponse.data.includes('esri') ||
htmlResponse.data.includes('ArcGIS Hub'));
}
catch {
return false;
}
}
}
/**
* Detects if the portal is using CKAN
*/
async function isCKAN(baseUrl) {
try {
const response = await axios.get(`${baseUrl}/api/3/action/package_list`, {
timeout: 5000
});
return response.status === 200 && response.data.success === true;
}
catch {
try {
// Check HTML for CKAN signatures
const htmlResponse = await axios.get(baseUrl, {
timeout: 5000
});
return (htmlResponse.data.includes('ckan') ||
htmlResponse.data.includes('class="ckan-'));
}
catch {
return false;
}
}
}
/**
* Detects the platform of a data portal
*/
export async function detectPortalPlatform(url) {
// Ensure URL has protocol
const baseUrl = url.startsWith('http') ? url : `https://${url}`;
// Extract domain from URL
const domain = new URL(baseUrl).hostname;
// Try each platform detection in sequence
if (await isSocrata(baseUrl)) {
return { platform: PortalPlatform.SOCRATA, baseUrl, domain };
}
if (await isArcGIS(baseUrl)) {
return { platform: PortalPlatform.ARCGIS, baseUrl, domain };
}
if (await isCKAN(baseUrl)) {
return { platform: PortalPlatform.CKAN, baseUrl, domain };
}
// Default to unknown
return { platform: PortalPlatform.UNKNOWN, baseUrl, domain };
}
//# sourceMappingURL=portal-detector.js.map