@ansvar/singapore-law-mcp
Version:
Complete Singapore law database — 523 Acts, 28K+ provisions from Singapore Statutes Online (sso.agc.gov.sg) with full-text search, definitions, and citation support
80 lines • 2.7 kB
JavaScript
/**
* Singapore Law MCP Server — stdio entry point.
*
* Provides Singapore legislation search via Model Context Protocol.
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import Database from '@ansvar/mcp-sqlite';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { createHash } from 'crypto';
import { readFileSync } from 'fs';
import { registerTools } from './tools/registry.js';
import { detectCapabilities, readDbMetadata } from './capabilities.js';
import { DB_ENV_VAR, SERVER_NAME, SERVER_VERSION, } from './constants.js';
const __dirname = dirname(fileURLToPath(import.meta.url));
function resolveDbPath() {
if (process.env[DB_ENV_VAR]) {
return process.env[DB_ENV_VAR];
}
return join(__dirname, '..', 'data', 'database.db');
}
let db = null;
function getDb() {
if (!db) {
const dbPath = resolveDbPath();
db = new Database(dbPath, { readonly: true });
db.pragma('foreign_keys = ON');
const caps = detectCapabilities(db);
const meta = readDbMetadata(db);
console.error(`[${SERVER_NAME}] DB opened: tier=${meta.tier}, caps=[${[...caps].join(',')}]`);
}
return db;
}
function computeAboutContext() {
const dbPath = resolveDbPath();
let fingerprint = 'unknown';
let dbBuilt = 'unknown';
try {
const buf = readFileSync(dbPath);
fingerprint = createHash('sha256').update(buf).digest('hex').slice(0, 12);
}
catch {
// DB might not exist in dev
}
try {
const database = getDb();
const row = database.prepare("SELECT value FROM db_metadata WHERE key = 'built_at'").get();
if (row)
dbBuilt = row.value;
}
catch {
// Ignore
}
return { version: SERVER_VERSION, fingerprint, dbBuilt };
}
async function main() {
const database = getDb();
const aboutContext = computeAboutContext();
const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} } });
registerTools(server, database, aboutContext);
const transport = new StdioServerTransport();
await server.connect(transport);
console.error(`[${SERVER_NAME}] Server running on stdio`);
const cleanup = () => {
if (db) {
db.close();
db = null;
}
process.exit(0);
};
process.on('SIGINT', cleanup);
process.on('SIGTERM', cleanup);
}
main().catch((err) => {
console.error(`[${SERVER_NAME}] Fatal error:`, err);
process.exit(1);
});
//# sourceMappingURL=index.js.map